All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac
@ 2018-04-03  7:53 pkshih
  2018-04-03  7:53 ` [PATCH v2 01/17] rtlwifi: add halmac structure to wifi.h pkshih
                   ` (16 more replies)
  0 siblings, 17 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

v2: remove indirection to get halmac ops
    Only patches 1/17 and 11/17 are changed.

Patches 1/17-3/17 are added structure to support this module.
Patches 4/17-16/17 add new files.
Patch 17/17 add this module to Makefile and Kconfig.

Ping-Ke Shih (17):
  rtlwifi: add halmac structure to wifi.h
  rtlwifi: add debug ID COMP_HALMAC
  rtlwifi: add dmdef.h to share with driver and other modules
  rtlwifi: halmac: add main definition used by halmac
  rtlwifi: halmac: describe number and size of chip functions
  rtlwifi: halmac: add definitions of registers and bit fields
  rtlwifi: halmac: add definition of TX/RX descriptor
  rtlwifi: halmac: add GPIO pin/pinmux definitions
  rtlwifi: halmac: add power sequence to turn on/off wifi card
  rtlwifi: halmac: access efuse through halmac helper functions
  rtlwifi: halmac: add files to implement halmac ops
  rtlwifi: halmac: add halmac init/deinit functions
  rtlwifi: halmac: add firmware related functions and definitions
  rtlwifi: halmac: add bus interface commands
  rtlwifi: halmac: add to control WiFi mac functions and registers
  rtlwifi: halmac: add to support BB and RF functions
  rtlwifi: add halmac to Makefile and Kconfig

 drivers/net/wireless/realtek/rtlwifi/Kconfig       |     5 +
 drivers/net/wireless/realtek/rtlwifi/Makefile      |     1 +
 drivers/net/wireless/realtek/rtlwifi/debug.h       |     1 +
 drivers/net/wireless/realtek/rtlwifi/dmdef.h       |    40 +
 .../net/wireless/realtek/rtlwifi/halmac/Makefile   |    29 +
 .../halmac_88xx/halmac_8822b/halmac_8822b_cfg.h    |    68 +
 .../halmac_8822b/halmac_cfg_wmac_8822b.c           |   144 +
 .../halmac_8822b/halmac_cfg_wmac_8822b.h           |    36 +
 .../halmac_88xx/halmac_8822b/halmac_common_8822b.c |   173 +
 .../halmac_88xx/halmac_8822b/halmac_common_8822b.h |    32 +
 .../halmac_88xx/halmac_8822b/halmac_gpio_8822b.c   |   847 +
 .../halmac_88xx/halmac_8822b/halmac_gpio_8822b.h   |    34 +
 .../halmac_88xx/halmac_8822b/halmac_init_8822b.c   |   688 +
 .../halmac_88xx/halmac_8822b/halmac_init_8822b.h   |    33 +
 .../halmac_88xx/halmac_8822b/halmac_pcie_8822b.c   |   218 +
 .../halmac_88xx/halmac_8822b/halmac_pcie_8822b.h   |    38 +
 .../halmac_88xx/halmac_8822b/halmac_phy_8822b.c    |   148 +
 .../halmac_8822b/halmac_pwr_seq_8822b.c            |   396 +
 .../halmac_8822b/halmac_pwr_seq_8822b.h            |    26 +
 .../halmac_88xx/halmac_8822b/halmac_sdio_8822b.c   |   880 +
 .../halmac_88xx/halmac_8822b/halmac_sdio_8822b.h   |    62 +
 .../halmac_88xx/halmac_8822b/halmac_usb_8822b.c    |   161 +
 .../halmac_88xx/halmac_8822b/halmac_usb_8822b.h    |    38 +
 .../rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h   |    40 +
 .../rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.c |   397 +
 .../rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.h |    53 +
 .../halmac/halmac_88xx/halmac_cfg_wmac_88xx.c      |  1158 ++
 .../halmac/halmac_88xx/halmac_cfg_wmac_88xx.h      |   122 +
 .../halmac/halmac_88xx/halmac_common_88xx.c        |  2931 +++
 .../halmac/halmac_88xx/halmac_common_88xx.h        |   151 +
 .../rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.c |  1918 ++
 .../rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.h |   101 +
 .../rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.c |   316 +
 .../rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.h |    35 +
 .../rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.c    |  1149 ++
 .../rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.h    |    57 +
 .../rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.c  |   415 +
 .../rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.h  |    55 +
 .../rtlwifi/halmac/halmac_88xx/halmac_init_88xx.c  |  1071 ++
 .../rtlwifi/halmac/halmac_88xx/halmac_init_88xx.h  |    70 +
 .../rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.c  |   869 +
 .../rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.h  |    79 +
 .../rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.c  |   538 +
 .../rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.h  |    98 +
 .../rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.c  |   895 +
 .../rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.h  |    75 +
 .../rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.c   |   522 +
 .../rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.h   |    83 +
 .../wireless/realtek/rtlwifi/halmac/halmac_api.c   |   438 +
 .../wireless/realtek/rtlwifi/halmac/halmac_api.h   |    65 +
 .../wireless/realtek/rtlwifi/halmac/halmac_bit2.h  | 18234 +++++++++++++++++++
 .../realtek/rtlwifi/halmac/halmac_bit_8822b.h      | 17870 ++++++++++++++++++
 .../realtek/rtlwifi/halmac/halmac_fw_info.h        |   119 +
 .../rtlwifi/halmac/halmac_fw_offload_c2h_nic.h     |   371 +
 .../rtlwifi/halmac/halmac_fw_offload_h2c_nic.h     |   694 +
 .../realtek/rtlwifi/halmac/halmac_gpio_cmd.h       |    84 +
 .../rtlwifi/halmac/halmac_h2c_extra_info_nic.h     |   171 +
 .../realtek/rtlwifi/halmac/halmac_intf_phy_cmd.h   |    45 +
 .../rtlwifi/halmac/halmac_original_c2h_nic.h       |   408 +
 .../rtlwifi/halmac/halmac_original_h2c_nic.h       |  1143 ++
 .../realtek/rtlwifi/halmac/halmac_pcie_reg.h       |    36 +
 .../realtek/rtlwifi/halmac/halmac_pwr_seq_cmd.h    |    98 +
 .../wireless/realtek/rtlwifi/halmac/halmac_reg2.h  |  1292 ++
 .../realtek/rtlwifi/halmac/halmac_reg_8822b.h      |   733 +
 .../realtek/rtlwifi/halmac/halmac_rx_bd_nic.h      |    36 +
 .../realtek/rtlwifi/halmac/halmac_rx_desc_chip.h   |   100 +
 .../realtek/rtlwifi/halmac/halmac_rx_desc_nic.h    |   123 +
 .../realtek/rtlwifi/halmac/halmac_sdio_reg.h       |    53 +
 .../realtek/rtlwifi/halmac/halmac_state_machine.h  |   157 +
 .../realtek/rtlwifi/halmac/halmac_tx_bd_nic.h      |   106 +
 .../realtek/rtlwifi/halmac/halmac_tx_desc_chip.h   |   398 +
 .../realtek/rtlwifi/halmac/halmac_tx_desc_nic.h    |   439 +
 .../wireless/realtek/rtlwifi/halmac/halmac_type.h  |  2134 +++
 .../realtek/rtlwifi/halmac/halmac_usb_reg.h        |    19 +
 .../wireless/realtek/rtlwifi/halmac/rtl_halmac.c   |  1403 ++
 .../wireless/realtek/rtlwifi/halmac/rtl_halmac.h   |    77 +
 drivers/net/wireless/realtek/rtlwifi/wifi.h        |    59 +
 77 files changed, 64201 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/dmdef.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/Makefile
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_bit2.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_bit_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_info.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_gpio_cmd.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_h2c_extra_info_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_intf_phy_cmd.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_c2h_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_h2c_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pcie_reg.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pwr_seq_cmd.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_reg2.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_reg_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_bd_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_chip.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_sdio_reg.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_state_machine.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_bd_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_chip.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_type.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_usb_reg.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.h

-- 
2.15.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 01/17] rtlwifi: add halmac structure to wifi.h
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 02/17] rtlwifi: add debug ID COMP_HALMAC pkshih
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

Add structure and ops to interact with halmac and other modules.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtlwifi/wifi.h | 58 +++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index d27e33960e77..c8542b87cc2b 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2305,6 +2305,13 @@ struct rtl_hal_ops {
 	u16 (*get_available_desc)(struct ieee80211_hw *hw, u8 q_idx);
 	void (*c2h_content_parsing)(struct ieee80211_hw *hw, u8 tag, u8 len,
 				    u8 *val);
+	/* ops for halmac cb */
+	bool (*halmac_cb_init_mac_register)(struct rtl_priv *rtlpriv);
+	bool (*halmac_cb_init_bb_rf_register)(struct rtl_priv *rtlpriv);
+	bool (*halmac_cb_write_data_rsvd_page)(struct rtl_priv *rtlpriv,
+					       u8 *buf, u32 size);
+	bool (*halmac_cb_write_data_h2c)(struct rtl_priv *rtlpriv, u8 *buf,
+					 u32 size);
 };
 
 struct rtl_intf_ops {
@@ -2687,6 +2694,54 @@ struct rtl_btc_ops {
 	bool (*btc_is_bt_lps_on)(struct rtl_priv *rtlpriv);
 };
 
+struct rtl_halmac_ops {
+	int (*halmac_init_adapter)(struct rtl_priv *rtlpriv);
+	int (*halmac_deinit_adapter)(struct rtl_priv *rtlpriv);
+	int (*halmac_init_hal)(struct rtl_priv *rtlpriv);
+	int (*halmac_deinit_hal)(struct rtl_priv *rtlpriv);
+	int (*halmac_poweron)(struct rtl_priv *rtlpriv);
+	int (*halmac_poweroff)(struct rtl_priv *rtlpriv);
+
+	int (*halmac_phy_power_switch)(struct rtl_priv *rtlpriv, u8 enable);
+	int (*halmac_set_mac_address)(struct rtl_priv *rtlpriv, u8 hwport,
+				      u8 *addr);
+	int (*halmac_set_bssid)(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr);
+
+	int (*halmac_get_physical_efuse_size)(struct rtl_priv *rtlpriv,
+					      u32 *size);
+	int (*halmac_read_physical_efuse_map)(struct rtl_priv *rtlpriv,
+					      u8 *map, u32 size);
+	int (*halmac_get_logical_efuse_size)(struct rtl_priv *rtlpriv,
+					     u32 *size);
+	int (*halmac_read_logical_efuse_map)(struct rtl_priv *rtlpriv, u8 *map,
+					     u32 size);
+
+	int (*halmac_set_bandwidth)(struct rtl_priv *rtlpriv, u8 channel,
+				    u8 pri_ch_idx, u8 bw);
+
+	int (*halmac_c2h_handle)(struct rtl_priv *rtlpriv, u8 *c2h, u32 size);
+
+	int (*halmac_chk_txdesc)(struct rtl_priv *rtlpriv, u8 *txdesc,
+				 u32 size);
+	int (*halmac_iqk)(struct rtl_priv *rtlpriv, u8 clear, u8 segment);
+};
+
+struct rtl_halmac_indicator {
+	struct completion *comp;
+	u32 wait_ms;
+
+	u8 *buffer;
+	u32 buf_size;
+	u32 ret_size;
+	u32 status;
+};
+
+struct rtl_halmac {
+	const struct rtl_halmac_ops *ops;
+	void *internal;	/* internal context of halmac, i.e. PHALMAC_ADAPTER */
+	struct rtl_halmac_indicator *indicator;	/* size=10 */
+};
+
 struct proxim {
 	bool proxim_on;
 
@@ -2792,6 +2847,9 @@ struct rtl_priv {
 	/*for bt coexist use*/
 	struct bt_coexist_info btcoexist;
 
+	/* halmac for newer ICs */
+	struct rtl_halmac halmac;
+
 	/* separate 92ee from other ICs,
 	 * 92ee use new trx flow.
 	 */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 02/17] rtlwifi: add debug ID COMP_HALMAC
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
  2018-04-03  7:53 ` [PATCH v2 01/17] rtlwifi: add halmac structure to wifi.h pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 03/17] rtlwifi: add dmdef.h to share with driver and other modules pkshih
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

Add a debug ID for the module halmac

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtlwifi/debug.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h
index ad6834af618b..90c41c17d678 100644
--- a/drivers/net/wireless/realtek/rtlwifi/debug.h
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.h
@@ -106,6 +106,7 @@
 #define COMP_BT_COEXIST			BIT(30)
 #define COMP_IQK			BIT(31)
 #define COMP_TX_REPORT			BIT_ULL(32)
+#define COMP_HALMAC			BIT_ULL(33)
 
 /*--------------------------------------------------------------
 		Define the rt_print components
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 03/17] rtlwifi: add dmdef.h to share with driver and other modules
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
  2018-04-03  7:53 ` [PATCH v2 01/17] rtlwifi: add halmac structure to wifi.h pkshih
  2018-04-03  7:53 ` [PATCH v2 02/17] rtlwifi: add debug ID COMP_HALMAC pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 04/17] rtlwifi: halmac: add main definition used by halmac pkshih
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

This header file is maintained by new module phydm, and share with
driver and other modules, such as halmac. This patch adds only one
enumeration, and more information will be added later.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtlwifi/dmdef.h | 40 ++++++++++++++++++++++++++++
 drivers/net/wireless/realtek/rtlwifi/wifi.h  |  1 +
 2 files changed, 41 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/dmdef.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/dmdef.h b/drivers/net/wireless/realtek/rtlwifi/dmdef.h
new file mode 100644
index 000000000000..5560cd1f98ed
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/dmdef.h
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef __RTL_DMINFO_H__
+#define __RTL_DMINFO_H__
+
+enum bb_path {
+	BB_PATH_A = 0x00000001,
+	BB_PATH_B = 0x00000002,
+	BB_PATH_C = 0x00000004,
+	BB_PATH_D = 0x00000008,
+
+	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),
+};
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index c8542b87cc2b..c32985cfe48d 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -35,6 +35,7 @@
 #include <linux/usb.h>
 #include <net/mac80211.h>
 #include <linux/completion.h>
+#include "dmdef.h"
 #include "debug.h"
 
 #define	MASKBYTE0				0xff
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 04/17] rtlwifi: halmac: add main definition used by halmac
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (2 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 03/17] rtlwifi: add dmdef.h to share with driver and other modules pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 05/17] rtlwifi: halmac: describe number and size of chip functions pkshih
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

The files contain main definition of struct, enum, prototypes,
state machine, etc.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../realtek/rtlwifi/halmac/halmac_state_machine.h  |  157 ++
 .../wireless/realtek/rtlwifi/halmac/halmac_type.h  | 2134 ++++++++++++++++++++
 2 files changed, 2291 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_state_machine.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_type.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_state_machine.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_state_machine.h
new file mode 100644
index 000000000000..d6cce79a460d
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_state_machine.h
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2017 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_STATE_MACHINE_H_
+#define _HALMAC_STATE_MACHINE_H_
+
+enum halmac_dlfw_state {
+	HALMAC_DLFW_NONE = 0,
+	HALMAC_DLFW_DONE = 1,
+	HALMAC_GEN_INFO_SENT = 2,
+
+	/* Data CPU firmware download framework */
+	HALMAC_DLFW_INIT = 0x11,
+	HALMAC_DLFW_START = 0x12,
+	HALMAC_DLFW_CONF_READY = 0x13,
+	HALMAC_DLFW_CPU_READY = 0x14,
+	HALMAC_DLFW_MEM_READY = 0x15,
+	HALMAC_DLFW_SW_READY = 0x16,
+	HALMAC_DLFW_OFLD_READY = 0x17,
+
+	HALMAC_DLFW_UNDEFINED = 0x7F,
+};
+
+enum halmac_gpio_cfg_state {
+	HALMAC_GPIO_CFG_STATE_IDLE = 0,
+	HALMAC_GPIO_CFG_STATE_BUSY = 1,
+	HALMAC_GPIO_CFG_STATE_UNDEFINED = 0x7F,
+};
+
+enum halmac_rsvd_pg_state {
+	HALMAC_RSVD_PG_STATE_IDLE = 0,
+	HALMAC_RSVD_PG_STATE_BUSY = 1,
+	HALMAC_RSVD_PG_STATE_UNDEFINED = 0x7F,
+};
+
+enum halmac_api_state {
+	HALMAC_API_STATE_INIT = 0,
+	HALMAC_API_STATE_HALT = 1,
+	HALMAC_API_STATE_UNDEFINED = 0x7F,
+};
+
+enum halmac_cmd_construct_state {
+	HALMAC_CMD_CNSTR_IDLE = 0,
+	HALMAC_CMD_CNSTR_BUSY = 1,
+	HALMAC_CMD_CNSTR_H2C_SENT = 2,
+	HALMAC_CMD_CNSTR_CNSTR = 3,
+	HALMAC_CMD_CNSTR_BUF_CLR = 4,
+	HALMAC_CMD_CNSTR_UNDEFINED = 0x7F,
+};
+
+enum halmac_cmd_process_status {
+	HALMAC_CMD_PROCESS_IDLE = 0x01, /* Init status */
+	HALMAC_CMD_PROCESS_SENDING = 0x02, /* Wait ack */
+	HALMAC_CMD_PROCESS_RCVD = 0x03, /* Rcvd ack */
+	HALMAC_CMD_PROCESS_DONE = 0x04, /* Event done */
+	HALMAC_CMD_PROCESS_ERROR = 0x05, /* Return code error */
+	HALMAC_CMD_PROCESS_UNDEFINE = 0x7F,
+};
+
+enum halmac_mac_power {
+	HALMAC_MAC_POWER_OFF = 0x0,
+	HALMAC_MAC_POWER_ON = 0x1,
+	HALMAC_MAC_POWER_UNDEFINE = 0x7F,
+};
+
+enum halmac_wlcpu_mode {
+	HALMAC_WLCPU_ACTIVE = 0x0,
+	HALMAC_WLCPU_ENTER_SLEEP = 0x1,
+	HALMAC_WLCPU_SLEEP = 0x2,
+	HALMAC_WLCPU_UNDEFINE = 0x7F,
+};
+
+struct halmac_efuse_state {
+	enum halmac_cmd_construct_state cmd_cnstr_state;
+	enum halmac_cmd_process_status proc_status;
+	u8 fw_rc;
+	u16 seq_num;
+};
+
+struct halmac_cfg_param_state {
+	enum halmac_cmd_construct_state cmd_cnstr_state;
+	enum halmac_cmd_process_status proc_status;
+	u8 fw_rc;
+	u16 seq_num;
+};
+
+struct halmac_scan_state {
+	enum halmac_cmd_construct_state cmd_cnstr_state;
+	enum halmac_cmd_process_status proc_status;
+	u8 fw_rc;
+	u16 seq_num;
+};
+
+struct halmac_update_pkt_state {
+	enum halmac_cmd_process_status proc_status;
+	u8 fw_rc;
+	u16 seq_num;
+};
+
+struct halmac_iqk_state {
+	enum halmac_cmd_process_status proc_status;
+	u8 fw_rc;
+	u16 seq_num;
+};
+
+struct halmac_pwr_tracking_state {
+	enum halmac_cmd_process_status	proc_status;
+	u8 fw_rc;
+	u16 seq_num;
+};
+
+struct halmac_psd_state {
+	enum halmac_cmd_process_status proc_status;
+	u16 data_size;
+	u16 seg_size;
+	u8 *data;
+	u8 fw_rc;
+	u16 seq_num;
+};
+
+struct halmac_fw_snding_state {
+	enum halmac_cmd_construct_state cmd_cnstr_state;
+	enum halmac_cmd_process_status proc_status;
+	u8 fw_rc;
+	u16 seq_num;
+};
+
+struct halmac_state {
+	struct halmac_efuse_state efuse_state;
+	struct halmac_cfg_param_state cfg_param_state;
+	struct halmac_scan_state scan_state;
+	struct halmac_update_pkt_state update_pkt_state;
+	struct halmac_iqk_state iqk_state;
+	struct halmac_pwr_tracking_state pwr_trk_state;
+	struct halmac_psd_state psd_state;
+	struct halmac_fw_snding_state fw_snding_state;
+	enum halmac_api_state api_state;
+	enum halmac_mac_power mac_pwr;
+	enum halmac_dlfw_state dlfw_state;
+	enum halmac_wlcpu_mode wlcpu_mode;
+	enum halmac_gpio_cfg_state gpio_cfg_state;
+	enum halmac_rsvd_pg_state rsvd_pg_state;
+};
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_type.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_type.h
new file mode 100644
index 000000000000..2d043c68dba8
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_type.h
@@ -0,0 +1,2134 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_TYPE_H_
+#define _HALMAC_TYPE_H_
+
+#include "../wifi.h"
+#include "halmac_fw_info.h"
+#include "halmac_intf_phy_cmd.h"
+#include "halmac_state_machine.h"
+
+#define HALMAC_BCN_IE_BMP_SIZE	24 /* ID0~ID191, 192/8=24 */
+
+#ifndef HALMAC_RX_FIFO_EXPANDING_MODE_PKT_SIZE
+#define HALMAC_RX_FIFO_EXPANDING_MODE_PKT_SIZE	80
+#endif
+
+/* platform api */
+#define PLTFM_SDIO_CMD52_R(offset)                                             \
+	adapter->pltfm_api->SDIO_CMD52_READ(adapter->drv_adapter, offset)
+#define PLTFM_SDIO_CMD53_R8(offset)                                            \
+	adapter->pltfm_api->SDIO_CMD53_READ_8(adapter->drv_adapter, offset)
+#define PLTFM_SDIO_CMD53_R16(offset)                                           \
+	adapter->pltfm_api->SDIO_CMD53_READ_16(adapter->drv_adapter, offset)
+#define PLTFM_SDIO_CMD53_R32(offset)                                           \
+	adapter->pltfm_api->SDIO_CMD53_READ_32(adapter->drv_adapter, offset)
+#define PLTFM_SDIO_CMD53_RN(offset, size, data)                                \
+	adapter->pltfm_api->SDIO_CMD53_READ_N(adapter->drv_adapter, offset,    \
+					      size, data)
+#define PLTFM_SDIO_CMD52_W(offset, val)                                        \
+	adapter->pltfm_api->SDIO_CMD52_WRITE(adapter->drv_adapter, offset, val)
+#define PLTFM_SDIO_CMD53_W8(offset, val)                                       \
+	adapter->pltfm_api->SDIO_CMD53_WRITE_8(adapter->drv_adapter, offset,   \
+					       val)
+#define PLTFM_SDIO_CMD53_W16(offset, val)                                      \
+	adapter->pltfm_api->SDIO_CMD53_WRITE_16(adapter->drv_adapter, offset,  \
+						val)
+#define PLTFM_SDIO_CMD53_W32(offset, val)                                      \
+	adapter->pltfm_api->SDIO_CMD53_WRITE_32(adapter->drv_adapter, offset,  \
+						val)
+#define PLTFM_SDIO_CMD52_CIA_R(offset)                                         \
+	adapter->pltfm_api->SDIO_CMD52_CIA_READ(adapter->drv_adapter, offset)
+
+#define PLTFM_REG_R8(offset)                                                   \
+	adapter->pltfm_api->REG_READ_8(adapter->drv_adapter, offset)
+#define PLTFM_REG_R16(offset)                                                  \
+	adapter->pltfm_api->REG_READ_16(adapter->drv_adapter, offset)
+#define PLTFM_REG_R32(offset)                                                  \
+	adapter->pltfm_api->REG_READ_32(adapter->drv_adapter, offset)
+#define PLTFM_REG_W8(offset, val)                                              \
+	adapter->pltfm_api->REG_WRITE_8(adapter->drv_adapter, offset, val)
+#define PLTFM_REG_W16(offset, val)                                             \
+	adapter->pltfm_api->REG_WRITE_16(adapter->drv_adapter, offset, val)
+#define PLTFM_REG_W32(offset, val)                                             \
+	adapter->pltfm_api->REG_WRITE_32(adapter->drv_adapter, offset, val)
+
+#define PLTFM_SEND_RSVD_PAGE(buf, size)                                        \
+	adapter->pltfm_api->SEND_RSVD_PAGE(adapter->drv_adapter, buf, size)
+#define PLTFM_SEND_H2C_PKT(buf, size)                                          \
+	adapter->pltfm_api->SEND_H2C_PKT(adapter->drv_adapter, buf, size)
+
+#define PLTFM_EVENT_SIG(feature_id, proc_status, buf, size)                    \
+	adapter->pltfm_api->EVENT_INDICATION(adapter->drv_adapter, feature_id, \
+					     proc_status, buf, size)
+
+#define HALMAC_REG_R8(offset) api->halmac_reg_read_8(adapter, offset)
+#define HALMAC_REG_R16(offset) api->halmac_reg_read_16(adapter, offset)
+#define HALMAC_REG_R32(offset) api->halmac_reg_read_32(adapter, offset)
+#define HALMAC_REG_W8(offset, val) api->halmac_reg_write_8(adapter, offset, val)
+#define HALMAC_REG_W16(offset, val)                                            \
+	api->halmac_reg_write_16(adapter, offset, val)
+#define HALMAC_REG_W32(offset, val)                                            \
+	api->halmac_reg_write_32(adapter, offset, val)
+#define HALMAC_REG_SDIO_RN(offset, size, data)                                 \
+	api->halmac_reg_sdio_cmd53_read_n(adapter, offset, size, data)
+
+#define HALMAC_REG_W8_CLR(offset, mask)                                        \
+	do {                                                                   \
+		u32 __offset = (u32)offset;                                    \
+		HALMAC_REG_W8(__offset, HALMAC_REG_R8(__offset) & ~(mask));    \
+	} while (0)
+#define HALMAC_REG_W16_CLR(offset, mask)                                       \
+	do {                                                                   \
+		u32 __offset = (u32)offset;                                    \
+		HALMAC_REG_W16(__offset, HALMAC_REG_R16(__offset) & ~(mask));  \
+	} while (0)
+#define HALMAC_REG_W32_CLR(offset, mask)                                       \
+	do {                                                                   \
+		u32 __offset = (u32)offset;                                    \
+		HALMAC_REG_W32(__offset, HALMAC_REG_R32(__offset) & ~(mask));  \
+	} while (0)
+
+#define HALMAC_REG_W8_SET(offset, mask)                                        \
+	do {                                                                   \
+		u32 __offset = (u32)offset;                                    \
+		HALMAC_REG_W8(__offset, HALMAC_REG_R8(__offset) | mask);       \
+	} while (0)
+#define HALMAC_REG_W16_SET(offset, mask)                                       \
+	do {                                                                   \
+		u32 __offset = (u32)offset;                                    \
+		HALMAC_REG_W16(__offset, HALMAC_REG_R16(__offset) | mask);     \
+	} while (0)
+#define HALMAC_REG_W32_SET(offset, mask)                                       \
+	do {                                                                   \
+		u32 __offset = (u32)offset;                                    \
+		HALMAC_REG_W32(__offset, HALMAC_REG_R32(__offset) | mask);     \
+	} while (0)
+
+#ifndef HALMAC_BIT_OFFSET_VAL_MASK_32
+#define HALMAC_BIT_OFFSET_VAL_MASK_32(__bitval, __bitoffset)                   \
+	(__bitval << (__bitoffset))
+#endif
+
+#ifndef GET_H2C_FIELD
+#define GET_H2C_FIELD   LE_BITS_TO_4BYTE
+#endif
+
+#ifndef SET_H2C_FIELD_CLR
+#define SET_H2C_FIELD_CLR       SET_BITS_TO_LE_4BYTE
+#endif
+
+#ifndef SET_H2C_FIELD_NO_CLR
+#define SET_H2C_FIELD_NO_CLR    SET_BITS_TO_LE_4BYTE
+#endif
+
+#ifndef GET_C2H_FIELD
+#define GET_C2H_FIELD   LE_BITS_TO_4BYTE
+#endif
+
+#ifndef SET_C2H_FIELD_CLR
+#define SET_C2H_FIELD_CLR       SET_BITS_TO_LE_4BYTE
+#endif
+
+#ifndef SET_C2H_FIELD_NO_CLR
+#define SET_C2H_FIELD_NO_CLR    SET_BITS_TO_LE_4BYTE
+#endif
+
+/* HALMAC API return status*/
+enum halmac_ret_status {
+	HALMAC_RET_SUCCESS = 0x00,
+	HALMAC_RET_NOT_SUPPORT = 0x01,
+	HALMAC_RET_SUCCESS_ENQUEUE = 0x01, /*Don't use this return code!!*/
+	HALMAC_RET_PLATFORM_API_NULL = 0x02,
+	HALMAC_RET_EFUSE_SIZE_INCORRECT = 0x03,
+	HALMAC_RET_MALLOC_FAIL = 0x04,
+	HALMAC_RET_ADAPTER_INVALID = 0x05,
+	HALMAC_RET_ITF_INCORRECT = 0x06,
+	HALMAC_RET_DLFW_FAIL = 0x07,
+	HALMAC_RET_PORT_NOT_SUPPORT = 0x08,
+	HALMAC_RET_TXAGG_OVERFLOW = 0x09,
+	HALMAC_RET_INIT_LLT_FAIL = 0x0A,
+	HALMAC_RET_POWER_STATE_INVALID = 0x0B,
+	HALMAC_RET_H2C_ACK_NOT_RECEIVED = 0x0C,
+	HALMAC_RET_DL_RSVD_PAGE_FAIL = 0x0D,
+	HALMAC_RET_EFUSE_R_FAIL = 0x0E,
+	HALMAC_RET_EFUSE_W_FAIL = 0x0F,
+	HALMAC_RET_H2C_SW_RES_FAIL = 0x10,
+	HALMAC_RET_SEND_H2C_FAIL = 0x11,
+	HALMAC_RET_PARA_NOT_SUPPORT = 0x12,
+	HALMAC_RET_PLATFORM_API_INCORRECT = 0x13,
+	HALMAC_RET_ENDIAN_ERR = 0x14,
+	HALMAC_RET_FW_SIZE_ERR = 0x15,
+	HALMAC_RET_TRX_MODE_NOT_SUPPORT = 0x16,
+	HALMAC_RET_FAIL = 0x17,
+	HALMAC_RET_CHANGE_PS_FAIL = 0x18,
+	HALMAC_RET_CFG_PARA_FAIL = 0x19,
+	HALMAC_RET_UPDATE_PROBE_FAIL = 0x1A,
+	HALMAC_RET_SCAN_FAIL = 0x1B,
+	HALMAC_RET_STOP_SCAN_FAIL = 0x1C,
+	HALMAC_RET_BCN_PARSER_CMD_FAIL = 0x1D,
+	HALMAC_RET_POWER_ON_FAIL = 0x1E,
+	HALMAC_RET_POWER_OFF_FAIL = 0x1F,
+	HALMAC_RET_RX_AGG_MODE_FAIL = 0x20,
+	HALMAC_RET_DATA_BUF_NULL = 0x21,
+	HALMAC_RET_DATA_SIZE_INCORRECT = 0x22,
+	HALMAC_RET_QSEL_INCORRECT = 0x23,
+	HALMAC_RET_DMA_MAP_INCORRECT = 0x24,
+	HALMAC_RET_SEND_ORIGINAL_H2C_FAIL = 0x25,
+	HALMAC_RET_DDMA_FAIL = 0x26,
+	HALMAC_RET_FW_CHECKSUM_FAIL = 0x27,
+	HALMAC_RET_PWRSEQ_POLLING_FAIL = 0x28,
+	HALMAC_RET_PWRSEQ_CMD_INCORRECT = 0x29,
+	HALMAC_RET_WRITE_DATA_FAIL = 0x2A,
+	HALMAC_RET_DUMP_FIFOSIZE_INCORRECT = 0x2B,
+	HALMAC_RET_NULL_POINTER = 0x2C,
+	HALMAC_RET_PROBE_NOT_FOUND = 0x2D,
+	HALMAC_RET_FW_NO_MEMORY = 0x2E,
+	HALMAC_RET_H2C_STATUS_ERR = 0x2F,
+	HALMAC_RET_GET_H2C_SPACE_ERR = 0x30,
+	HALMAC_RET_H2C_SPACE_FULL = 0x31,
+	HALMAC_RET_DATAPACK_NO_FOUND = 0x32,
+	HALMAC_RET_CANNOT_FIND_H2C_RESOURCE = 0x33,
+	HALMAC_RET_TX_DMA_ERR = 0x34,
+	HALMAC_RET_RX_DMA_ERR = 0x35,
+	HALMAC_RET_CHIP_NOT_SUPPORT = 0x36,
+	HALMAC_RET_FREE_SPACE_NOT_ENOUGH = 0x37,
+	HALMAC_RET_CH_SW_SEQ_WRONG = 0x38,
+	HALMAC_RET_CH_SW_NO_BUF = 0x39,
+	HALMAC_RET_SW_CASE_NOT_SUPPORT = 0x3A,
+	HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL = 0x3B,
+	HALMAC_RET_INVALID_SOUNDING_SETTING = 0x3C,
+	HALMAC_RET_GEN_INFO_NOT_SENT = 0x3D,
+	HALMAC_RET_STATE_INCORRECT = 0x3E,
+	HALMAC_RET_H2C_BUSY = 0x3F,
+	HALMAC_RET_INVALID_FEATURE_ID = 0x40,
+	HALMAC_RET_BUFFER_TOO_SMALL = 0x41,
+	HALMAC_RET_ZERO_LEN_RSVD_PACKET = 0x42,
+	HALMAC_RET_BUSY_STATE = 0x43,
+	HALMAC_RET_ERROR_STATE = 0x44,
+	HALMAC_RET_API_INVALID = 0x45,
+	HALMAC_RET_POLLING_BCN_VALID_FAIL = 0x46,
+	HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL = 0x47,
+	HALMAC_RET_EEPROM_PARSING_FAIL = 0x48,
+	HALMAC_RET_EFUSE_NOT_ENOUGH = 0x49,
+	HALMAC_RET_WRONG_ARGUMENT = 0x4A,
+	HALMAC_RET_C2H_NOT_HANDLED = 0x4C,
+	HALMAC_RET_PARA_SENDING = 0x4D,
+	HALMAC_RET_CFG_DLFW_SIZE_FAIL = 0x4E,
+	HALMAC_RET_CFG_TXFIFO_PAGE_FAIL = 0x4F,
+	HALMAC_RET_SWITCH_CASE_ERROR = 0x50,
+	HALMAC_RET_EFUSE_BANK_INCORRECT = 0x51,
+	HALMAC_RET_SWITCH_EFUSE_BANK_FAIL = 0x52,
+	HALMAC_RET_USB_MODE_UNCHANGE = 0x53,
+	HALMAC_RET_NO_DLFW = 0x54,
+	HALMAC_RET_USB2_3_SWITCH_UNSUPPORT = 0x55,
+	HALMAC_RET_BIP_NO_SUPPORT = 0x56,
+	HALMAC_RET_ENTRY_INDEX_ERROR = 0x57,
+	HALMAC_RET_ENTRY_KEY_ID_ERROR = 0x58,
+	HALMAC_RET_DRV_DL_ERR = 0x59,
+	HALMAC_RET_OQT_NOT_ENOUGH = 0x5A,
+	HALMAC_RET_PWR_UNCHANGE = 0x5B,
+	HALMAC_RET_WRONG_INTF = 0x5C,
+	HALMAC_RET_POLLING_HIOE_REQ_FAIL = 0x5E,
+	HALMAC_RET_HIOE_CHKSUM_FAIL = 0x5F,
+	HALMAC_RET_HIOE_ERR = 0x60,
+	HALMAC_RET_FW_NO_SUPPORT = 0x60,
+	HALMAC_RET_TXFIFO_NO_EMPTY = 0x61,
+	HALMAC_RET_SDIO_CLOCK_ERR = 0x62,
+	HALMAC_RET_GET_PINMUX_ERR = 0x63,
+	HALMAC_RET_PINMUX_USED = 0x64,
+	HALMAC_RET_WRONG_GPIO = 0x65,
+	HALMAC_RET_LTECOEX_READY_FAIL = 0x66,
+	HALMAC_RET_IDMEM_CHKSUM_FAIL = 0x67,
+	HALMAC_RET_ILLEGAL_KEY_FAIL = 0x68,
+	HALMAC_RET_FW_READY_CHK_FAIL = 0x69,
+	HALMAC_RET_RSVD_PG_OVERFLOW_FAIL = 0x70,
+	HALMAC_RET_THRESHOLD_FAIL = 0x71,
+	HALMAC_RET_SDIO_MIX_MODE = 0x72,
+	HALMAC_RET_TXDESC_SET_FAIL = 0x73,
+	HALMAC_RET_WLHDR_FAIL = 0x74,
+	HALMAC_RET_WLAN_MODE_FAIL = 0x75,
+};
+
+enum halmac_chip_id {
+	HALMAC_CHIP_ID_8822B = 0,
+	HALMAC_CHIP_ID_8821C = 1,
+	HALMAC_CHIP_ID_8814B = 2,
+	HALMAC_CHIP_ID_8197F = 3,
+	HALMAC_CHIP_ID_8822C = 4,
+	HALMAC_CHIP_ID_UNDEFINE = 0x7F,
+};
+
+enum halmac_chip_ver {
+	HALMAC_CHIP_VER_A_CUT = 0x00,
+	HALMAC_CHIP_VER_B_CUT = 0x01,
+	HALMAC_CHIP_VER_C_CUT = 0x02,
+	HALMAC_CHIP_VER_D_CUT = 0x03,
+	HALMAC_CHIP_VER_E_CUT = 0x04,
+	HALMAC_CHIP_VER_F_CUT = 0x05,
+	HALMAC_CHIP_VER_TEST = 0xFF,
+	HALMAC_CHIP_VER_UNDEFINE = 0x7FFF,
+};
+
+enum halmac_network_type_select {
+	HALMAC_NETWORK_NO_LINK = 0,
+	HALMAC_NETWORK_ADHOC = 1,
+	HALMAC_NETWORK_INFRASTRUCTURE = 2,
+	HALMAC_NETWORK_AP = 3,
+	HALMAC_NETWORK_UNDEFINE = 0x7F,
+};
+
+enum halmac_transfer_mode_select {
+	HALMAC_TRNSFER_NORMAL = 0x0,
+	HALMAC_TRNSFER_LOOPBACK_DIRECT = 0xB,
+	HALMAC_TRNSFER_LOOPBACK_DELAY = 0x3,
+	HALMAC_TRNSFER_UNDEFINE = 0x7F,
+};
+
+enum halmac_dma_mapping {
+	HALMAC_DMA_MAPPING_EXTRA = 0,
+	HALMAC_DMA_MAPPING_LOW = 1,
+	HALMAC_DMA_MAPPING_NORMAL = 2,
+	HALMAC_DMA_MAPPING_HIGH = 3,
+	HALMAC_DMA_MAPPING_UNDEFINE = 0x7F,
+};
+
+enum halmac_io_size {
+	HALMAC_IO_BYTE = 0x0,
+	HALMAC_IO_WORD = 0x1,
+	HALMAC_IO_DWORD = 0x2,
+	HALMAC_IO_UNDEFINE = 0x7F,
+};
+
+#define HALMAC_MAP2_HQ		HALMAC_DMA_MAPPING_HIGH
+#define HALMAC_MAP2_NQ		HALMAC_DMA_MAPPING_NORMAL
+#define HALMAC_MAP2_LQ		HALMAC_DMA_MAPPING_LOW
+#define HALMAC_MAP2_EXQ		HALMAC_DMA_MAPPING_EXTRA
+#define HALMAC_MAP2_UNDEF	HALMAC_DMA_MAPPING_UNDEFINE
+
+enum halmac_txdesc_queue_tid {
+	HALMAC_TXDESC_QSEL_TID0 = 0,
+	HALMAC_TXDESC_QSEL_TID1 = 1,
+	HALMAC_TXDESC_QSEL_TID2 = 2,
+	HALMAC_TXDESC_QSEL_TID3 = 3,
+	HALMAC_TXDESC_QSEL_TID4 = 4,
+	HALMAC_TXDESC_QSEL_TID5 = 5,
+	HALMAC_TXDESC_QSEL_TID6 = 6,
+	HALMAC_TXDESC_QSEL_TID7 = 7,
+	HALMAC_TXDESC_QSEL_TID8 = 8,
+	HALMAC_TXDESC_QSEL_TID9 = 9,
+	HALMAC_TXDESC_QSEL_TIDA = 10,
+	HALMAC_TXDESC_QSEL_TIDB = 11,
+	HALMAC_TXDESC_QSEL_TIDC = 12,
+	HALMAC_TXDESC_QSEL_TIDD = 13,
+	HALMAC_TXDESC_QSEL_TIDE = 14,
+	HALMAC_TXDESC_QSEL_TIDF = 15,
+
+	HALMAC_TXDESC_QSEL_BEACON = 0x10,
+	HALMAC_TXDESC_QSEL_HIGH = 0x11,
+	HALMAC_TXDESC_QSEL_MGT = 0x12,
+	HALMAC_TXDESC_QSEL_H2C_CMD = 0x13,
+	HALMAC_TXDESC_QSEL_FWCMD = 0x14,
+
+	HALMAC_TXDESC_QSEL_UNDEFINE = 0x7F,
+};
+
+enum halmac_pq_map_id {
+	HALMAC_PQ_MAP_VO = 0x0,
+	HALMAC_PQ_MAP_VI = 0x1,
+	HALMAC_PQ_MAP_BE = 0x2,
+	HALMAC_PQ_MAP_BK = 0x3,
+	HALMAC_PQ_MAP_MG = 0x4,
+	HALMAC_PQ_MAP_HI = 0x5,
+	HALMAC_PQ_MAP_NUM = 0x6,
+	HALMAC_PQ_MAP_UNDEF = 0x7F,
+};
+
+enum halmac_qsel {
+	HALMAC_QSEL_VO = HALMAC_TXDESC_QSEL_TID6,
+	HALMAC_QSEL_VI = HALMAC_TXDESC_QSEL_TID4,
+	HALMAC_QSEL_BE = HALMAC_TXDESC_QSEL_TID0,
+	HALMAC_QSEL_BK = HALMAC_TXDESC_QSEL_TID1,
+	HALMAC_QSEL_VO_V2 = HALMAC_TXDESC_QSEL_TID7,
+	HALMAC_QSEL_VI_V2 = HALMAC_TXDESC_QSEL_TID5,
+	HALMAC_QSEL_BE_V2 = HALMAC_TXDESC_QSEL_TID3,
+	HALMAC_QSEL_BK_V2 = HALMAC_TXDESC_QSEL_TID2,
+	HALMAC_QSEL_TID8 = HALMAC_TXDESC_QSEL_TID8,
+	HALMAC_QSEL_TID9 = HALMAC_TXDESC_QSEL_TID9,
+	HALMAC_QSEL_TIDA = HALMAC_TXDESC_QSEL_TIDA,
+	HALMAC_QSEL_TIDB = HALMAC_TXDESC_QSEL_TIDB,
+	HALMAC_QSEL_TIDC = HALMAC_TXDESC_QSEL_TIDC,
+	HALMAC_QSEL_TIDD = HALMAC_TXDESC_QSEL_TIDD,
+	HALMAC_QSEL_TIDE = HALMAC_TXDESC_QSEL_TIDE,
+	HALMAC_QSEL_TIDF = HALMAC_TXDESC_QSEL_TIDF,
+	HALMAC_QSEL_BCN = HALMAC_TXDESC_QSEL_BEACON,
+	HALMAC_QSEL_HIGH = HALMAC_TXDESC_QSEL_HIGH,
+	HALMAC_QSEL_MGNT = HALMAC_TXDESC_QSEL_MGT,
+	HALMAC_QSEL_CMD = HALMAC_TXDESC_QSEL_H2C_CMD,
+	HALMAC_QSEL_FWCMD = HALMAC_TXDESC_QSEL_FWCMD,
+	HALMAC_QSEL_UNDEFINE = 0x7F,
+};
+
+enum halmac_acq_id {
+	HALMAC_ACQ_ID_VO = 0,
+	HALMAC_ACQ_ID_VI = 1,
+	HALMAC_ACQ_ID_BE = 2,
+	HALMAC_ACQ_ID_BK = 3,
+	HALMAC_ACQ_ID_MAX = 0x7F,
+};
+
+enum halmac_txdesc_dma_ch {
+	HALMAC_TXDESC_DMA_CH0 = 0,
+	HALMAC_TXDESC_DMA_CH1 = 1,
+	HALMAC_TXDESC_DMA_CH2 = 2,
+	HALMAC_TXDESC_DMA_CH3 = 3,
+	HALMAC_TXDESC_DMA_CH4 = 4,
+	HALMAC_TXDESC_DMA_CH5 = 5,
+	HALMAC_TXDESC_DMA_CH6 = 6,
+	HALMAC_TXDESC_DMA_CH7 = 7,
+	HALMAC_TXDESC_DMA_CH8 = 8,
+	HALMAC_TXDESC_DMA_CH9 = 9,
+	HALMAC_TXDESC_DMA_CH10 = 10,
+	HALMAC_TXDESC_DMA_CH11 = 11,
+	HALMAC_TXDESC_DMA_CH12 = 12,
+	HALMAC_TXDESC_DMA_CH13 = 13,
+	HALMAC_TXDESC_DMA_CH14 = 14,
+	HALMAC_TXDESC_DMA_CH15 = 15,
+	HALMAC_TXDESC_DMA_CH16 = 16,
+	HALMAC_TXDESC_DMA_CH17 = 17,
+	HALMAC_TXDESC_DMA_CH18 = 18,
+	HALMAC_TXDESC_DMA_CH19 = 19,
+	HALMAC_TXDESC_DMA_CH20 = 20,
+	HALMAC_TXDESC_DMA_CHMAX,
+	HALMAC_TXDESC_DMA_CHUNDEFINE = 0x7F,
+};
+
+enum halmac_dma_ch {
+	HALMAC_DMA_CH_0 = HALMAC_TXDESC_DMA_CH0,
+	HALMAC_DMA_CH_1 = HALMAC_TXDESC_DMA_CH1,
+	HALMAC_DMA_CH_2 = HALMAC_TXDESC_DMA_CH2,
+	HALMAC_DMA_CH_3 = HALMAC_TXDESC_DMA_CH3,
+	HALMAC_DMA_CH_4 = HALMAC_TXDESC_DMA_CH4,
+	HALMAC_DMA_CH_5 = HALMAC_TXDESC_DMA_CH5,
+	HALMAC_DMA_CH_6 = HALMAC_TXDESC_DMA_CH6,
+	HALMAC_DMA_CH_7 = HALMAC_TXDESC_DMA_CH7,
+	HALMAC_DMA_CH_8 = HALMAC_TXDESC_DMA_CH8,
+	HALMAC_DMA_CH_9 = HALMAC_TXDESC_DMA_CH9,
+	HALMAC_DMA_CH_10 = HALMAC_TXDESC_DMA_CH10,
+	HALMAC_DMA_CH_11 = HALMAC_TXDESC_DMA_CH11,
+	HALMAC_DMA_CH_S0 = HALMAC_TXDESC_DMA_CH12,
+	HALMAC_DMA_CH_S1 = HALMAC_TXDESC_DMA_CH13,
+	HALMAC_DMA_CH_MGQ = HALMAC_TXDESC_DMA_CH14,
+	HALMAC_DMA_CH_HIGH = HALMAC_TXDESC_DMA_CH15,
+	HALMAC_DMA_CH_FWCMD = HALMAC_TXDESC_DMA_CH16,
+	HALMAC_DMA_CH_MGQ_BAND1 = HALMAC_TXDESC_DMA_CH17,
+	HALMAC_DMA_CH_HIGH_BAND1 = HALMAC_TXDESC_DMA_CH18,
+	HALMAC_DMA_CH_BCN = HALMAC_TXDESC_DMA_CH19,
+	HALMAC_DMA_CH_H2C = HALMAC_TXDESC_DMA_CH20,
+	HALMAC_DMA_CH_MAX = HALMAC_TXDESC_DMA_CHMAX,
+	HALMAC_DMA_CH_UNDEFINE = 0x7F,
+};
+
+enum halmac_interface {
+	HALMAC_INTERFACE_PCIE = 0x0,
+	HALMAC_INTERFACE_USB = 0x1,
+	HALMAC_INTERFACE_SDIO = 0x2,
+	HALMAC_INTERFACE_AXI = 0x3,
+	HALMAC_INTERFACE_UNDEFINE = 0x7F,
+};
+
+enum halmac_rx_agg_mode {
+	HALMAC_RX_AGG_MODE_NONE = 0x0,
+	HALMAC_RX_AGG_MODE_DMA = 0x1,
+	HALMAC_RX_AGG_MODE_USB = 0x2,
+	HALMAC_RX_AGG_MODE_UNDEFINE = 0x7F,
+};
+
+struct halmac_rxagg_th {
+	u8 drv_define;
+	u8 timeout;
+	u8 size;
+	u8 size_limit_en;
+};
+
+struct halmac_rxagg_cfg {
+	enum halmac_rx_agg_mode mode;
+	struct halmac_rxagg_th threshold;
+};
+
+struct halmac_api_registry {
+	u8 rx_exp_en:1;
+	u8 la_mode_en:1;
+	u8 cfg_drv_rsvd_pg_en:1;
+	u8 sdio_cmd53_4byte_en:1;
+	u8 rsvd:4;
+};
+
+enum halmac_trx_mode {
+	HALMAC_TRX_MODE_NORMAL = 0x0,
+	HALMAC_TRX_MODE_TRXSHARE = 0x1,
+	HALMAC_TRX_MODE_WMM = 0x2,
+	HALMAC_TRX_MODE_P2P = 0x3,
+	HALMAC_TRX_MODE_LOOPBACK = 0x4,
+	HALMAC_TRX_MODE_DELAY_LOOPBACK = 0x5,
+	HALMAC_TRX_MODE_MAX = 0x6,
+	HALMAC_TRX_MODE_WMM_LINUX = 0x7E,
+	HALMAC_TRX_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_wireless_mode {
+	HALMAC_WIRELESS_MODE_B = 0x0,
+	HALMAC_WIRELESS_MODE_G = 0x1,
+	HALMAC_WIRELESS_MODE_N = 0x2,
+	HALMAC_WIRELESS_MODE_AC = 0x3,
+	HALMAC_WIRELESS_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_bw {
+	HALMAC_BW_20 = 0x00,
+	HALMAC_BW_40 = 0x01,
+	HALMAC_BW_80 = 0x02,
+	HALMAC_BW_160 = 0x03,
+	HALMAC_BW_5 = 0x04,
+	HALMAC_BW_10 = 0x05,
+	HALMAC_BW_MAX = 0x06,
+	HALMAC_BW_UNDEFINE = 0x7F,
+};
+
+enum halmac_efuse_read_cfg {
+	HALMAC_EFUSE_R_AUTO = 0x00,
+	HALMAC_EFUSE_R_DRV = 0x01,
+	HALMAC_EFUSE_R_FW = 0x02,
+	HALMAC_EFUSE_R_UNDEFINE = 0x7F,
+};
+
+enum halmac_dlfw_mem {
+	HALMAC_DLFW_MEM_EMEM = 0x00,
+	HALMAC_DLFW_MEM_EMEM_RSVD_PG = 0x01,
+	HALMAC_DLFW_MEM_UNDEFINE = 0x7F,
+};
+
+struct halmac_tx_desc {
+	u32 dword0;
+	u32 dword1;
+	u32 dword2;
+	u32 dword3;
+	u32 dword4;
+	u32 dword5;
+	u32 dword6;
+	u32 dword7;
+	u32 dword8;
+	u32 dword9;
+	u32 dword10;
+	u32 dword11;
+};
+
+struct halmac_rx_desc {
+	u32 dword0;
+	u32 dword1;
+	u32 dword2;
+	u32 dword3;
+	u32 dword4;
+	u32 dword5;
+};
+
+struct halmac_bcn_ie_info {
+	u8 func_en;
+	u8 size_th;
+	u8 timeout;
+	u8 ie_bmp[HALMAC_BCN_IE_BMP_SIZE];
+};
+
+enum halmac_parameter_cmd {
+	/* HALMAC_PARAMETER_CMD_LLT	= 0x1, */
+	/* HALMAC_PARAMETER_CMD_R_EFUSE = 0x2, */
+	/* HALMAC_PARAMETER_CMD_EFUSE_PATCH = 0x3, */
+	HALMAC_PARAMETER_CMD_MAC_W8 = 0x4,
+	HALMAC_PARAMETER_CMD_MAC_W16 = 0x5,
+	HALMAC_PARAMETER_CMD_MAC_W32 = 0x6,
+	HALMAC_PARAMETER_CMD_RF_W = 0x7,
+	HALMAC_PARAMETER_CMD_BB_W8 = 0x8,
+	HALMAC_PARAMETER_CMD_BB_W16 = 0x9,
+	HALMAC_PARAMETER_CMD_BB_W32 = 0XA,
+	HALMAC_PARAMETER_CMD_DELAY_US = 0X10,
+	HALMAC_PARAMETER_CMD_DELAY_MS = 0X11,
+	HALMAC_PARAMETER_CMD_END = 0XFF,
+};
+
+union halmac_parameter_content {
+	struct _MAC_REG_W {
+		u32 value;
+		u32 msk;
+		u16 offset;
+		u8 msk_en;
+	} MAC_REG_W;
+	struct _BB_REG_W {
+		u32 value;
+		u32 msk;
+		u16 offset;
+		u8 msk_en;
+	} BB_REG_W;
+	struct _RF_REG_W {
+		u32 value;
+		u32 msk;
+		u8 offset;
+		u8 msk_en;
+		u8 rf_path;
+	} RF_REG_W;
+	struct _DELAY_TIME {
+		u32 rsvd1;
+		u32 rsvd2;
+		u16 delay_time;
+		u8 rsvd3;
+	} DELAY_TIME;
+};
+
+struct halmac_phy_parameter_info {
+	enum halmac_parameter_cmd cmd_id;
+	union halmac_parameter_content content;
+};
+
+struct halmac_pg_efuse_info {
+	u8 *efuse_map;
+	u32 efuse_map_size;
+	u8 *efuse_mask;
+	u32 efuse_mask_size;
+};
+
+struct halmac_cfg_param_info {
+	u32 buf_size;
+	u8 *buf;
+	u8 *buf_wptr;
+	u32 num;
+	u32 avl_buf_size;
+	u32 offset_accum;
+	u32 value_accum;
+	enum halmac_data_type data_type;
+	u8 full_fifo_mode;
+};
+
+struct halmac_hw_cfg_info {
+	u32 efuse_size;
+	u32 eeprom_size;
+	u32 bt_efuse_size;
+	u32 tx_fifo_size;
+	u32 rx_fifo_size;
+	u32 rx_desc_fifo_size;
+	u32 page_size;
+	u16 tx_align_size;
+	u8 txdesc_size;
+	u8 rxdesc_size;
+	u8 cam_entry_num;
+	u8 chk_security_keyid;
+	u8 txdesc_ie_max_num;
+	u8 txdesc_body_size;
+	u8 ac_oqt_size;
+	u8 non_ac_oqt_size;
+	u8 acq_num;
+	u8 trx_mode;
+	u8 usb_txagg_num;
+};
+
+struct halmac_sdio_free_space {
+	u16 hiq_pg_num;
+	u16 miq_pg_num;
+	u16 lowq_pg_num;
+	u16 pubq_pg_num;
+	u16 exq_pg_num;
+	u8 ac_oqt_num;
+	u8 non_ac_oqt_num;
+	u8 ac_empty;
+	u8 *macid_map;
+	u32 macid_map_size;
+};
+
+enum hal_fifo_sel {
+	HAL_FIFO_SEL_TX,
+	HAL_FIFO_SEL_RX,
+	HAL_FIFO_SEL_RSVD_PAGE,
+	HAL_FIFO_SEL_REPORT,
+	HAL_FIFO_SEL_LLT,
+	HAL_FIFO_SEL_RXBUF_FW,
+	HAL_FIFO_SEL_RXBUF_PHY,
+	HAL_FIFO_SEL_RXDESC,
+	HAL_BUF_SECURITY_CAM,
+	HAL_BUF_WOW_CAM,
+	HAL_BUF_RX_FILTER_CAM,
+	HAL_BUF_BA_CAM,
+	HAL_BUF_MBSSID_CAM
+};
+
+enum halmac_drv_info {
+	/* No information is appended in rx_pkt */
+	HALMAC_DRV_INFO_NONE,
+	/* PHY status is appended after rx_desc */
+	HALMAC_DRV_INFO_PHY_STATUS,
+	/* PHY status and sniffer info are appended after rx_desc */
+	HALMAC_DRV_INFO_PHY_SNIFFER,
+	/* PHY status and plcp header are appended after rx_desc */
+	HALMAC_DRV_INFO_PHY_PLCP,
+	HALMAC_DRV_INFO_UNDEFINE,
+};
+
+enum halmac_pri_ch_idx {
+	HALMAC_CH_IDX_UNDEFINE = 0,
+	HALMAC_CH_IDX_1 = 1,
+	HALMAC_CH_IDX_2 = 2,
+	HALMAC_CH_IDX_3 = 3,
+	HALMAC_CH_IDX_4 = 4,
+	HALMAC_CH_IDX_MAX = 5,
+};
+
+struct halmac_ch_info {
+	enum halmac_cs_action_id action_id;
+	enum halmac_bw bw;
+	enum halmac_pri_ch_idx pri_ch_idx;
+	u8 channel;
+	u8 timeout;
+	u8 extra_info;
+};
+
+struct halmac_ch_extra_info {
+	u8 extra_info;
+	enum halmac_cs_extra_action_id extra_action_id;
+	u8 extra_info_size;
+	u8 *extra_info_data;
+};
+
+enum halmac_cs_periodic_option {
+	HALMAC_CS_PERIODIC_NONE,
+	HALMAC_CS_PERIODIC_NORMAL,
+	HALMAC_CS_PERIODIC_2_PHASE,
+	HALMAC_CS_PERIODIC_SEAMLESS,
+};
+
+struct halmac_ch_switch_option {
+	enum halmac_bw dest_bw;
+	enum halmac_cs_periodic_option periodic_option;
+	enum halmac_pri_ch_idx dest_pri_ch_idx;
+	/* u32 tsf_high; */
+	u32 tsf_low;
+	u8 switch_en;
+	u8 dest_ch_en;
+	u8 absolute_time_en;
+	u8 dest_ch;
+	u8 normal_period;
+	u8 normal_period_sel;
+	u8 normal_cycle;
+	u8 phase_2_period;
+	u8 phase_2_period_sel;
+};
+
+struct halmac_p2pps {
+	u8 offload_en:1;
+	u8 role:1;
+	u8 ctwindow_en:1;
+	u8 noa_en:1;
+	u8 noa_sel:1;
+	u8 all_sta_sleep:1;
+	u8 discovery:1;
+	u8 disable_close_rf:1;
+	u8 p2p_port_id;
+	u8 p2p_group;
+	u8 p2p_macid;
+	u8 ctwindow_length;
+	u8 rsvd3;
+	u8 rsvd4;
+	u8 rsvd5;
+	u32 noa_duration_para;
+	u32 noa_interval_para;
+	u32 noa_start_time_para;
+	u32 noa_count_para;
+};
+
+struct halmac_fw_build_time {
+	u16 year;
+	u8 month;
+	u8 date;
+	u8 hour;
+	u8 min;
+};
+
+struct halmac_fw_version {
+	u16 version;
+	u8 sub_version;
+	u8 sub_index;
+	u16 h2c_version;
+	struct halmac_fw_build_time build_time;
+};
+
+enum halmac_rf_type {
+	HALMAC_RF_1T2R = 0,
+	HALMAC_RF_2T4R = 1,
+	HALMAC_RF_2T2R = 2,
+	HALMAC_RF_2T3R = 3,
+	HALMAC_RF_1T1R = 4,
+	HALMAC_RF_2T2R_GREEN = 5,
+	HALMAC_RF_3T3R = 6,
+	HALMAC_RF_3T4R = 7,
+	HALMAC_RF_4T4R = 8,
+	HALMAC_RF_MAX_TYPE = 0xF,
+};
+
+struct halmac_general_info {
+	u8 rfe_type;
+	enum halmac_rf_type rf_type;
+	u8 tx_ant_status;
+	u8 rx_ant_status;
+};
+
+struct halmac_pwr_tracking_para {
+	u8 enable;
+	u8 tx_pwr_index;
+	u8 pwr_tracking_offset_value;
+	u8 tssi_value;
+};
+
+struct halmac_pwr_tracking_option {
+	u8 type;
+	u8 bbswing_index;
+	/* pathA, pathB, pathC, pathD */
+	struct halmac_pwr_tracking_para pwr_tracking_para[4];
+};
+
+struct halmac_fast_edca_cfg {
+	enum halmac_acq_id acq_id;
+	u8 queue_to; /* unit : 32us*/
+};
+
+enum halmac_data_rate {
+	HALMAC_CCK1,
+	HALMAC_CCK2,
+	HALMAC_CCK5_5,
+	HALMAC_CCK11,
+	HALMAC_OFDM6,
+	HALMAC_OFDM9,
+	HALMAC_OFDM12,
+	HALMAC_OFDM18,
+	HALMAC_OFDM24,
+	HALMAC_OFDM36,
+	HALMAC_OFDM48,
+	HALMAC_OFDM54,
+	HALMAC_MCS0,
+	HALMAC_MCS1,
+	HALMAC_MCS2,
+	HALMAC_MCS3,
+	HALMAC_MCS4,
+	HALMAC_MCS5,
+	HALMAC_MCS6,
+	HALMAC_MCS7,
+	HALMAC_MCS8,
+	HALMAC_MCS9,
+	HALMAC_MCS10,
+	HALMAC_MCS11,
+	HALMAC_MCS12,
+	HALMAC_MCS13,
+	HALMAC_MCS14,
+	HALMAC_MCS15,
+	HALMAC_MCS16,
+	HALMAC_MCS17,
+	HALMAC_MCS18,
+	HALMAC_MCS19,
+	HALMAC_MCS20,
+	HALMAC_MCS21,
+	HALMAC_MCS22,
+	HALMAC_MCS23,
+	HALMAC_MCS24,
+	HALMAC_MCS25,
+	HALMAC_MCS26,
+	HALMAC_MCS27,
+	HALMAC_MCS28,
+	HALMAC_MCS29,
+	HALMAC_MCS30,
+	HALMAC_MCS31,
+	HALMAC_VHT_NSS1_MCS0,
+	HALMAC_VHT_NSS1_MCS1,
+	HALMAC_VHT_NSS1_MCS2,
+	HALMAC_VHT_NSS1_MCS3,
+	HALMAC_VHT_NSS1_MCS4,
+	HALMAC_VHT_NSS1_MCS5,
+	HALMAC_VHT_NSS1_MCS6,
+	HALMAC_VHT_NSS1_MCS7,
+	HALMAC_VHT_NSS1_MCS8,
+	HALMAC_VHT_NSS1_MCS9,
+	HALMAC_VHT_NSS2_MCS0,
+	HALMAC_VHT_NSS2_MCS1,
+	HALMAC_VHT_NSS2_MCS2,
+	HALMAC_VHT_NSS2_MCS3,
+	HALMAC_VHT_NSS2_MCS4,
+	HALMAC_VHT_NSS2_MCS5,
+	HALMAC_VHT_NSS2_MCS6,
+	HALMAC_VHT_NSS2_MCS7,
+	HALMAC_VHT_NSS2_MCS8,
+	HALMAC_VHT_NSS2_MCS9,
+	HALMAC_VHT_NSS3_MCS0,
+	HALMAC_VHT_NSS3_MCS1,
+	HALMAC_VHT_NSS3_MCS2,
+	HALMAC_VHT_NSS3_MCS3,
+	HALMAC_VHT_NSS3_MCS4,
+	HALMAC_VHT_NSS3_MCS5,
+	HALMAC_VHT_NSS3_MCS6,
+	HALMAC_VHT_NSS3_MCS7,
+	HALMAC_VHT_NSS3_MCS8,
+	HALMAC_VHT_NSS3_MCS9,
+	HALMAC_VHT_NSS4_MCS0,
+	HALMAC_VHT_NSS4_MCS1,
+	HALMAC_VHT_NSS4_MCS2,
+	HALMAC_VHT_NSS4_MCS3,
+	HALMAC_VHT_NSS4_MCS4,
+	HALMAC_VHT_NSS4_MCS5,
+	HALMAC_VHT_NSS4_MCS6,
+	HALMAC_VHT_NSS4_MCS7,
+	HALMAC_VHT_NSS4_MCS8,
+	HALMAC_VHT_NSS4_MCS9,
+	 /*FPGA only*/
+	HALMAC_VHT_NSS5_MCS0,
+	HALMAC_VHT_NSS6_MCS0,
+	HALMAC_VHT_NSS7_MCS0,
+	HALMAC_VHT_NSS8_MCS0
+};
+
+enum halmac_rf_path {
+	HALMAC_RF_PATH_A,
+	HALMAC_RF_PATH_B,
+	HALMAC_RF_PATH_C,
+	HALMAC_RF_PATH_D
+};
+
+enum hal_security_type {
+	HAL_SECURITY_TYPE_NONE = 0,
+	HAL_SECURITY_TYPE_WEP40 = 1,
+	HAL_SECURITY_TYPE_WEP104 = 2,
+	HAL_SECURITY_TYPE_TKIP = 3,
+	HAL_SECURITY_TYPE_AES128 = 4,
+	HAL_SECURITY_TYPE_WAPI = 5,
+	HAL_SECURITY_TYPE_AES256 = 6,
+	HAL_SECURITY_TYPE_GCMP128 = 7,
+	HAL_SECURITY_TYPE_GCMP256 = 8,
+	HAL_SECURITY_TYPE_GCMSMS4 = 9,
+	HAL_SECURITY_TYPE_BIP = 10,
+	HAL_SECURITY_TYPE_UNDEFINE = 0x7F,
+};
+
+enum hal_intf_phy {
+	HAL_INTF_PHY_USB2 = 0,
+	HAL_INTF_PHY_USB3 = 1,
+	HAL_INTF_PHY_PCIE_GEN1 = 2,
+	HAL_INTF_PHY_PCIE_GEN2 = 3,
+	HAL_INTF_PHY_UNDEFINE = 0x7F,
+};
+
+struct halmac_cut_amsdu_cfg {
+	u8 cut_amsdu_en;
+	u8 chk_len_en;
+	u8 chk_len_def_val;
+	u8 chk_len_l_th;
+	u16 chk_len_h_th;
+};
+
+enum halmac_dbg_msg_info {
+	HALMAC_DBG_ALWAYS,
+	HALMAC_DBG_ERR,
+	HALMAC_DBG_WARN,
+	HALMAC_DBG_TRACE,
+};
+
+enum halmac_dbg_msg_type {
+	HALMAC_MSG_INIT,
+	HALMAC_MSG_EFUSE,
+	HALMAC_MSG_FW,
+	HALMAC_MSG_H2C,
+	HALMAC_MSG_PWR,
+	HALMAC_MSG_SND,
+	HALMAC_MSG_COMMON,
+	HALMAC_MSG_DBI,
+	HALMAC_MSG_MDIO,
+	HALMAC_MSG_USB,
+};
+
+enum halmac_feature_id {
+	HALMAC_FEATURE_CFG_PARA,                /* Support */
+	HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,     /* Support */
+	HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,      /* Support */
+	HALMAC_FEATURE_UPDATE_PACKET,           /* Support */
+	HALMAC_FEATURE_UPDATE_DATAPACK,
+	HALMAC_FEATURE_RUN_DATAPACK,
+	HALMAC_FEATURE_CHANNEL_SWITCH,  /* Support */
+	HALMAC_FEATURE_IQK,             /* Support */
+	HALMAC_FEATURE_POWER_TRACKING,  /* Support */
+	HALMAC_FEATURE_PSD,             /* Support */
+	HALMAC_FEATURE_FW_SNDING,       /* Support */
+	HALMAC_FEATURE_ALL,             /* Support, only for reset */
+};
+
+enum halmac_drv_rsvd_pg_num {
+	HALMAC_RSVD_PG_NUM8,	/* 1K */
+	HALMAC_RSVD_PG_NUM16,   /* 2K */
+	HALMAC_RSVD_PG_NUM24,   /* 3K */
+	HALMAC_RSVD_PG_NUM32,   /* 4K */
+	HALMAC_RSVD_PG_NUM64,   /* 8K */
+	HALMAC_RSVD_PG_NUM128,  /* 16K */
+};
+
+enum halmac_pcie_cfg {
+	HALMAC_PCIE_GEN1,
+	HALMAC_PCIE_GEN2,
+	HALMAC_PCIE_CFG_UNDEFINE,
+};
+
+enum halmac_portid {
+	HALMAC_PORTID0 = 0,
+	HALMAC_PORTID1 = 1,
+	HALMAC_PORTID2 = 2,
+	HALMAC_PORTID3 = 3,
+	HALMAC_PORTID4 = 4,
+	HALMAC_PORTID_NUM = 5,
+};
+
+struct halmac_bcn_ctrl {
+	u8 dis_rx_bssid_fit;
+	u8 en_txbcn_rpt;
+	u8 dis_tsf_udt;
+	u8 en_bcn;
+	u8 en_rxbcn_rpt;
+	u8 en_p2p_ctwin;
+	u8 en_p2p_bcn_area;
+};
+
+/* User only can use  Address[6]*/
+/* Address[0] is lowest, Address[5] is highest */
+union halmac_wlan_addr {
+	u8 addr[6];
+	struct {
+		union {
+			__le32 low;
+			u8 low_byte[4];
+		};
+		union {
+			__le16 high;
+			u8 high_byte[2];
+		};
+	} addr_l_h;
+};
+
+struct halmac_platform_api {
+	/* R/W register */
+	u8 (*SDIO_CMD52_READ)(void *drv_adapter, u32 offset);
+	u8 (*SDIO_CMD53_READ_8)(void *drv_adapter, u32 offset);
+	u16 (*SDIO_CMD53_READ_16)(void *drv_adapter, u32 offset);
+	u32 (*SDIO_CMD53_READ_32)(void *drv_adapter, u32 offset);
+	u8 (*SDIO_CMD53_READ_N)(void *drv_adapter, u32 offset, u32 size,
+				u8 *data);
+	void (*SDIO_CMD52_WRITE)(void *drv_adapter, u32 offset, u8 value);
+	void (*SDIO_CMD53_WRITE_8)(void *drv_adapter, u32 offset, u8 value);
+	void (*SDIO_CMD53_WRITE_16)(void *drv_adapter, u32 offset, u16 value);
+	void (*SDIO_CMD53_WRITE_32)(void *drv_adapter, u32 offset, u32 value);
+	u8 (*REG_READ_8)(void *drv_adapter, u32 offset);
+	u16 (*REG_READ_16)(void *drv_adapter, u32 offset);
+	u32 (*REG_READ_32)(void *drv_adapter, u32 offset);
+	void (*REG_WRITE_8)(void *drv_adapter, u32 offset, u8 value);
+	void (*REG_WRITE_16)(void *drv_adapter, u32 offset, u16 value);
+	void (*REG_WRITE_32)(void *drv_adapter, u32 offset, u32 value);
+	u8 (*SDIO_CMD52_CIA_READ)(void *drv_adapter, u32 offset);
+
+	/* send pBuf to reserved page, the tx_desc is not included in pBuf */
+	/* driver need to fill tx_desc with qsel = bcn */
+	u8 (*SEND_RSVD_PAGE)(void *drv_adapter, u8 *buf, u32 size);
+	/* send pBuf to h2c queue, the tx_desc is not included in pBuf */
+	/* driver need to fill tx_desc with qsel = h2c */
+	u8 (*SEND_H2C_PKT)(void *drv_adapter, u8 *buf, u32 size);
+
+	u8 (*EVENT_INDICATION)(void *drv_adapter,
+			       enum halmac_feature_id feature_id,
+			       enum halmac_cmd_process_status process_status,
+			       u8 *buf, u32 size);
+
+};
+
+enum halmac_snd_role {
+	HAL_BFER = 0,
+	HAL_BFEE = 1,
+};
+
+enum halmac_csi_seg_len {
+	HAL_CSI_SEG_4K = 0,
+	HAL_CSI_SEG_8K = 1,
+	HAL_CSI_SEG_11K = 2,
+};
+
+struct halmac_cfg_mumimo_para {
+	enum halmac_snd_role role;
+	u8 sounding_sts[6];
+	u16 grouping_bitmap;
+	u8 mu_tx_en;
+	u32 given_gid_tab[2];
+	u32 given_user_pos[4];
+};
+
+struct halmac_su_bfer_init_para {
+	u8 userid;
+	u16 paid;
+	u16 csi_para;
+	union halmac_wlan_addr bfer_address;
+};
+
+struct halmac_mu_bfee_init_para {
+	u8 userid;
+	u16 paid;
+	u32 user_position_l;	/*for gid 0~15*/
+	u32 user_position_h;	/*for gid 16~31*/
+	u32 user_position_l_1;	/*for gid 32~47*/
+	u32 user_position_h_1;	/*for gid 48~63*/
+};
+
+struct halmac_mu_bfer_init_para {
+	u16 paid;
+	u16 csi_para;
+	u16 my_aid;
+	enum halmac_csi_seg_len csi_length_sel;
+	union halmac_wlan_addr bfer_address;
+};
+
+struct halmac_ch_sw_info {
+	u8 *buf;
+	u8 *buf_wptr;
+	u8 extra_info_en;
+	u32 buf_size;
+	u32 avl_buf_size;
+	u32 total_size;
+	u32 ch_num;
+};
+
+struct halmac_event_trigger {
+	u32 phy_efuse_map : 1;
+	u32 log_efuse_map : 1;
+	u32 rsvd1 : 28;
+};
+
+struct halmac_h2c_header_info {
+	u16 sub_cmd_id;
+	u16 content_size;
+	u8 ack;
+};
+
+struct halmac_ver {
+	u8 major_ver;
+	u8 prototype_ver;
+	u8 minor_ver;
+};
+
+enum halmac_api_id {
+	/*stuff, need to be the 1st*/
+	HALMAC_API_STUFF = 0x0,
+	/*stuff, need to be the 1st*/
+	HALMAC_API_MAC_POWER_SWITCH = 0x1,
+	HALMAC_API_DOWNLOAD_FIRMWARE = 0x2,
+	HALMAC_API_CFG_MAC_ADDR = 0x3,
+	HALMAC_API_CFG_BSSID = 0x4,
+	HALMAC_API_CFG_MULTICAST_ADDR = 0x5,
+	HALMAC_API_PRE_INIT_SYSTEM_CFG = 0x6,
+	HALMAC_API_INIT_SYSTEM_CFG = 0x7,
+	HALMAC_API_INIT_TRX_CFG = 0x8,
+	HALMAC_API_CFG_RX_AGGREGATION = 0x9,
+	HALMAC_API_INIT_PROTOCOL_CFG = 0xA,
+	HALMAC_API_INIT_EDCA_CFG = 0xB,
+	HALMAC_API_CFG_OPERATION_MODE = 0xC,
+	HALMAC_API_CFG_CH_BW = 0xD,
+	HALMAC_API_CFG_BW = 0xE,
+	HALMAC_API_INIT_WMAC_CFG = 0xF,
+	HALMAC_API_INIT_MAC_CFG = 0x10,
+	HALMAC_API_INIT_SDIO_CFG = 0x11,
+	HALMAC_API_INIT_USB_CFG = 0x12,
+	HALMAC_API_INIT_PCIE_CFG = 0x13,
+	HALMAC_API_INIT_INTERFACE_CFG = 0x14,
+	HALMAC_API_DEINIT_SDIO_CFG = 0x15,
+	HALMAC_API_DEINIT_USB_CFG = 0x16,
+	HALMAC_API_DEINIT_PCIE_CFG = 0x17,
+	HALMAC_API_DEINIT_INTERFACE_CFG = 0x18,
+	HALMAC_API_GET_EFUSE_SIZE = 0x19,
+	HALMAC_API_DUMP_EFUSE_MAP = 0x1A,
+	HALMAC_API_GET_LOGICAL_EFUSE_SIZE = 0x1D,
+	HALMAC_API_DUMP_LOGICAL_EFUSE_MAP = 0x1E,
+	HALMAC_API_WRITE_LOGICAL_EFUSE = 0x1F,
+	HALMAC_API_READ_LOGICAL_EFUSE = 0x20,
+	HALMAC_API_PG_EFUSE_BY_MAP = 0x21,
+	HALMAC_API_GET_C2H_INFO = 0x22,
+	HALMAC_API_CFG_FWLPS_OPTION = 0x23,
+	HALMAC_API_CFG_FWIPS_OPTION = 0x24,
+	HALMAC_API_ENTER_WOWLAN = 0x25,
+	HALMAC_API_LEAVE_WOWLAN = 0x26,
+	HALMAC_API_ENTER_PS = 0x27,
+	HALMAC_API_LEAVE_PS = 0x28,
+	HALMAC_API_H2C_LB = 0x29,
+	HALMAC_API_DEBUG = 0x2A,
+	HALMAC_API_CFG_PARAMETER = 0x2B,
+	HALMAC_API_UPDATE_PACKET = 0x2C,
+	HALMAC_API_BCN_IE_FILTER = 0x2D,
+	HALMAC_API_REG_READ_8 = 0x2E,
+	HALMAC_API_REG_WRITE_8 = 0x2F,
+	HALMAC_API_REG_READ_16 = 0x30,
+	HALMAC_API_REG_WRITE_16 = 0x31,
+	HALMAC_API_REG_READ_32 = 0x32,
+	HALMAC_API_REG_WRITE_32 = 0x33,
+	HALMAC_API_TX_ALLOWED_SDIO = 0x34,
+	HALMAC_API_SET_BULKOUT_NUM = 0x35,
+	HALMAC_API_GET_SDIO_TX_ADDR = 0x36,
+	HALMAC_API_GET_USB_BULKOUT_ID = 0x37,
+	HALMAC_API_TIMER_2S = 0x38,
+	HALMAC_API_FILL_TXDESC_CHECKSUM = 0x39,
+	HALMAC_API_SEND_ORIGINAL_H2C = 0x3A,
+	HALMAC_API_UPDATE_DATAPACK = 0x3B,
+	HALMAC_API_RUN_DATAPACK = 0x3C,
+	HALMAC_API_CFG_DRV_INFO = 0x3D,
+	HALMAC_API_SEND_BT_COEX = 0x3E,
+	HALMAC_API_VERIFY_PLATFORM_API = 0x3F,
+	HALMAC_API_GET_FIFO_SIZE = 0x40,
+	HALMAC_API_DUMP_FIFO = 0x41,
+	HALMAC_API_CFG_TXBF = 0x42,
+	HALMAC_API_CFG_MUMIMO = 0x43,
+	HALMAC_API_CFG_SOUNDING = 0x44,
+	HALMAC_API_DEL_SOUNDING = 0x45,
+	HALMAC_API_SU_BFER_ENTRY_INIT = 0x46,
+	HALMAC_API_SU_BFEE_ENTRY_INIT = 0x47,
+	HALMAC_API_MU_BFER_ENTRY_INIT = 0x48,
+	HALMAC_API_MU_BFEE_ENTRY_INIT = 0x49,
+	HALMAC_API_SU_BFER_ENTRY_DEL = 0x4A,
+	HALMAC_API_SU_BFEE_ENTRY_DEL = 0x4B,
+	HALMAC_API_MU_BFER_ENTRY_DEL = 0x4C,
+	HALMAC_API_MU_BFEE_ENTRY_DEL = 0x4D,
+	HALMAC_API_ADD_CH_INFO = 0x4E,
+	HALMAC_API_ADD_EXTRA_CH_INFO = 0x4F,
+	HALMAC_API_CTRL_CH_SWITCH = 0x50,
+	HALMAC_API_CLEAR_CH_INFO = 0x51,
+	HALMAC_API_SEND_GENERAL_INFO = 0x52,
+	HALMAC_API_START_IQK = 0x53,
+	HALMAC_API_CTRL_PWR_TRACKING = 0x54,
+	HALMAC_API_PSD = 0x55,
+	HALMAC_API_CFG_TX_AGG_ALIGN = 0x56,
+	HALMAC_API_QUERY_STATE = 0x57,
+	HALMAC_API_RESET_FEATURE = 0x58,
+	HALMAC_API_CHECK_FW_STATUS = 0x59,
+	HALMAC_API_DUMP_FW_DMEM = 0x5A,
+	HALMAC_API_CFG_MAX_DL_SIZE = 0x5B,
+	HALMAC_API_INIT_OBJ = 0x5C,
+	HALMAC_API_DEINIT_OBJ = 0x5D,
+	HALMAC_API_CFG_LA_MODE = 0x5E,
+	HALMAC_API_GET_HW_VALUE = 0x5F,
+	HALMAC_API_SET_HW_VALUE = 0x60,
+	HALMAC_API_CFG_DRV_RSVD_PG_NUM = 0x61,
+	HALMAC_API_WRITE_EFUSE_BT = 0x63,
+	HALMAC_API_DUMP_EFUSE_MAP_BT = 0x64,
+	HALMAC_API_DL_DRV_RSVD_PG = 0x65,
+	HALMAC_API_PCIE_SWITCH = 0x66,
+	HALMAC_API_PHY_CFG = 0x67,
+	HALMAC_API_CFG_RX_FIFO_EXPANDING_MODE = 0x68,
+	HALMAC_API_CFG_CSI_RATE = 0x69,
+	HALMAC_API_P2PPS = 0x6A,
+	HALMAC_API_CFG_TX_ADDR = 0x6B,
+	HALMAC_API_CFG_NET_TYPE = 0x6C,
+	HALMAC_API_CFG_TSF_RESET = 0x6D,
+	HALMAC_API_CFG_BCN_SPACE = 0x6E,
+	HALMAC_API_CFG_BCN_CTRL = 0x6F,
+	HALMAC_API_CFG_SIDEBAND_INT = 0x70,
+	HALMAC_API_REGISTER_API = 0x71,
+	HALMAC_API_FREE_DOWNLOAD_FIRMWARE = 0x72,
+	HALMAC_API_GET_FW_VERSION = 0x73,
+	HALMAC_API_GET_EFUSE_AVAL_SIZE = 0x74,
+	HALMAC_API_CHK_TXDESC = 0x75,
+	HALMAC_API_SDIO_CMD53_4BYTE = 0x76,
+	HALMAC_API_CFG_TRANS_ADDR = 0x77,
+	HALMAC_API_INTF_INTEGRA_TUNING	= 0x78,
+	HALMAC_API_TXFIFO_IS_EMPTY = 0x79,
+	HALMAC_API_DOWNLOAD_FLASH = 0x7A,
+	HALMAC_API_READ_FLASH = 0x7B,
+	HALMAC_API_ERASE_FLASH = 0x7C,
+	HALMAC_API_CHECK_FLASH = 0x7D,
+	HALMAC_API_SDIO_HW_INFO = 0x80,
+	HALMAC_API_READ_EFUSE_BT = 0x81,
+	HALMAC_API_CFG_EFUSE_AUTO_CHECK = 0x82,
+	HALMAC_API_CFG_PINMUX_GET_FUNC = 0x83,
+	HALMAC_API_CFG_PINMUX_SET_FUNC = 0x84,
+	HALMAC_API_CFG_PINMUX_FREE_FUNC = 0x85,
+	HALMAC_API_CFG_PINMUX_WL_LED_MODE = 0x86,
+	HALMAC_API_CFG_PINMUX_WL_LED_SW_CTRL = 0x87,
+	HALMAC_API_CFG_PINMUX_SDIO_INT_POLARITY = 0x88,
+	HALMAC_API_CFG_PINMUX_GPIO_MODE = 0x89,
+	HALMAC_API_CFG_PINMUX_GPIO_OUTPUT = 0x90,
+	HALMAC_API_REG_READ_INDIRECT_32 = 0x91,
+	HALMAC_API_REG_SDIO_CMD53_READ_N = 0x92,
+	HALMAC_API_PINMUX_PIN_STATUS = 0x94,
+	HALMAC_API_OFLD_FUNC_CFG = 0x95,
+	HALMAC_API_MASK_LOGICAL_EFUSE = 0x96,
+	HALMAC_API_RX_CUT_AMSDU_CFG = 0x97,
+	HALMAC_API_FW_SNDING = 0x98,
+	HALMAC_API_ENTER_CPU_SLEEP_MODE = 0x99,
+	HALMAC_API_GET_CPU_MODE = 0x9A,
+	HALMAC_API_DRV_FWCTRL = 0x9B,
+	HALMAC_API_EN_REF_AUTOK = 0x9C,
+	HALMAC_API_MAX
+};
+
+enum halmac_la_mode {
+	HALMAC_LA_MODE_DISABLE = 0,
+	HALMAC_LA_MODE_PARTIAL = 1,
+	HALMAC_LA_MODE_FULL = 2,
+	HALMAC_LA_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_rx_fifo_expanding_mode {
+	HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE = 0,
+	HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK = 1,
+	HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK = 2,
+	HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK = 3,
+	HALMAC_RX_FIFO_EXPANDING_MODE_4_BLOCK = 4,
+	HALMAC_RX_FIFO_EXPANDING_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_sdio_cmd53_4byte_mode {
+	HALMAC_SDIO_CMD53_4BYTE_MODE_DISABLE = 0,
+	HALMAC_SDIO_CMD53_4BYTE_MODE_RW = 1,
+	HALMAC_SDIO_CMD53_4BYTE_MODE_R = 2,
+	HALMAC_SDIO_CMD53_4BYTE_MODE_W = 3,
+	HALMAC_SDIO_CMD53_4BYTE_MODE_UNDEFINE = 0x7F,
+};
+
+enum halmac_usb_mode {
+	HALMAC_USB_MODE_U2 = 1,
+	HALMAC_USB_MODE_U3 = 2,
+};
+
+enum halmac_sdio_tx_format {
+	HALMAC_SDIO_AGG_MODE = 1,
+	HALMAC_SDIO_DUMMY_BLOCK_MODE = 2,
+	HALMAC_SDIO_DUMMY_AUTO_MODE = 3,
+};
+
+enum halmac_sdio_clk_monitor {
+	HALMAC_MONITOR_5US = 1,
+	HALMAC_MONITOR_50US = 2,
+	HALMAC_MONITOR_9MS = 3,
+};
+
+enum halmac_hw_id {
+	/* Get HW value */
+	HALMAC_HW_RQPN_MAPPING = 0x00,
+	HALMAC_HW_EFUSE_SIZE = 0x01,
+	HALMAC_HW_EEPROM_SIZE = 0x02,
+	HALMAC_HW_BT_BANK_EFUSE_SIZE = 0x03,
+	HALMAC_HW_BT_BANK1_EFUSE_SIZE = 0x04,
+	HALMAC_HW_BT_BANK2_EFUSE_SIZE = 0x05,
+	HALMAC_HW_TXFIFO_SIZE = 0x06,
+	HALMAC_HW_RXFIFO_SIZE = 0x07,
+	HALMAC_HW_RSVD_PG_BNDY = 0x08,
+	HALMAC_HW_CAM_ENTRY_NUM = 0x09,
+	HALMAC_HW_IC_VERSION = 0x0A,
+	HALMAC_HW_PAGE_SIZE = 0x0B,
+	HALMAC_HW_TX_AGG_ALIGN_SIZE = 0x0C,
+	HALMAC_HW_RX_AGG_ALIGN_SIZE = 0x0D,
+	HALMAC_HW_DRV_INFO_SIZE = 0x0E,
+	HALMAC_HW_TXFF_ALLOCATION = 0x0F,
+	HALMAC_HW_RSVD_EFUSE_SIZE = 0x10,
+	HALMAC_HW_FW_HDR_SIZE = 0x11,
+	HALMAC_HW_TX_DESC_SIZE = 0x12,
+	HALMAC_HW_RX_DESC_SIZE = 0x13,
+	HALMAC_HW_FW_MAX_SIZE = 0x14,
+	HALMAC_HW_ORI_H2C_SIZE = 0x15,
+	HALMAC_HW_RSVD_DRV_PGNUM = 0x16,
+	HALMAC_HW_TX_PAGE_SIZE = 0x17,
+	HALMAC_HW_USB_TXAGG_DESC_NUM = 0x18,
+	HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE = 0x19,
+	HALMAC_HW_AC_OQT_SIZE = 0x1C,
+	HALMAC_HW_NON_AC_OQT_SIZE = 0x1D,
+	HALMAC_HW_AC_QUEUE_NUM = 0x1E,
+	HALMAC_HW_RQPN_CH_MAPPING = 0x1F,
+	HALMAC_HW_PWR_STATE = 0x20,
+	HALMAC_HW_SDIO_INT_LAT = 0x21,
+	HALMAC_HW_SDIO_CLK_CNT = 0x22,
+	/* Set HW value */
+	HALMAC_HW_USB_MODE = 0x60,
+	HALMAC_HW_SEQ_EN = 0x61,
+	HALMAC_HW_BANDWIDTH = 0x62,
+	HALMAC_HW_CHANNEL = 0x63,
+	HALMAC_HW_PRI_CHANNEL_IDX = 0x64,
+	HALMAC_HW_EN_BB_RF = 0x65,
+	HALMAC_HW_SDIO_TX_PAGE_THRESHOLD = 0x66,
+	HALMAC_HW_AMPDU_CONFIG = 0x67,
+	HALMAC_HW_RX_SHIFT = 0x68,
+	HALMAC_HW_TXDESC_CHECKSUM = 0x69,
+	HALMAC_HW_RX_CLK_GATE = 0x6A,
+	HALMAC_HW_RXGCK_FIFO = 0x6B,
+	HALMAC_HW_RX_IGNORE = 0x6C,
+	HALMAC_HW_SDIO_TX_FORMAT = 0x6D,
+	HALMAC_HW_FAST_EDCA = 0x6E,
+	HALMAC_HW_LDO25_EN = 0x6F,
+	HALMAC_HW_PCIE_REF_AUTOK = 0x70,
+	HALMAC_HW_RTS_FULL_BW = 0x71,
+	HALMAC_HW_FREE_CNT_EN = 0x72,
+	HALMAC_HW_SDIO_WT_EN = 0x73,
+	HALMAC_HW_SDIO_CLK_MONITOR = 0x74,
+	HALMAC_HW_ID_UNDEFINE = 0x7F,
+};
+
+enum halmac_efuse_bank {
+	HALMAC_EFUSE_BANK_WIFI = 0,
+	HALMAC_EFUSE_BANK_BT = 1,
+	HALMAC_EFUSE_BANK_BT_1 = 2,
+	HALMAC_EFUSE_BANK_BT_2 = 3,
+	HALMAC_EFUSE_BANK_MAX,
+	HALMAC_EFUSE_BANK_UNDEFINE = 0X7F,
+};
+
+enum halmac_sdio_spec_ver {
+	HALMAC_SDIO_SPEC_VER_2_00 = 0,
+	HALMAC_SDIO_SPEC_VER_3_00 = 1,
+	HALMAC_SDIO_SPEC_VER_UNDEFINE = 0X7F,
+};
+
+enum halmac_gpio_func {
+	HALMAC_GPIO_FUNC_WL_LED = 0,
+	HALMAC_GPIO_FUNC_SDIO_INT = 1,
+	HALMAC_GPIO_FUNC_SW_IO_0 = 2,
+	HALMAC_GPIO_FUNC_SW_IO_1 = 3,
+	HALMAC_GPIO_FUNC_SW_IO_2 = 4,
+	HALMAC_GPIO_FUNC_SW_IO_3 = 5,
+	HALMAC_GPIO_FUNC_SW_IO_4 = 6,
+	HALMAC_GPIO_FUNC_SW_IO_5 = 7,
+	HALMAC_GPIO_FUNC_SW_IO_6 = 8,
+	HALMAC_GPIO_FUNC_SW_IO_7 = 9,
+	HALMAC_GPIO_FUNC_SW_IO_8 = 10,
+	HALMAC_GPIO_FUNC_SW_IO_9 = 11,
+	HALMAC_GPIO_FUNC_SW_IO_10 = 12,
+	HALMAC_GPIO_FUNC_SW_IO_11 = 13,
+	HALMAC_GPIO_FUNC_SW_IO_12 = 14,
+	HALMAC_GPIO_FUNC_SW_IO_13 = 15,
+	HALMAC_GPIO_FUNC_SW_IO_14 = 16,
+	HALMAC_GPIO_FUNC_SW_IO_15 = 17,
+	HALMAC_GPIO_FUNC_BT_HOST_WAKE1 = 18,
+	HALMAC_GPIO_FUNC_BT_DEV_WAKE1 = 19,
+	HALMAC_GPIO_FUNC_UNDEFINE = 0X7F,
+};
+
+enum halmac_wlled_mode {
+	HALMAC_WLLED_MODE_TRX = 0,
+	HALMAC_WLLED_MODE_TX = 1,
+	HALMAC_WLLED_MODE_RX = 2,
+	HALMAC_WLLED_MODE_SW_CTRL = 3,
+	HALMAC_WLLED_MODE_UNDEFINE = 0X7F,
+};
+
+enum halmac_psf_fcs_chk_thr {
+	HALMAC_PSF_FCS_CHK_THR_1 = 0,
+	HALMAC_PSF_FCS_CHK_THR_4 = 1,
+	HALMAC_PSF_FCS_CHK_THR_8 = 2,
+	HALMAC_PSF_FCS_CHK_THR_12 = 3,
+	HALMAC_PSF_FCS_CHK_THR_16 = 4,
+	HALMAC_PSF_FCS_CHK_THR_20 = 5,
+	HALMAC_PSF_FCS_CHK_THR_24 = 6,
+	HALMAC_PSF_FCS_CHK_THR_28 = 7,
+};
+
+struct halmac_txff_allocation {
+	u16 tx_fifo_pg_num;
+	u16 rsvd_pg_num;
+	u16 rsvd_drv_pg_num;
+	u16 acq_pg_num;
+	u16 high_queue_pg_num;
+	u16 low_queue_pg_num;
+	u16 normal_queue_pg_num;
+	u16 extra_queue_pg_num;
+	u16 pub_queue_pg_num;
+	u16 rsvd_boundary;
+	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 halmac_la_mode la_mode;
+	enum halmac_rx_fifo_expanding_mode rx_fifo_exp_mode;
+};
+
+struct halmac_rqpn_map {
+	enum halmac_dma_mapping dma_map_vo;
+	enum halmac_dma_mapping dma_map_vi;
+	enum halmac_dma_mapping dma_map_be;
+	enum halmac_dma_mapping dma_map_bk;
+	enum halmac_dma_mapping dma_map_mg;
+	enum halmac_dma_mapping dma_map_hi;
+};
+
+struct halmac_rqpn_ch_map {
+	enum halmac_dma_ch dma_map_vo;
+	enum halmac_dma_ch dma_map_vi;
+	enum halmac_dma_ch dma_map_be;
+	enum halmac_dma_ch dma_map_bk;
+	enum halmac_dma_ch dma_map_mg;
+	enum halmac_dma_ch dma_map_hi;
+};
+
+struct halmac_security_setting {
+	u8 tx_encryption;
+	u8 rx_decryption;
+	u8 bip_enable;
+	u8 compare_keyid;
+};
+
+struct halmac_cam_entry_info {
+	enum hal_security_type security_type;
+	u32 key[4];
+	u32 key_ext[4];
+	u8 mac_address[6];
+	u8 unicast;
+	u8 key_id;
+	u8 valid;
+};
+
+struct halmac_cam_entry_format {
+	u16 key_id : 2;
+	u16 type : 3;
+	u16 mic : 1;
+	u16 grp : 1;
+	u16 spp_mode : 1;
+	u16 rpt_md : 1;
+	u16 ext_sectype : 1;
+	u16 mgnt : 1;
+	u16 rsvd1 : 4;
+	u16 valid : 1;
+	u8 mac_address[6];
+	u32 key[4];
+	u32 rsvd[2];
+};
+
+struct halmac_tx_page_threshold_info {
+	u32	threshold;
+	enum halmac_dma_mapping dma_queue_sel;
+	u8 enable;
+};
+
+struct halmac_ampdu_config {
+	u8 max_agg_num;
+	u8 max_len_en;
+	u32 ht_max_len;
+	u32 vht_max_len;
+};
+
+struct halmac_rqpn {
+	enum halmac_trx_mode mode;
+	enum halmac_dma_mapping dma_map_vo;
+	enum halmac_dma_mapping dma_map_vi;
+	enum halmac_dma_mapping dma_map_be;
+	enum halmac_dma_mapping dma_map_bk;
+	enum halmac_dma_mapping dma_map_mg;
+	enum halmac_dma_mapping dma_map_hi;
+};
+
+struct halmac_ch_mapping {
+	enum halmac_trx_mode mode;
+	enum halmac_dma_ch dma_map_vo;
+	enum halmac_dma_ch dma_map_vi;
+	enum halmac_dma_ch dma_map_be;
+	enum halmac_dma_ch dma_map_bk;
+	enum halmac_dma_ch dma_map_mg;
+	enum halmac_dma_ch dma_map_hi;
+};
+
+struct halmac_pg_num {
+	enum halmac_trx_mode mode;
+	u16 hq_num;
+	u16 nq_num;
+	u16 lq_num;
+	u16 exq_num;
+	u16 gap_num;/*used for loopback mode*/
+};
+
+struct halmac_ch_pg_num {
+	enum halmac_trx_mode mode;
+	u16 ch_num[HALMAC_TXDESC_DMA_CH16 + 1];
+	u16 gap_num;
+};
+
+struct halmac_intf_phy_para {
+	u16 offset;
+	u16 value;
+	u16 ip_sel;
+	u16 cut;
+	u16 plaform;
+};
+
+struct halmac_iqk_para {
+	u8 clear;
+	u8 segment_iqk;
+};
+
+struct halmac_txdesc_ie_param {
+	u8 *start_offset;
+	u8 *end_offset;
+	u8 *ie_offset;
+	u8 *ie_exist;
+};
+
+struct halmac_sdio_hw_info {
+	enum halmac_sdio_spec_ver spec_ver;
+	u32 clock_speed;
+	u8 io_hi_speed_flag; /* Halmac internal use */
+	enum halmac_sdio_tx_format tx_addr_format;
+	u16 block_size;
+	u8 tx_seq;
+	u8 io_indir_flag; /* Halmac internal use */
+};
+
+struct halmac_edca_para {
+	u8 aifs;
+	u8 cw;
+	u16 txop_limit;
+};
+
+struct halmac_mac_rx_ignore_cfg {
+	u8 hdr_chk_en;
+	u8 fcs_chk_en;
+	u8 cck_rst_en;
+	enum halmac_psf_fcs_chk_thr fcs_chk_thr;
+};
+
+struct halmac_rx_ignore_info {
+	u8 hdr_chk_mask;
+	u8 fcs_chk_mask;
+	u8 hdr_chk_en;
+	u8 fcs_chk_en;
+	u8 cck_rst_en;
+	enum halmac_psf_fcs_chk_thr fcs_chk_thr;
+};
+
+struct halmac_pinmux_info {
+	/* byte0 */
+	u8 wl_led:1;
+	u8 sdio_int:1;
+	u8 bt_host_wake:1;
+	u8 bt_dev_wake:1;
+	u8 rsvd1:4;
+	/* byte1 */
+	u8 sw_io_0:1;
+	u8 sw_io_1:1;
+	u8 sw_io_2:1;
+	u8 sw_io_3:1;
+	u8 sw_io_4:1;
+	u8 sw_io_5:1;
+	u8 sw_io_6:1;
+	u8 sw_io_7:1;
+	/* byte2 */
+	u8 sw_io_8:1;
+	u8 sw_io_9:1;
+	u8 sw_io_10:1;
+	u8 sw_io_11:1;
+	u8 sw_io_12:1;
+	u8 sw_io_13:1;
+	u8 sw_io_14:1;
+	u8 sw_io_15:1;
+};
+
+struct halmac_ofld_func_info {
+	u32 halmac_malloc_max_sz;
+	u32 rsvd_pg_drv_buf_max_sz;
+};
+
+struct halmac_pltfm_cfg_info {
+	u32 malloc_size;
+	u32 rsvd_pg_size;
+};
+
+struct halmac_su_snding_info {
+	u8 su0_en;
+	u8 *su0_ndpa_pkt;
+	u32 su0_pkt_sz;
+};
+
+struct halmac_mu_snding_info {
+	u8 tmp;
+};
+
+struct halmac_h2c_info {
+	u32 buf_fs;
+	u32 buf_size;
+	u8 seq_num;
+};
+
+struct halmac_adapter {
+	enum halmac_dma_mapping pq_map[HALMAC_PQ_MAP_NUM];
+	enum halmac_dma_ch ch_map[HALMAC_PQ_MAP_NUM];
+	struct mutex h2c_seq_mutex; /* protect h2c seq num */
+	struct mutex efuse_mutex; /*protect adapter efuse map */
+	struct mutex sdio_indir_mutex; /*protect sdio indirect access */
+	struct halmac_cfg_param_info cfg_param_info;
+	struct halmac_ch_sw_info ch_sw_info;
+	struct halmac_event_trigger evnt;
+	struct halmac_hw_cfg_info hw_cfg_info;
+	struct halmac_sdio_free_space sdio_fs;
+	struct halmac_api_registry api_registry;
+	struct halmac_pinmux_info pinmux_info;
+	struct halmac_pltfm_cfg_info pltfm_info;
+	struct halmac_h2c_info h2c_info;
+	void *drv_adapter;
+	u8 *efuse_map;
+	void *halmac_api;
+	struct halmac_platform_api *pltfm_api;
+	u32 efuse_end;
+	u32 dlfw_pkt_size;
+	enum halmac_chip_id chip_id;
+	enum halmac_chip_ver chip_ver;
+	struct halmac_fw_version fw_ver;
+	struct halmac_state halmac_state;
+	enum halmac_interface intf;
+	enum halmac_trx_mode trx_mode;
+	struct halmac_txff_allocation txff_alloc;
+	u8 efuse_map_valid;
+	u8 efuse_seg_size;
+	u8 rpwm;
+	u8 bulkout_num;
+	u8 drv_info_size;
+	enum halmac_sdio_cmd53_4byte_mode sdio_cmd53_4byte;
+	struct halmac_sdio_hw_info sdio_hw_info;
+	u8 tx_desc_transfer;
+	u8 tx_desc_checksum;
+	u8 efuse_auto_check_en;
+	u8 pcie_refautok_en;
+	u8 pwr_off_flow_flag;
+	struct halmac_rx_ignore_info rx_ignore_info;
+};
+
+struct halmac_api {
+	enum halmac_ret_status
+	(*halmac_register_api)(struct halmac_adapter *adapter,
+			       struct halmac_api_registry *registry);
+	enum halmac_ret_status
+	(*halmac_mac_power_switch)(struct halmac_adapter *adapter,
+				   enum halmac_mac_power pwr);
+	enum halmac_ret_status
+	(*halmac_download_firmware)(struct halmac_adapter *adapter, u8 *fw_bin,
+				    u32 size);
+	enum halmac_ret_status
+	(*halmac_free_download_firmware)(struct halmac_adapter *adapter,
+					 enum halmac_dlfw_mem mem_sel,
+					 u8 *fw_bin, u32 size);
+	enum halmac_ret_status
+	(*halmac_get_fw_version)(struct halmac_adapter *adapter,
+				 struct halmac_fw_version *ver);
+	enum halmac_ret_status
+	(*halmac_cfg_mac_addr)(struct halmac_adapter *adapter,
+			       u8 port, union halmac_wlan_addr *addr);
+	enum halmac_ret_status
+	(*halmac_cfg_bssid)(struct halmac_adapter *adapter, u8 port,
+			    union halmac_wlan_addr *addr);
+	enum halmac_ret_status
+	(*halmac_cfg_multicast_addr)(struct halmac_adapter *adapter,
+				     union halmac_wlan_addr *addr);
+	enum halmac_ret_status
+	(*halmac_pre_init_system_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_init_system_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_init_trx_cfg)(struct halmac_adapter *adapter,
+			       enum halmac_trx_mode mode);
+	enum halmac_ret_status
+	(*halmac_init_h2c)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_cfg_rx_aggregation)(struct halmac_adapter *adapter,
+				     struct halmac_rxagg_cfg *cfg);
+	enum halmac_ret_status
+	(*halmac_init_protocol_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_init_edca_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_cfg_operation_mode)(struct halmac_adapter *adapter,
+				     enum halmac_wireless_mode mode);
+	enum halmac_ret_status
+	(*halmac_cfg_ch_bw)(struct halmac_adapter *adapter, u8 ch,
+			    enum halmac_pri_ch_idx idx, enum halmac_bw bw);
+	enum halmac_ret_status
+	(*halmac_cfg_bw)(struct halmac_adapter *adapter, enum halmac_bw bw);
+	enum halmac_ret_status
+	(*halmac_init_wmac_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_init_mac_cfg)(struct halmac_adapter *adapter,
+			       enum halmac_trx_mode mode);
+	enum halmac_ret_status
+	(*halmac_init_interface_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_deinit_interface_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_init_sdio_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_init_usb_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_init_pcie_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_deinit_sdio_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_deinit_usb_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_deinit_pcie_cfg)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_get_efuse_size)(struct halmac_adapter *adapter, u32 *size);
+	enum halmac_ret_status
+	(*halmac_get_efuse_available_size)(struct halmac_adapter *adapter,
+					   u32 *size);
+	enum halmac_ret_status
+	(*halmac_dump_efuse_map)(struct halmac_adapter *adapter,
+				 enum halmac_efuse_read_cfg cfg);
+	enum halmac_ret_status
+	(*halmac_dump_efuse_map_bt)(struct halmac_adapter *adapter,
+				    enum halmac_efuse_bank bank, u32 size,
+				    u8 *map);
+	enum halmac_ret_status
+	(*halmac_write_efuse_bt)(struct halmac_adapter *adapter, u32 offset,
+				 u8 value, enum halmac_efuse_bank bank);
+	enum halmac_ret_status
+	(*halmac_read_efuse_bt)(struct halmac_adapter *adapter, u32 offset,
+				u8 *value, enum halmac_efuse_bank bank);
+	enum halmac_ret_status
+	(*halmac_cfg_efuse_auto_check)(struct halmac_adapter *adapter,
+				       u8 enable);
+	enum halmac_ret_status
+	(*halmac_get_logical_efuse_size)(struct halmac_adapter *adapter,
+					 u32 *size);
+	enum halmac_ret_status
+	(*halmac_dump_logical_efuse_map)(struct halmac_adapter *adapter,
+					 enum halmac_efuse_read_cfg cfg);
+	enum halmac_ret_status
+	(*halmac_write_logical_efuse)(struct halmac_adapter *adapter,
+				      u32 offset, u8 value);
+	enum halmac_ret_status
+	(*halmac_read_logical_efuse)(struct halmac_adapter *adapter, u32 offset,
+				     u8 *value);
+	enum halmac_ret_status
+	(*halmac_pg_efuse_by_map)(struct halmac_adapter *adapter,
+				  struct halmac_pg_efuse_info *info,
+				  enum halmac_efuse_read_cfg cfg);
+	enum halmac_ret_status
+	(*halmac_mask_logical_efuse)(struct halmac_adapter *adapter,
+				     struct halmac_pg_efuse_info *info);
+	enum halmac_ret_status
+	(*halmac_get_c2h_info)(struct halmac_adapter *adapter, u8 *buf,
+			       u32 size);
+	enum halmac_ret_status
+	(*halmac_h2c_lb)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_debug)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_cfg_parameter)(struct halmac_adapter *adapter,
+				struct halmac_phy_parameter_info *info,
+				u8 full_fifo);
+	enum halmac_ret_status
+	(*halmac_update_packet)(struct halmac_adapter *adapter,
+				enum halmac_packet_id pkt_id, u8 *pkt,
+				u32 size);
+	enum halmac_ret_status
+	(*halmac_bcn_ie_filter)(struct halmac_adapter *adapter,
+				struct halmac_bcn_ie_info *info);
+	u8
+	(*halmac_reg_read_8)(struct halmac_adapter *adapter, u32 offset);
+	enum halmac_ret_status
+	(*halmac_reg_write_8)(struct halmac_adapter *adapter, u32 offset,
+			      u8 value);
+	u16
+	(*halmac_reg_read_16)(struct halmac_adapter *adapter, u32 offset);
+	enum halmac_ret_status
+	(*halmac_reg_write_16)(struct halmac_adapter *adapter, u32 offset,
+			       u16 value);
+	u32
+	(*halmac_reg_read_32)(struct halmac_adapter *adapter, u32 offset);
+	enum halmac_ret_status
+	(*halmac_reg_write_32)(struct halmac_adapter *adapter, u32 offset,
+			       u32 value);
+	u32
+	(*halmac_reg_read_indirect_32)(struct halmac_adapter *adapter,
+				       u32 offset);
+	enum halmac_ret_status
+	(*halmac_reg_sdio_cmd53_read_n)(struct halmac_adapter *adapter,
+					u32 offset, u32 size, u8 *value);
+	enum halmac_ret_status
+	(*halmac_tx_allowed_sdio)(struct halmac_adapter *adapter, u8 *buf,
+				  u32 size);
+	enum halmac_ret_status
+	(*halmac_set_bulkout_num)(struct halmac_adapter *adapter, u8 num);
+	enum halmac_ret_status
+	(*halmac_get_sdio_tx_addr)(struct halmac_adapter *adapter, u8 *buf,
+				   u32 size, u32 *cmd53_addr);
+	enum halmac_ret_status
+	(*halmac_get_usb_bulkout_id)(struct halmac_adapter *adapter, u8 *buf,
+				     u32 size, u8 *id);
+	enum halmac_ret_status
+	(*halmac_fill_txdesc_checksum)(struct halmac_adapter *adapter,
+				       u8 *txdesc);
+	enum halmac_ret_status
+	(*halmac_update_datapack)(struct halmac_adapter *adapter,
+				  enum halmac_data_type data_type,
+				  struct halmac_phy_parameter_info *info);
+	enum halmac_ret_status
+	(*halmac_run_datapack)(struct halmac_adapter *adapter,
+			       enum halmac_data_type data_type);
+	enum halmac_ret_status
+	(*halmac_cfg_drv_info)(struct halmac_adapter *adapter,
+			       enum halmac_drv_info drv_info);
+	enum halmac_ret_status
+	(*halmac_send_bt_coex)(struct halmac_adapter *adapter, u8 *buf,
+			       u32 size, u8 ack);
+	enum halmac_ret_status
+	(*halmac_verify_platform_api)(struct halmac_adapter *adapter);
+	u32
+	(*halmac_get_fifo_size)(struct halmac_adapter *adapter,
+				enum hal_fifo_sel sel);
+	enum halmac_ret_status
+	(*halmac_dump_fifo)(struct halmac_adapter *adapter,
+			    enum hal_fifo_sel sel, u32 start_addr, u32 size,
+			    u8 *data);
+	enum halmac_ret_status
+	(*halmac_cfg_txbf)(struct halmac_adapter *adapter, u8 userid,
+			   enum halmac_bw bw, u8 txbf_en);
+	enum halmac_ret_status
+	(*halmac_cfg_mumimo)(struct halmac_adapter *adapter,
+			     struct halmac_cfg_mumimo_para *param);
+	enum halmac_ret_status
+	(*halmac_cfg_sounding)(struct halmac_adapter *adapter,
+			       enum halmac_snd_role role,
+			       enum halmac_data_rate rate);
+	enum halmac_ret_status
+	(*halmac_del_sounding)(struct halmac_adapter *adapter,
+			       enum halmac_snd_role role);
+	enum halmac_ret_status
+	(*halmac_su_bfer_entry_init)(struct halmac_adapter *adapter,
+				     struct halmac_su_bfer_init_para *param);
+	enum halmac_ret_status
+	(*halmac_su_bfee_entry_init)(struct halmac_adapter *adapter, u8 userid,
+				     u16 paid);
+	enum halmac_ret_status
+	(*halmac_mu_bfer_entry_init)(struct halmac_adapter *adapter,
+				     struct halmac_mu_bfer_init_para *param);
+	enum halmac_ret_status
+	(*halmac_mu_bfee_entry_init)(struct halmac_adapter *adapter,
+				     struct halmac_mu_bfee_init_para *param);
+	enum halmac_ret_status
+	(*halmac_su_bfer_entry_del)(struct halmac_adapter *adapter, u8 userid);
+	enum halmac_ret_status
+	(*halmac_su_bfee_entry_del)(struct halmac_adapter *adapter, u8 userid);
+	enum halmac_ret_status
+	(*halmac_mu_bfer_entry_del)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_mu_bfee_entry_del)(struct halmac_adapter *adapter, u8 userid);
+	enum halmac_ret_status
+	(*halmac_add_ch_info)(struct halmac_adapter *adapter,
+			      struct halmac_ch_info *info);
+	enum halmac_ret_status
+	(*halmac_add_extra_ch_info)(struct halmac_adapter *adapter,
+				    struct halmac_ch_extra_info *info);
+	enum halmac_ret_status
+	(*halmac_ctrl_ch_switch)(struct halmac_adapter *adapter,
+				 struct halmac_ch_switch_option *opt);
+	enum halmac_ret_status
+	(*halmac_p2pps)(struct halmac_adapter *adapter,
+			struct halmac_p2pps *info);
+	enum halmac_ret_status
+	(*halmac_clear_ch_info)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_send_general_info)(struct halmac_adapter *adapter,
+				    struct halmac_general_info *info);
+	enum halmac_ret_status
+	(*halmac_start_iqk)(struct halmac_adapter *adapter,
+			    struct halmac_iqk_para *param);
+	enum halmac_ret_status
+	(*halmac_ctrl_pwr_tracking)(struct halmac_adapter *adapter,
+				    struct halmac_pwr_tracking_option *opt);
+	enum halmac_ret_status
+	(*halmac_psd)(struct halmac_adapter *adapter, u16 start_psd,
+		      u16 end_psd);
+	enum halmac_ret_status
+	(*halmac_cfg_tx_agg_align)(struct halmac_adapter *adapter, u8 enable,
+				   u16 align_size);
+	enum halmac_ret_status
+	(*halmac_query_status)(struct halmac_adapter *adapter,
+			       enum halmac_feature_id feature_id,
+			       enum halmac_cmd_process_status *proc_status,
+			       u8 *data, u32 *size);
+	enum halmac_ret_status
+	(*halmac_reset_feature)(struct halmac_adapter *adapter,
+				enum halmac_feature_id feature_id);
+	enum halmac_ret_status
+	(*halmac_check_fw_status)(struct halmac_adapter *adapter,
+				  u8 *fw_status);
+	enum halmac_ret_status
+	(*halmac_dump_fw_dmem)(struct halmac_adapter *adapter, u8 *dmem,
+			       u32 *size);
+	enum halmac_ret_status
+	(*halmac_cfg_max_dl_size)(struct halmac_adapter *adapter, u32 size);
+	enum halmac_ret_status
+	(*halmac_cfg_la_mode)(struct halmac_adapter *adapter,
+			      enum halmac_la_mode mode);
+	enum halmac_ret_status
+	(*halmac_cfg_rxff_expand_mode)(struct halmac_adapter *adapter,
+				       enum halmac_rx_fifo_expanding_mode mode);
+	enum halmac_ret_status
+	(*halmac_config_security)(struct halmac_adapter *adapter,
+				  struct halmac_security_setting *setting);
+	u8
+	(*halmac_get_used_cam_entry_num)(struct halmac_adapter *adapter,
+					 enum hal_security_type sec_type);
+	enum halmac_ret_status
+	(*halmac_write_cam)(struct halmac_adapter *adapter, u32 idx,
+			    struct halmac_cam_entry_info *info);
+	enum halmac_ret_status
+	(*halmac_read_cam_entry)(struct halmac_adapter *adapter, u32 idx,
+				 struct halmac_cam_entry_format *content);
+	enum halmac_ret_status
+	(*halmac_clear_cam_entry)(struct halmac_adapter *adapter, u32 idx);
+	enum halmac_ret_status
+	(*halmac_get_hw_value)(struct halmac_adapter *adapter,
+			       enum halmac_hw_id hw_id, void *value);
+	enum halmac_ret_status
+	(*halmac_set_hw_value)(struct halmac_adapter *adapter,
+			       enum halmac_hw_id hw_id, void *value);
+	enum halmac_ret_status
+	(*halmac_cfg_drv_rsvd_pg_num)(struct halmac_adapter *adapter,
+				      enum halmac_drv_rsvd_pg_num pg_num);
+	enum halmac_ret_status
+	(*halmac_get_chip_version)(struct halmac_adapter *adapter,
+				   struct halmac_ver *ver);
+	enum halmac_ret_status
+	(*halmac_chk_txdesc)(struct halmac_adapter *adapter, u8 *buf, u32 size);
+	enum halmac_ret_status
+	(*halmac_dl_drv_rsvd_page)(struct halmac_adapter *adapter, u8 pg_offset,
+				   u8 *buf, u32 size);
+	enum halmac_ret_status
+	(*halmac_pcie_switch)(struct halmac_adapter *adapter,
+			      enum halmac_pcie_cfg cfg);
+	enum halmac_ret_status
+	(*halmac_phy_cfg)(struct halmac_adapter *adapter,
+			  enum halmac_intf_phy_platform pltfm);
+	enum halmac_ret_status
+	(*halmac_cfg_csi_rate)(struct halmac_adapter *adapter, u8 rssi,
+			       u8 cur_rate, u8 fixrate_en, u8 *new_rate);
+	enum halmac_ret_status
+	(*halmac_sdio_cmd53_4byte)(struct halmac_adapter *adapter,
+				   enum halmac_sdio_cmd53_4byte_mode mode);
+	enum halmac_ret_status
+	(*halmac_sdio_hw_info)(struct halmac_adapter *adapter,
+			       struct halmac_sdio_hw_info *info);
+	enum halmac_ret_status
+	(*halmac_cfg_transmitter_addr)(struct halmac_adapter *adapter, u8 port,
+				       union halmac_wlan_addr *addr);
+	enum halmac_ret_status
+	(*halmac_cfg_net_type)(struct halmac_adapter *adapter, u8 port,
+			       enum halmac_network_type_select net_type);
+	enum halmac_ret_status
+	(*halmac_cfg_tsf_rst)(struct halmac_adapter *adapter, u8 port);
+	enum halmac_ret_status
+	(*halmac_cfg_bcn_space)(struct halmac_adapter *adapter, u8 port,
+				u32 bcn_space);
+	enum halmac_ret_status
+	(*halmac_rw_bcn_ctrl)(struct halmac_adapter *adapter, u8 port,
+			      u8 write_en, struct halmac_bcn_ctrl *ctrl);
+	enum halmac_ret_status
+	(*halmac_interface_integration_tuning)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_txfifo_is_empty)(struct halmac_adapter *adapter, u32 chk_num);
+	enum halmac_ret_status
+	(*halmac_download_flash)(struct halmac_adapter *adapter, u8 *fw_bin,
+				 u32 size, u32 rom_addr);
+	enum halmac_ret_status
+	(*halmac_read_flash)(struct halmac_adapter *adapter, u32 addr,
+			     u32 length);
+	enum halmac_ret_status
+	(*halmac_erase_flash)(struct halmac_adapter *adapter, u8 erase_cmd,
+			      u32 addr);
+	enum halmac_ret_status
+	(*halmac_check_flash)(struct halmac_adapter *adapter, u8 *fw_bin,
+			      u32 size, u32 addr);
+	enum halmac_ret_status
+	(*halmac_cfg_edca_para)(struct halmac_adapter *adapter,
+				enum halmac_acq_id acq_id,
+				struct halmac_edca_para *param);
+	enum halmac_ret_status
+	(*halmac_pinmux_get_func)(struct halmac_adapter *adapter,
+				  enum halmac_gpio_func gpio_func, u8 *enable);
+	enum halmac_ret_status
+	(*halmac_pinmux_set_func)(struct halmac_adapter *adapter,
+				  enum halmac_gpio_func gpio_func);
+	enum halmac_ret_status
+	(*halmac_pinmux_free_func)(struct halmac_adapter *adapter,
+				   enum halmac_gpio_func gpio_func);
+	enum halmac_ret_status
+	(*halmac_pinmux_wl_led_mode)(struct halmac_adapter *adapter,
+				     enum halmac_wlled_mode mode);
+	void
+	(*halmac_pinmux_wl_led_sw_ctrl)(struct halmac_adapter *adapter, u8 on);
+	void
+	(*halmac_pinmux_sdio_int_polarity)(struct halmac_adapter *adapter,
+					   u8 low_active);
+	enum halmac_ret_status
+	(*halmac_pinmux_gpio_mode)(struct halmac_adapter *adapter, u8 gpio_id,
+				   u8 output);
+	enum halmac_ret_status
+	(*halmac_pinmux_gpio_output)(struct halmac_adapter *adapter, u8 gpio_id,
+				     u8 high);
+	enum halmac_ret_status
+	(*halmac_pinmux_pin_status)(struct halmac_adapter *adapter, u8 pin_id,
+				    u8 *high);
+	enum halmac_ret_status
+	(*halmac_ofld_func_cfg)(struct halmac_adapter *adapter,
+				struct halmac_ofld_func_info *info);
+	enum halmac_ret_status
+	(*halmac_rx_cut_amsdu_cfg)(struct halmac_adapter *adapter,
+				   struct halmac_cut_amsdu_cfg *cfg);
+	enum halmac_ret_status
+	(*halmac_fw_snding)(struct halmac_adapter *adapter,
+			    struct halmac_su_snding_info *su_info,
+			    struct halmac_mu_snding_info *mu_info, u8 period);
+	enum halmac_ret_status
+	(*halmac_get_mac_addr)(struct halmac_adapter *adapter, u8 port,
+			       union halmac_wlan_addr *addr);
+	enum halmac_ret_status
+	(*halmac_init_low_pwr)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_enter_cpu_sleep_mode)(struct halmac_adapter *adapter);
+	enum halmac_ret_status
+	(*halmac_get_cpu_mode)(struct halmac_adapter *adapter,
+			       enum halmac_wlcpu_mode *mode);
+	enum halmac_ret_status
+	(*halmac_drv_fwctrl)(struct halmac_adapter *adapter, u8 *payload,
+			     u32 size, u8 ack);
+	enum halmac_ret_status
+	(*halmac_read_efuse)(struct halmac_adapter *adapter, u32 offset,
+			     u8 *value);
+	enum halmac_ret_status
+	(*halmac_write_efuse)(struct halmac_adapter *adapter, u32 offset,
+			      u8 value);
+	void
+	(*halmac_en_ref_autok_pcie)(struct halmac_adapter *adapter, u8 en);
+};
+
+#define HALMAC_GET_API(halmac_adapter)                                         \
+	((struct halmac_api *)halmac_adapter->halmac_api)
+
+static inline enum halmac_ret_status
+halmac_fw_validate(struct halmac_adapter *adapter)
+{
+	if (adapter->halmac_state.dlfw_state != HALMAC_DLFW_DONE &&
+	    adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT)
+		return HALMAC_RET_NO_DLFW;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+#endif
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 05/17] rtlwifi: halmac: describe number and size of chip functions
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (3 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 04/17] rtlwifi: halmac: add main definition used by halmac pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 07/17] rtlwifi: halmac: add definition of TX/RX descriptor pkshih
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

The number and size of chip fucntions are different, such as TX/RX FIFO
size, efuse size, etc. So they are defined in an individual file.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../halmac_88xx/halmac_8822b/halmac_8822b_cfg.h    | 68 ++++++++++++++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h   | 40 +++++++++++++
 2 files changed, 108 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h
new file mode 100644
index 000000000000..f6ed7b44549c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_8822b_cfg.h
@@ -0,0 +1,68 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_8822B_CFG_H_
+#define _HALMAC_8822B_CFG_H_
+
+#include "../halmac_88xx_cfg.h"
+
+#define TX_FIFO_SIZE_8822B	262144
+#define RX_FIFO_SIZE_8822B	24576
+#define TRX_SHARE_SIZE_8822B	65536
+
+#define RX_DESC_DUMMY_SIZE_8822B	72 /* 8 * 9 Bytes */
+#define RX_FIFO_EXPANDING_MODE_PKT_SIZE_MAX_8822B	80 /* 8 Byte alignment*/
+
+/* should be 8 Byte alignment*/
+#if (HALMAC_RX_FIFO_EXPANDING_MODE_PKT_SIZE <= \
+	RX_FIFO_EXPANDING_MODE_PKT_SIZE_MAX_8822B)
+#define RX_FIFO_EXPANDING_UNIT_8822B	(RX_DESC_SIZE_88XX + \
+	RX_DESC_DUMMY_SIZE_8822B + HALMAC_RX_FIFO_EXPANDING_MODE_PKT_SIZE)
+#else
+#define RX_FIFO_EXPANDING_UNIT_8822B (RX_DESC_SIZE_88XX + \
+	RX_DESC_DUMMY_SIZE_8822B + RX_FIFO_EXPANDING_MODE_PKT_SIZE_MAX_8822B)
+#endif
+
+#define TX_FIFO_SIZE_LA_8822B	(TX_FIFO_SIZE_8822B >>  1)
+#define TX_FIFO_SIZE_RX_EXPAND_1BLK_8822B	\
+		(TX_FIFO_SIZE_8822B - TRX_SHARE_SIZE_8822B)
+#define RX_FIFO_SIZE_RX_EXPAND_1BLK_8822B	\
+		((((RX_FIFO_EXPANDING_UNIT_8822B << 8) - 1) >> 10) << 10)
+#define TX_FIFO_SIZE_RX_EXPAND_2BLK_8822B	\
+		(TX_FIFO_SIZE_8822B - (2 * TRX_SHARE_SIZE_8822B))
+#define RX_FIFO_SIZE_RX_EXPAND_2BLK_8822B	\
+		(RX_FIFO_SIZE_8822B +  (2 * TRX_SHARE_SIZE_8822B))
+#define TX_FIFO_SIZE_RX_EXPAND_3BLK_8822B	\
+		(TX_FIFO_SIZE_8822B - (3 * TRX_SHARE_SIZE_8822B))
+#define RX_FIFO_SIZE_RX_EXPAND_3BLK_8822B	\
+		(RX_FIFO_SIZE_8822B +  (3 * TRX_SHARE_SIZE_8822B))
+
+#define EFUSE_SIZE_8822B		1024
+#define EEPROM_SIZE_8822B		768
+#define BT_EFUSE_SIZE_8822B		128
+
+#define SEC_CAM_NUM_8822B		64
+
+#define OQT_ENTRY_AC_8822B		32
+#define OQT_ENTRY_NOAC_8822B		32
+#define MACID_MAX_8822B			128
+
+#define WLAN_FW_IRAM_MAX_SIZE_8822B	196608
+#define WLAN_FW_DRAM_MAX_SIZE_8822B	49152
+#define WLAN_FW_ERAM_MAX_SIZE_8822B	0
+#define WLAN_FW_MAX_SIZE_8822B		(WLAN_FW_IRAM_MAX_SIZE_8822B + \
+	WLAN_FW_DRAM_MAX_SIZE_8822B + WLAN_FW_ERAM_MAX_SIZE_8822B)
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h
new file mode 100644
index 000000000000..22514ef4680d
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_88xx_cfg.h
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_88XX_CFG_H_
+#define _HALMAC_88XX_CFG_H_
+
+#include "../halmac_api.h"
+
+#define TX_PAGE_SIZE_88XX		128
+#define TX_PAGE_SIZE_SHIFT_88XX		7 /* 128 = 2^7 */
+#define TX_ALIGN_SIZE_88XX		8
+#define SDIO_TX_MAX_SIZE_88XX		31744
+#define RX_BUF_FW_88XX			12288
+
+#define TX_DESC_SIZE_88XX		48
+#define RX_DESC_SIZE_88XX		24
+
+#define H2C_PKT_SIZE_88XX		32 /* Only support 32 byte packet now */
+#define H2C_PKT_HDR_SIZE_88XX		8
+#define C2H_DATA_OFFSET_88XX		10
+#define C2H_PKT_BUF_88XX		256
+
+/* HW memory address */
+#define OCPBASE_TXBUF_88XX		0x18780000
+#define OCPBASE_DMEM_88XX		0x00200000
+#define OCPBASE_EMEM_88XX		0x00100000
+
+#endif
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 07/17] rtlwifi: halmac: add definition of TX/RX descriptor
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (4 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 05/17] rtlwifi: halmac: describe number and size of chip functions pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 08/17] rtlwifi: halmac: add GPIO pin/pinmux definitions pkshih
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

TX/RX descriptor are the headers to describe the packet content.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../realtek/rtlwifi/halmac/halmac_rx_bd_nic.h      |  36 ++
 .../realtek/rtlwifi/halmac/halmac_rx_desc_chip.h   | 100 +++++
 .../realtek/rtlwifi/halmac/halmac_rx_desc_nic.h    | 123 ++++++
 .../realtek/rtlwifi/halmac/halmac_tx_bd_nic.h      | 106 +++++
 .../realtek/rtlwifi/halmac/halmac_tx_desc_chip.h   | 398 +++++++++++++++++++
 .../realtek/rtlwifi/halmac/halmac_tx_desc_nic.h    | 439 +++++++++++++++++++++
 6 files changed, 1202 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_bd_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_chip.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_bd_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_chip.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_nic.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_bd_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_bd_nic.h
new file mode 100644
index 000000000000..c03d4d0e4e8a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_bd_nic.h
@@ -0,0 +1,36 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_RX_BD_NIC_H_
+#define _HALMAC_RX_BD_NIC_H_
+
+/*TXBD_DW0*/
+
+#define GET_RX_BD_RXFAIL(rxbd) LE_BITS_TO_4BYTE(rxbd + 0x00, 31, 1)
+#define GET_RX_BD_TOTALRXPKTSIZE(rxbd) LE_BITS_TO_4BYTE(rxbd + 0x00, 16, 13)
+#define GET_RX_BD_RXTAG(rxbd) LE_BITS_TO_4BYTE(rxbd + 0x00, 16, 13)
+#define GET_RX_BD_FS(rxbd) LE_BITS_TO_4BYTE(rxbd + 0x00, 15, 1)
+#define GET_RX_BD_LS(rxbd) LE_BITS_TO_4BYTE(rxbd + 0x00, 14, 1)
+#define GET_RX_BD_RXBUFFSIZE(rxbd) LE_BITS_TO_4BYTE(rxbd + 0x00, 0, 14)
+
+/*TXBD_DW1*/
+
+#define GET_RX_BD_PHYSICAL_ADDR_LOW(rxbd) LE_BITS_TO_4BYTE(rxbd + 0x04, 0, 32)
+
+/*TXBD_DW2*/
+
+#define GET_RX_BD_PHYSICAL_ADDR_HIGH(rxbd) LE_BITS_TO_4BYTE(rxbd + 0x08, 0, 32)
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_chip.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_chip.h
new file mode 100644
index 000000000000..3134d3631281
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_chip.h
@@ -0,0 +1,100 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_RX_DESC_CHIP_H_
+#define _HALMAC_RX_DESC_CHIP_H_
+
+/*RXDESC_WORD0*/
+
+#define GET_RX_DESC_EOR_8822B(rxdesc) GET_RX_DESC_EOR(rxdesc)
+#define GET_RX_DESC_PHYPKTIDC_8822B(rxdesc) GET_RX_DESC_PHYPKTIDC(rxdesc)
+#define GET_RX_DESC_SWDEC_8822B(rxdesc) GET_RX_DESC_SWDEC(rxdesc)
+#define GET_RX_DESC_PHYST_8822B(rxdesc) GET_RX_DESC_PHYST(rxdesc)
+#define GET_RX_DESC_SHIFT_8822B(rxdesc) GET_RX_DESC_SHIFT(rxdesc)
+#define GET_RX_DESC_QOS_8822B(rxdesc) GET_RX_DESC_QOS(rxdesc)
+#define GET_RX_DESC_SECURITY_8822B(rxdesc) GET_RX_DESC_SECURITY(rxdesc)
+#define GET_RX_DESC_DRV_INFO_SIZE_8822B(rxdesc)                                \
+	GET_RX_DESC_DRV_INFO_SIZE(rxdesc)
+#define GET_RX_DESC_ICV_ERR_8822B(rxdesc) GET_RX_DESC_ICV_ERR(rxdesc)
+#define GET_RX_DESC_CRC32_8822B(rxdesc) GET_RX_DESC_CRC32(rxdesc)
+#define GET_RX_DESC_PKT_LEN_8822B(rxdesc) GET_RX_DESC_PKT_LEN(rxdesc)
+
+/*RXDESC_WORD1*/
+
+#define GET_RX_DESC_BC_8822B(rxdesc) GET_RX_DESC_BC(rxdesc)
+#define GET_RX_DESC_MC_8822B(rxdesc) GET_RX_DESC_MC(rxdesc)
+#define GET_RX_DESC_TY_PE_8822B(rxdesc) GET_RX_DESC_TY_PE(rxdesc)
+#define GET_RX_DESC_MF_8822B(rxdesc) GET_RX_DESC_MF(rxdesc)
+#define GET_RX_DESC_MD_8822B(rxdesc) GET_RX_DESC_MD(rxdesc)
+#define GET_RX_DESC_PWR_8822B(rxdesc) GET_RX_DESC_PWR(rxdesc)
+#define GET_RX_DESC_PAM_8822B(rxdesc) GET_RX_DESC_PAM(rxdesc)
+#define GET_RX_DESC_CHK_VLD_8822B(rxdesc) GET_RX_DESC_CHK_VLD(rxdesc)
+#define GET_RX_DESC_RX_IS_TCP_UDP_8822B(rxdesc)                                \
+	GET_RX_DESC_RX_IS_TCP_UDP(rxdesc)
+#define GET_RX_DESC_RX_IPV_8822B(rxdesc) GET_RX_DESC_RX_IPV(rxdesc)
+#define GET_RX_DESC_CHKERR_8822B(rxdesc) GET_RX_DESC_CHKERR(rxdesc)
+#define GET_RX_DESC_PAGGR_8822B(rxdesc) GET_RX_DESC_PAGGR(rxdesc)
+#define GET_RX_DESC_RXID_MATCH_8822B(rxdesc) GET_RX_DESC_RXID_MATCH(rxdesc)
+#define GET_RX_DESC_AMSDU_8822B(rxdesc) GET_RX_DESC_AMSDU(rxdesc)
+#define GET_RX_DESC_MACID_VLD_8822B(rxdesc) GET_RX_DESC_MACID_VLD(rxdesc)
+#define GET_RX_DESC_TID_8822B(rxdesc) GET_RX_DESC_TID(rxdesc)
+#define GET_RX_DESC_MACID_8822B(rxdesc) GET_RX_DESC_MACID(rxdesc)
+
+/*RXDESC_WORD2*/
+
+#define GET_RX_DESC_FCS_OK_8822B(rxdesc) GET_RX_DESC_FCS_OK(rxdesc)
+#define GET_RX_DESC_PPDU_CNT_8822B(rxdesc) GET_RX_DESC_PPDU_CNT(rxdesc)
+#define GET_RX_DESC_C2H_8822B(rxdesc) GET_RX_DESC_C2H(rxdesc)
+#define GET_RX_DESC_HWRSVD_8822B(rxdesc) GET_RX_DESC_HWRSVD(rxdesc)
+#define GET_RX_DESC_WLANHD_IV_LEN_8822B(rxdesc)                                \
+	GET_RX_DESC_WLANHD_IV_LEN(rxdesc)
+#define GET_RX_DESC_RX_IS_QOS_8822B(rxdesc) GET_RX_DESC_RX_IS_QOS(rxdesc)
+#define GET_RX_DESC_FRAG_8822B(rxdesc) GET_RX_DESC_FRAG(rxdesc)
+#define GET_RX_DESC_SEQ_8822B(rxdesc) GET_RX_DESC_SEQ(rxdesc)
+
+/*RXDESC_WORD3*/
+
+#define GET_RX_DESC_MAGIC_WAKE_8822B(rxdesc) GET_RX_DESC_MAGIC_WAKE(rxdesc)
+#define GET_RX_DESC_UNICAST_WAKE_8822B(rxdesc) GET_RX_DESC_UNICAST_WAKE(rxdesc)
+#define GET_RX_DESC_PATTERN_MATCH_8822B(rxdesc)                                \
+	GET_RX_DESC_PATTERN_MATCH(rxdesc)
+#define GET_RX_DESC_RXPAYLOAD_MATCH_8822B(rxdesc)                              \
+	GET_RX_DESC_RXPAYLOAD_MATCH(rxdesc)
+#define GET_RX_DESC_RXPAYLOAD_ID_8822B(rxdesc) GET_RX_DESC_RXPAYLOAD_ID(rxdesc)
+#define GET_RX_DESC_DMA_AGG_NUM_8822B(rxdesc) GET_RX_DESC_DMA_AGG_NUM(rxdesc)
+#define GET_RX_DESC_BSSID_FIT_1_0_8822B(rxdesc)                                \
+	GET_RX_DESC_BSSID_FIT_1_0(rxdesc)
+#define GET_RX_DESC_EOSP_8822B(rxdesc) GET_RX_DESC_EOSP(rxdesc)
+#define GET_RX_DESC_HTC_8822B(rxdesc) GET_RX_DESC_HTC(rxdesc)
+#define GET_RX_DESC_BSSID_FIT_4_2_8822B(rxdesc)                                \
+	GET_RX_DESC_BSSID_FIT_4_2(rxdesc)
+#define GET_RX_DESC_RX_RATE_8822B(rxdesc) GET_RX_DESC_RX_RATE(rxdesc)
+
+/*RXDESC_WORD4*/
+
+#define GET_RX_DESC_A1_FIT_8822B(rxdesc) GET_RX_DESC_A1_FIT(rxdesc)
+#define GET_RX_DESC_MACID_RPT_BUFF_8822B(rxdesc)                               \
+	GET_RX_DESC_MACID_RPT_BUFF(rxdesc)
+#define GET_RX_DESC_RX_PRE_NDP_VLD_8822B(rxdesc)                               \
+	GET_RX_DESC_RX_PRE_NDP_VLD(rxdesc)
+#define GET_RX_DESC_RX_SCRAMBLER_8822B(rxdesc) GET_RX_DESC_RX_SCRAMBLER(rxdesc)
+#define GET_RX_DESC_RX_EOF_8822B(rxdesc) GET_RX_DESC_RX_EOF(rxdesc)
+#define GET_RX_DESC_PATTERN_IDX_8822B(rxdesc) GET_RX_DESC_PATTERN_IDX(rxdesc)
+
+/*RXDESC_WORD5*/
+
+#define GET_RX_DESC_TSFL_8822B(rxdesc) GET_RX_DESC_TSFL(rxdesc)
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_nic.h
new file mode 100644
index 000000000000..245d6d1b60be
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_rx_desc_nic.h
@@ -0,0 +1,123 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_RX_DESC_NIC_H_
+#define _HALMAC_RX_DESC_NIC_H_
+
+/*RXDESC_WORD0*/
+
+#define GET_RX_DESC_EOR(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 30, 1)
+#define GET_RX_DESC_PHYPKTIDC(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 28, 1)
+
+#define GET_RX_DESC_SWDEC(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 27, 1)
+#define GET_RX_DESC_PHYST(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 26, 1)
+#define GET_RX_DESC_SHIFT(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 24, 2)
+#define GET_RX_DESC_QOS(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 23, 1)
+#define GET_RX_DESC_SECURITY(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 20, 3)
+#define GET_RX_DESC_DRV_INFO_SIZE(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 16, 4)
+#define GET_RX_DESC_ICV_ERR(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 15, 1)
+#define GET_RX_DESC_CRC32(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 14, 1)
+#define GET_RX_DESC_PKT_LEN(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x00, 0, 14)
+
+/*RXDESC_WORD1*/
+
+#define GET_RX_DESC_BC(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 31, 1)
+#define GET_RX_DESC_MC(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 30, 1)
+
+#define GET_RX_DESC_TY_PE(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 28, 2)
+
+#define GET_RX_DESC_MF(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 27, 1)
+#define GET_RX_DESC_MD(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 26, 1)
+#define GET_RX_DESC_PWR(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 25, 1)
+
+#define GET_RX_DESC_PAM(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 24, 1)
+
+#define GET_RX_DESC_CHK_VLD(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 23, 1)
+
+#define GET_RX_DESC_RX_IS_TCP_UDP(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 22, 1)
+#define GET_RX_DESC_RX_IPV(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 21, 1)
+
+#define GET_RX_DESC_CHKERR(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 20, 1)
+
+#define GET_RX_DESC_PAGGR(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 15, 1)
+
+#define GET_RX_DESC_RXID_MATCH(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 14, 1)
+
+#define GET_RX_DESC_AMSDU(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 13, 1)
+
+#define GET_RX_DESC_MACID_VLD(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 12, 1)
+
+#define GET_RX_DESC_TID(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 8, 4)
+
+#define GET_RX_DESC_MACID(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x04, 0, 7)
+
+/*RXDESC_WORD2*/
+
+#define GET_RX_DESC_FCS_OK(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x08, 31, 1)
+
+#define GET_RX_DESC_PPDU_CNT(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x08, 29, 2)
+
+#define GET_RX_DESC_C2H(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x08, 28, 1)
+
+#define GET_RX_DESC_HWRSVD(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x08, 24, 4)
+
+#define GET_RX_DESC_WLANHD_IV_LEN(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x08, 18, 6)
+
+#define GET_RX_DESC_RX_IS_QOS(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x08, 16, 1)
+
+#define GET_RX_DESC_FRAG(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x08, 12, 4)
+#define GET_RX_DESC_SEQ(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x08, 0, 12)
+
+/*RXDESC_WORD3*/
+
+#define GET_RX_DESC_MAGIC_WAKE(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 31, 1)
+#define GET_RX_DESC_UNICAST_WAKE(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 30, 1)
+
+#define GET_RX_DESC_PATTERN_MATCH(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 29, 1)
+
+#define GET_RX_DESC_RXPAYLOAD_MATCH(rxdesc)                                    \
+	LE_BITS_TO_4BYTE(rxdesc + 0x0C, 28, 1)
+#define GET_RX_DESC_RXPAYLOAD_ID(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 24, 4)
+
+#define GET_RX_DESC_DMA_AGG_NUM(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 16, 8)
+
+#define GET_RX_DESC_BSSID_FIT_1_0(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 12, 2)
+#define GET_RX_DESC_EOSP(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 11, 1)
+
+#define GET_RX_DESC_HTC(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 10, 1)
+
+#define GET_RX_DESC_BSSID_FIT_4_2(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 7, 3)
+
+#define GET_RX_DESC_RX_RATE(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x0C, 0, 7)
+
+/*RXDESC_WORD4*/
+
+#define GET_RX_DESC_A1_FIT(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x10, 24, 5)
+
+#define GET_RX_DESC_MACID_RPT_BUFF(rxdesc)                                     \
+	LE_BITS_TO_4BYTE(rxdesc + 0x10, 17, 7)
+#define GET_RX_DESC_RX_PRE_NDP_VLD(rxdesc)                                     \
+	LE_BITS_TO_4BYTE(rxdesc + 0x10, 16, 1)
+
+#define GET_RX_DESC_RX_SCRAMBLER(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x10, 9, 7)
+#define GET_RX_DESC_RX_EOF(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x10, 8, 1)
+
+#define GET_RX_DESC_PATTERN_IDX(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x10, 0, 8)
+
+/*RXDESC_WORD5*/
+
+#define GET_RX_DESC_TSFL(rxdesc) LE_BITS_TO_4BYTE(rxdesc + 0x14, 0, 32)
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_bd_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_bd_nic.h
new file mode 100644
index 000000000000..3260fcfcc04f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_bd_nic.h
@@ -0,0 +1,106 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_TX_BD_NIC_H_
+#define _HALMAC_TX_BD_NIC_H_
+
+/*TXBD_DW0*/
+
+#define SET_TX_BD_OWN(txbd, value)                                             \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x00, 31, 1, value)
+#define GET_TX_BD_OWN(txbd) LE_BITS_TO_4BYTE(txbd + 0x00, 31, 1)
+#define SET_TX_BD_PSB(txbd, value)                                             \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x00, 16, 8, value)
+#define GET_TX_BD_PSB(txbd) LE_BITS_TO_4BYTE(txbd + 0x00, 16, 8)
+#define SET_TX_BD_TX_BUFF_SIZE0(txbd, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x00, 0, 16, value)
+#define GET_TX_BD_TX_BUFF_SIZE0(txbd) LE_BITS_TO_4BYTE(txbd + 0x00, 0, 16)
+
+/*TXBD_DW1*/
+
+#define SET_TX_BD_PHYSICAL_ADDR0_LOW(txbd, value)                              \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x04, 0, 32, value)
+#define GET_TX_BD_PHYSICAL_ADDR0_LOW(txbd) LE_BITS_TO_4BYTE(txbd + 0x04, 0, 32)
+
+/*TXBD_DW2*/
+
+#define SET_TX_BD_PHYSICAL_ADDR0_HIGH(txbd, value)                             \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x08, 0, 32, value)
+#define GET_TX_BD_PHYSICAL_ADDR0_HIGH(txbd) LE_BITS_TO_4BYTE(txbd + 0x08, 0, 32)
+
+/*TXBD_DW4*/
+
+#define SET_TX_BD_A1(txbd, value)                                              \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x10, 31, 1, value)
+#define GET_TX_BD_A1(txbd) LE_BITS_TO_4BYTE(txbd + 0x10, 31, 1)
+#define SET_TX_BD_TX_BUFF_SIZE1(txbd, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x10, 0, 16, value)
+#define GET_TX_BD_TX_BUFF_SIZE1(txbd) LE_BITS_TO_4BYTE(txbd + 0x10, 0, 16)
+
+/*TXBD_DW5*/
+
+#define SET_TX_BD_PHYSICAL_ADDR1_LOW(txbd, value)                              \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x14, 0, 32, value)
+#define GET_TX_BD_PHYSICAL_ADDR1_LOW(txbd) LE_BITS_TO_4BYTE(txbd + 0x14, 0, 32)
+
+/*TXBD_DW6*/
+
+#define SET_TX_BD_PHYSICAL_ADDR1_HIGH(txbd, value)                             \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x18, 0, 32, value)
+#define GET_TX_BD_PHYSICAL_ADDR1_HIGH(txbd) LE_BITS_TO_4BYTE(txbd + 0x18, 0, 32)
+
+/*TXBD_DW8*/
+
+#define SET_TX_BD_A2(txbd, value)                                              \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x20, 31, 1, value)
+#define GET_TX_BD_A2(txbd) LE_BITS_TO_4BYTE(txbd + 0x20, 31, 1)
+#define SET_TX_BD_TX_BUFF_SIZE2(txbd, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x20, 0, 16, value)
+#define GET_TX_BD_TX_BUFF_SIZE2(txbd) LE_BITS_TO_4BYTE(txbd + 0x20, 0, 16)
+
+/*TXBD_DW9*/
+
+#define SET_TX_BD_PHYSICAL_ADDR2_LOW(txbd, value)                              \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x24, 0, 32, value)
+#define GET_TX_BD_PHYSICAL_ADDR2_LOW(txbd) LE_BITS_TO_4BYTE(txbd + 0x24, 0, 32)
+
+/*TXBD_DW10*/
+
+#define SET_TX_BD_PHYSICAL_ADDR2_HIGH(txbd, value)                             \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x28, 0, 32, value)
+#define GET_TX_BD_PHYSICAL_ADDR2_HIGH(txbd) LE_BITS_TO_4BYTE(txbd + 0x28, 0, 32)
+
+/*TXBD_DW12*/
+
+#define SET_TX_BD_A3(txbd, value)                                              \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x30, 31, 1, value)
+#define GET_TX_BD_A3(txbd) LE_BITS_TO_4BYTE(txbd + 0x30, 31, 1)
+#define SET_TX_BD_TX_BUFF_SIZE3(txbd, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x30, 0, 16, value)
+#define GET_TX_BD_TX_BUFF_SIZE3(txbd) LE_BITS_TO_4BYTE(txbd + 0x30, 0, 16)
+
+/*TXBD_DW13*/
+
+#define SET_TX_BD_PHYSICAL_ADDR3_LOW(txbd, value)                              \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x34, 0, 32, value)
+#define GET_TX_BD_PHYSICAL_ADDR3_LOW(txbd) LE_BITS_TO_4BYTE(txbd + 0x34, 0, 32)
+
+/*TXBD_DW14*/
+
+#define SET_TX_BD_PHYSICAL_ADDR3_HIGH(txbd, value)                             \
+	SET_BITS_TO_LE_4BYTE(txbd + 0x38, 0, 32, value)
+#define GET_TX_BD_PHYSICAL_ADDR3_HIGH(txbd) LE_BITS_TO_4BYTE(txbd + 0x38, 0, 32)
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_chip.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_chip.h
new file mode 100644
index 000000000000..2df9202b7963
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_chip.h
@@ -0,0 +1,398 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_TX_DESC_CHIP_H_
+#define _HALMAC_TX_DESC_CHIP_H_
+
+/*TXDESC_WORD0*/
+
+#define SET_TX_DESC_DISQSELSEQ_8822B(txdesc, value)                            \
+	SET_TX_DESC_DISQSELSEQ(txdesc, value)
+#define GET_TX_DESC_DISQSELSEQ_8822B(txdesc) GET_TX_DESC_DISQSELSEQ(txdesc)
+#define SET_TX_DESC_GF_8822B(txdesc, value) SET_TX_DESC_GF(txdesc, value)
+#define GET_TX_DESC_GF_8822B(txdesc) GET_TX_DESC_GF(txdesc)
+#define SET_TX_DESC_NO_ACM_8822B(txdesc, value)                                \
+	SET_TX_DESC_NO_ACM(txdesc, value)
+#define GET_TX_DESC_NO_ACM_8822B(txdesc) GET_TX_DESC_NO_ACM(txdesc)
+#define SET_TX_DESC_BCNPKT_TSF_CTRL_8822B(txdesc, value)                       \
+	SET_TX_DESC_BCNPKT_TSF_CTRL(txdesc, value)
+#define GET_TX_DESC_BCNPKT_TSF_CTRL_8822B(txdesc)                              \
+	GET_TX_DESC_BCNPKT_TSF_CTRL(txdesc)
+#define SET_TX_DESC_AMSDU_PAD_EN_8822B(txdesc, value)                          \
+	SET_TX_DESC_AMSDU_PAD_EN(txdesc, value)
+#define GET_TX_DESC_AMSDU_PAD_EN_8822B(txdesc) GET_TX_DESC_AMSDU_PAD_EN(txdesc)
+#define SET_TX_DESC_LS_8822B(txdesc, value) SET_TX_DESC_LS(txdesc, value)
+#define GET_TX_DESC_LS_8822B(txdesc) GET_TX_DESC_LS(txdesc)
+#define SET_TX_DESC_HTC_8822B(txdesc, value) SET_TX_DESC_HTC(txdesc, value)
+#define GET_TX_DESC_HTC_8822B(txdesc) GET_TX_DESC_HTC(txdesc)
+#define SET_TX_DESC_BMC_8822B(txdesc, value) SET_TX_DESC_BMC(txdesc, value)
+#define GET_TX_DESC_BMC_8822B(txdesc) GET_TX_DESC_BMC(txdesc)
+#define SET_TX_DESC_OFFSET_8822B(txdesc, value)                                \
+	SET_TX_DESC_OFFSET(txdesc, value)
+#define GET_TX_DESC_OFFSET_8822B(txdesc) GET_TX_DESC_OFFSET(txdesc)
+#define SET_TX_DESC_TXPKTSIZE_8822B(txdesc, value)                             \
+	SET_TX_DESC_TXPKTSIZE(txdesc, value)
+#define GET_TX_DESC_TXPKTSIZE_8822B(txdesc) GET_TX_DESC_TXPKTSIZE(txdesc)
+
+/*WORD1*/
+
+#define SET_TX_DESC_MOREDATA_8822B(txdesc, value)                              \
+	SET_TX_DESC_MOREDATA(txdesc, value)
+#define GET_TX_DESC_MOREDATA_8822B(txdesc) GET_TX_DESC_MOREDATA(txdesc)
+#define SET_TX_DESC_PKT_OFFSET_8822B(txdesc, value)                            \
+	SET_TX_DESC_PKT_OFFSET(txdesc, value)
+#define GET_TX_DESC_PKT_OFFSET_8822B(txdesc) GET_TX_DESC_PKT_OFFSET(txdesc)
+#define SET_TX_DESC_SEC_TYPE_8822B(txdesc, value)                              \
+	SET_TX_DESC_SEC_TYPE(txdesc, value)
+#define GET_TX_DESC_SEC_TYPE_8822B(txdesc) GET_TX_DESC_SEC_TYPE(txdesc)
+#define SET_TX_DESC_EN_DESC_ID_8822B(txdesc, value)                            \
+	SET_TX_DESC_EN_DESC_ID(txdesc, value)
+#define GET_TX_DESC_EN_DESC_ID_8822B(txdesc) GET_TX_DESC_EN_DESC_ID(txdesc)
+#define SET_TX_DESC_RATE_ID_8822B(txdesc, value)                               \
+	SET_TX_DESC_RATE_ID(txdesc, value)
+#define GET_TX_DESC_RATE_ID_8822B(txdesc) GET_TX_DESC_RATE_ID(txdesc)
+#define SET_TX_DESC_PIFS_8822B(txdesc, value) SET_TX_DESC_PIFS(txdesc, value)
+#define GET_TX_DESC_PIFS_8822B(txdesc) GET_TX_DESC_PIFS(txdesc)
+#define SET_TX_DESC_LSIG_TXOP_EN_8822B(txdesc, value)                          \
+	SET_TX_DESC_LSIG_TXOP_EN(txdesc, value)
+#define GET_TX_DESC_LSIG_TXOP_EN_8822B(txdesc) GET_TX_DESC_LSIG_TXOP_EN(txdesc)
+#define SET_TX_DESC_RD_NAV_EXT_8822B(txdesc, value)                            \
+	SET_TX_DESC_RD_NAV_EXT(txdesc, value)
+#define GET_TX_DESC_RD_NAV_EXT_8822B(txdesc) GET_TX_DESC_RD_NAV_EXT(txdesc)
+#define SET_TX_DESC_QSEL_8822B(txdesc, value) SET_TX_DESC_QSEL(txdesc, value)
+#define GET_TX_DESC_QSEL_8822B(txdesc) GET_TX_DESC_QSEL(txdesc)
+#define SET_TX_DESC_MACID_8822B(txdesc, value) SET_TX_DESC_MACID(txdesc, value)
+#define GET_TX_DESC_MACID_8822B(txdesc) GET_TX_DESC_MACID(txdesc)
+
+/*TXDESC_WORD2*/
+
+#define SET_TX_DESC_HW_AES_IV_8822B(txdesc, value)                             \
+	SET_TX_DESC_HW_AES_IV(txdesc, value)
+#define GET_TX_DESC_HW_AES_IV_8822B(txdesc) GET_TX_DESC_HW_AES_IV(txdesc)
+#define SET_TX_DESC_FTM_EN_8822B(txdesc, value)                                \
+	SET_TX_DESC_FTM_EN(txdesc, value)
+#define GET_TX_DESC_FTM_EN_8822B(txdesc) GET_TX_DESC_FTM_EN(txdesc)
+#define SET_TX_DESC_G_ID_8822B(txdesc, value) SET_TX_DESC_G_ID(txdesc, value)
+#define GET_TX_DESC_G_ID_8822B(txdesc) GET_TX_DESC_G_ID(txdesc)
+#define SET_TX_DESC_BT_NULL_8822B(txdesc, value)                               \
+	SET_TX_DESC_BT_NULL(txdesc, value)
+#define GET_TX_DESC_BT_NULL_8822B(txdesc) GET_TX_DESC_BT_NULL(txdesc)
+#define SET_TX_DESC_AMPDU_DENSITY_8822B(txdesc, value)                         \
+	SET_TX_DESC_AMPDU_DENSITY(txdesc, value)
+#define GET_TX_DESC_AMPDU_DENSITY_8822B(txdesc)                                \
+	GET_TX_DESC_AMPDU_DENSITY(txdesc)
+#define SET_TX_DESC_SPE_RPT_8822B(txdesc, value)                               \
+	SET_TX_DESC_SPE_RPT(txdesc, value)
+#define GET_TX_DESC_SPE_RPT_8822B(txdesc) GET_TX_DESC_SPE_RPT(txdesc)
+#define SET_TX_DESC_RAW_8822B(txdesc, value) SET_TX_DESC_RAW(txdesc, value)
+#define GET_TX_DESC_RAW_8822B(txdesc) GET_TX_DESC_RAW(txdesc)
+#define SET_TX_DESC_MOREFRAG_8822B(txdesc, value)                              \
+	SET_TX_DESC_MOREFRAG(txdesc, value)
+#define GET_TX_DESC_MOREFRAG_8822B(txdesc) GET_TX_DESC_MOREFRAG(txdesc)
+#define SET_TX_DESC_BK_8822B(txdesc, value) SET_TX_DESC_BK(txdesc, value)
+#define GET_TX_DESC_BK_8822B(txdesc) GET_TX_DESC_BK(txdesc)
+#define SET_TX_DESC_NULL_1_8822B(txdesc, value)                                \
+	SET_TX_DESC_NULL_1(txdesc, value)
+#define GET_TX_DESC_NULL_1_8822B(txdesc) GET_TX_DESC_NULL_1(txdesc)
+#define SET_TX_DESC_NULL_0_8822B(txdesc, value)                                \
+	SET_TX_DESC_NULL_0(txdesc, value)
+#define GET_TX_DESC_NULL_0_8822B(txdesc) GET_TX_DESC_NULL_0(txdesc)
+#define SET_TX_DESC_RDG_EN_8822B(txdesc, value)                                \
+	SET_TX_DESC_RDG_EN(txdesc, value)
+#define GET_TX_DESC_RDG_EN_8822B(txdesc) GET_TX_DESC_RDG_EN(txdesc)
+#define SET_TX_DESC_AGG_EN_8822B(txdesc, value)                                \
+	SET_TX_DESC_AGG_EN(txdesc, value)
+#define GET_TX_DESC_AGG_EN_8822B(txdesc) GET_TX_DESC_AGG_EN(txdesc)
+#define SET_TX_DESC_CCA_RTS_8822B(txdesc, value)                               \
+	SET_TX_DESC_CCA_RTS(txdesc, value)
+#define GET_TX_DESC_CCA_RTS_8822B(txdesc) GET_TX_DESC_CCA_RTS(txdesc)
+#define SET_TX_DESC_TRI_FRAME_8822B(txdesc, value)                             \
+	SET_TX_DESC_TRI_FRAME(txdesc, value)
+#define GET_TX_DESC_TRI_FRAME_8822B(txdesc) GET_TX_DESC_TRI_FRAME(txdesc)
+#define SET_TX_DESC_P_AID_8822B(txdesc, value) SET_TX_DESC_P_AID(txdesc, value)
+#define GET_TX_DESC_P_AID_8822B(txdesc) GET_TX_DESC_P_AID(txdesc)
+
+/*TXDESC_WORD3*/
+
+#define SET_TX_DESC_AMPDU_MAX_TIME_8822B(txdesc, value)                        \
+	SET_TX_DESC_AMPDU_MAX_TIME(txdesc, value)
+#define GET_TX_DESC_AMPDU_MAX_TIME_8822B(txdesc)                               \
+	GET_TX_DESC_AMPDU_MAX_TIME(txdesc)
+#define SET_TX_DESC_NDPA_8822B(txdesc, value) SET_TX_DESC_NDPA(txdesc, value)
+#define GET_TX_DESC_NDPA_8822B(txdesc) GET_TX_DESC_NDPA(txdesc)
+#define SET_TX_DESC_MAX_AGG_NUM_8822B(txdesc, value)                           \
+	SET_TX_DESC_MAX_AGG_NUM(txdesc, value)
+#define GET_TX_DESC_MAX_AGG_NUM_8822B(txdesc) GET_TX_DESC_MAX_AGG_NUM(txdesc)
+#define SET_TX_DESC_USE_MAX_TIME_EN_8822B(txdesc, value)                       \
+	SET_TX_DESC_USE_MAX_TIME_EN(txdesc, value)
+#define GET_TX_DESC_USE_MAX_TIME_EN_8822B(txdesc)                              \
+	GET_TX_DESC_USE_MAX_TIME_EN(txdesc)
+#define SET_TX_DESC_NAVUSEHDR_8822B(txdesc, value)                             \
+	SET_TX_DESC_NAVUSEHDR(txdesc, value)
+#define GET_TX_DESC_NAVUSEHDR_8822B(txdesc) GET_TX_DESC_NAVUSEHDR(txdesc)
+#define SET_TX_DESC_CHK_EN_8822B(txdesc, value)                                \
+	SET_TX_DESC_CHK_EN(txdesc, value)
+#define GET_TX_DESC_CHK_EN_8822B(txdesc) GET_TX_DESC_CHK_EN(txdesc)
+#define SET_TX_DESC_HW_RTS_EN_8822B(txdesc, value)                             \
+	SET_TX_DESC_HW_RTS_EN(txdesc, value)
+#define GET_TX_DESC_HW_RTS_EN_8822B(txdesc) GET_TX_DESC_HW_RTS_EN(txdesc)
+#define SET_TX_DESC_RTSEN_8822B(txdesc, value) SET_TX_DESC_RTSEN(txdesc, value)
+#define GET_TX_DESC_RTSEN_8822B(txdesc) GET_TX_DESC_RTSEN(txdesc)
+#define SET_TX_DESC_CTS2SELF_8822B(txdesc, value)                              \
+	SET_TX_DESC_CTS2SELF(txdesc, value)
+#define GET_TX_DESC_CTS2SELF_8822B(txdesc) GET_TX_DESC_CTS2SELF(txdesc)
+#define SET_TX_DESC_DISDATAFB_8822B(txdesc, value)                             \
+	SET_TX_DESC_DISDATAFB(txdesc, value)
+#define GET_TX_DESC_DISDATAFB_8822B(txdesc) GET_TX_DESC_DISDATAFB(txdesc)
+#define SET_TX_DESC_DISRTSFB_8822B(txdesc, value)                              \
+	SET_TX_DESC_DISRTSFB(txdesc, value)
+#define GET_TX_DESC_DISRTSFB_8822B(txdesc) GET_TX_DESC_DISRTSFB(txdesc)
+#define SET_TX_DESC_USE_RATE_8822B(txdesc, value)                              \
+	SET_TX_DESC_USE_RATE(txdesc, value)
+#define GET_TX_DESC_USE_RATE_8822B(txdesc) GET_TX_DESC_USE_RATE(txdesc)
+#define SET_TX_DESC_HW_SSN_SEL_8822B(txdesc, value)                            \
+	SET_TX_DESC_HW_SSN_SEL(txdesc, value)
+#define GET_TX_DESC_HW_SSN_SEL_8822B(txdesc) GET_TX_DESC_HW_SSN_SEL(txdesc)
+#define SET_TX_DESC_WHEADER_LEN_8822B(txdesc, value)                           \
+	SET_TX_DESC_WHEADER_LEN(txdesc, value)
+#define GET_TX_DESC_WHEADER_LEN_8822B(txdesc) GET_TX_DESC_WHEADER_LEN(txdesc)
+
+/*TXDESC_WORD4*/
+
+#define SET_TX_DESC_PCTS_MASK_IDX_8822B(txdesc, value)                         \
+	SET_TX_DESC_PCTS_MASK_IDX(txdesc, value)
+#define GET_TX_DESC_PCTS_MASK_IDX_8822B(txdesc)                                \
+	GET_TX_DESC_PCTS_MASK_IDX(txdesc)
+#define SET_TX_DESC_PCTS_EN_8822B(txdesc, value)                               \
+	SET_TX_DESC_PCTS_EN(txdesc, value)
+#define GET_TX_DESC_PCTS_EN_8822B(txdesc) GET_TX_DESC_PCTS_EN(txdesc)
+#define SET_TX_DESC_RTSRATE_8822B(txdesc, value)                               \
+	SET_TX_DESC_RTSRATE(txdesc, value)
+#define GET_TX_DESC_RTSRATE_8822B(txdesc) GET_TX_DESC_RTSRATE(txdesc)
+#define SET_TX_DESC_RTS_DATA_RTY_LMT_8822B(txdesc, value)                      \
+	SET_TX_DESC_RTS_DATA_RTY_LMT(txdesc, value)
+#define GET_TX_DESC_RTS_DATA_RTY_LMT_8822B(txdesc)                             \
+	GET_TX_DESC_RTS_DATA_RTY_LMT(txdesc)
+#define SET_TX_DESC_RTY_LMT_EN_8822B(txdesc, value)                            \
+	SET_TX_DESC_RTY_LMT_EN(txdesc, value)
+#define GET_TX_DESC_RTY_LMT_EN_8822B(txdesc) GET_TX_DESC_RTY_LMT_EN(txdesc)
+#define SET_TX_DESC_RTS_RTY_LOWEST_RATE_8822B(txdesc, value)                   \
+	SET_TX_DESC_RTS_RTY_LOWEST_RATE(txdesc, value)
+#define GET_TX_DESC_RTS_RTY_LOWEST_RATE_8822B(txdesc)                          \
+	GET_TX_DESC_RTS_RTY_LOWEST_RATE(txdesc)
+#define SET_TX_DESC_DATA_RTY_LOWEST_RATE_8822B(txdesc, value)                  \
+	SET_TX_DESC_DATA_RTY_LOWEST_RATE(txdesc, value)
+#define GET_TX_DESC_DATA_RTY_LOWEST_RATE_8822B(txdesc)                         \
+	GET_TX_DESC_DATA_RTY_LOWEST_RATE(txdesc)
+#define SET_TX_DESC_TRY_RATE_8822B(txdesc, value)                              \
+	SET_TX_DESC_TRY_RATE(txdesc, value)
+#define GET_TX_DESC_TRY_RATE_8822B(txdesc) GET_TX_DESC_TRY_RATE(txdesc)
+#define SET_TX_DESC_DATARATE_8822B(txdesc, value)                              \
+	SET_TX_DESC_DATARATE(txdesc, value)
+#define GET_TX_DESC_DATARATE_8822B(txdesc) GET_TX_DESC_DATARATE(txdesc)
+
+/*TXDESC_WORD5*/
+
+#define SET_TX_DESC_POLLUTED_8822B(txdesc, value)                              \
+	SET_TX_DESC_POLLUTED(txdesc, value)
+#define GET_TX_DESC_POLLUTED_8822B(txdesc) GET_TX_DESC_POLLUTED(txdesc)
+#define SET_TX_DESC_TXPWR_OFSET_8822B(txdesc, value)                           \
+	SET_TX_DESC_TXPWR_OFSET(txdesc, value)
+#define GET_TX_DESC_TXPWR_OFSET_8822B(txdesc) GET_TX_DESC_TXPWR_OFSET(txdesc)
+#define SET_TX_DESC_TX_ANT_8822B(txdesc, value)                                \
+	SET_TX_DESC_TX_ANT(txdesc, value)
+#define GET_TX_DESC_TX_ANT_8822B(txdesc) GET_TX_DESC_TX_ANT(txdesc)
+#define SET_TX_DESC_PORT_ID_8822B(txdesc, value)                               \
+	SET_TX_DESC_PORT_ID(txdesc, value)
+#define GET_TX_DESC_PORT_ID_8822B(txdesc) GET_TX_DESC_PORT_ID(txdesc)
+#define SET_TX_DESC_MULTIPLE_PORT_8822B(txdesc, value)                         \
+	SET_TX_DESC_MULTIPLE_PORT(txdesc, value)
+#define GET_TX_DESC_MULTIPLE_PORT_8822B(txdesc)                                \
+	GET_TX_DESC_MULTIPLE_PORT(txdesc)
+#define SET_TX_DESC_SIGNALING_TAPKT_EN_8822B(txdesc, value)                    \
+	SET_TX_DESC_SIGNALING_TAPKT_EN(txdesc, value)
+#define GET_TX_DESC_SIGNALING_TAPKT_EN_8822B(txdesc)                           \
+	GET_TX_DESC_SIGNALING_TAPKT_EN(txdesc)
+#define SET_TX_DESC_SIGNALING_TA_PKT_SC_8822B(txdesc, value)                   \
+	SET_TX_DESC_SIGNALING_TA_PKT_SC(txdesc, value)
+#define GET_TX_DESC_SIGNALING_TA_PKT_SC_8822B(txdesc)                          \
+	GET_TX_DESC_SIGNALING_TA_PKT_SC(txdesc)
+#define SET_TX_DESC_RTS_SHORT_8822B(txdesc, value)                             \
+	SET_TX_DESC_RTS_SHORT(txdesc, value)
+#define GET_TX_DESC_RTS_SHORT_8822B(txdesc) GET_TX_DESC_RTS_SHORT(txdesc)
+#define SET_TX_DESC_VCS_STBC_8822B(txdesc, value)                              \
+	SET_TX_DESC_VCS_STBC(txdesc, value)
+#define GET_TX_DESC_VCS_STBC_8822B(txdesc) GET_TX_DESC_VCS_STBC(txdesc)
+#define SET_TX_DESC_DATA_STBC_8822B(txdesc, value)                             \
+	SET_TX_DESC_DATA_STBC(txdesc, value)
+#define GET_TX_DESC_DATA_STBC_8822B(txdesc) GET_TX_DESC_DATA_STBC(txdesc)
+#define SET_TX_DESC_DATA_LDPC_8822B(txdesc, value)                             \
+	SET_TX_DESC_DATA_LDPC(txdesc, value)
+#define GET_TX_DESC_DATA_LDPC_8822B(txdesc) GET_TX_DESC_DATA_LDPC(txdesc)
+#define SET_TX_DESC_DATA_BW_8822B(txdesc, value)                               \
+	SET_TX_DESC_DATA_BW(txdesc, value)
+#define GET_TX_DESC_DATA_BW_8822B(txdesc) GET_TX_DESC_DATA_BW(txdesc)
+#define SET_TX_DESC_DATA_SHORT_8822B(txdesc, value)                            \
+	SET_TX_DESC_DATA_SHORT(txdesc, value)
+#define GET_TX_DESC_DATA_SHORT_8822B(txdesc) GET_TX_DESC_DATA_SHORT(txdesc)
+#define SET_TX_DESC_DATA_SC_8822B(txdesc, value)                               \
+	SET_TX_DESC_DATA_SC(txdesc, value)
+#define GET_TX_DESC_DATA_SC_8822B(txdesc) GET_TX_DESC_DATA_SC(txdesc)
+
+/*TXDESC_WORD6*/
+
+#define SET_TX_DESC_ANTSEL_D_8822B(txdesc, value)                              \
+	SET_TX_DESC_ANTSEL_D(txdesc, value)
+#define GET_TX_DESC_ANTSEL_D_8822B(txdesc) GET_TX_DESC_ANTSEL_D(txdesc)
+#define SET_TX_DESC_ANT_MAPD_8822B(txdesc, value)                              \
+	SET_TX_DESC_ANT_MAPD(txdesc, value)
+#define GET_TX_DESC_ANT_MAPD_8822B(txdesc) GET_TX_DESC_ANT_MAPD(txdesc)
+#define SET_TX_DESC_ANT_MAPC_8822B(txdesc, value)                              \
+	SET_TX_DESC_ANT_MAPC(txdesc, value)
+#define GET_TX_DESC_ANT_MAPC_8822B(txdesc) GET_TX_DESC_ANT_MAPC(txdesc)
+#define SET_TX_DESC_ANT_MAPB_8822B(txdesc, value)                              \
+	SET_TX_DESC_ANT_MAPB(txdesc, value)
+#define GET_TX_DESC_ANT_MAPB_8822B(txdesc) GET_TX_DESC_ANT_MAPB(txdesc)
+#define SET_TX_DESC_ANT_MAPA_8822B(txdesc, value)                              \
+	SET_TX_DESC_ANT_MAPA(txdesc, value)
+#define GET_TX_DESC_ANT_MAPA_8822B(txdesc) GET_TX_DESC_ANT_MAPA(txdesc)
+#define SET_TX_DESC_ANTSEL_C_8822B(txdesc, value)                              \
+	SET_TX_DESC_ANTSEL_C(txdesc, value)
+#define GET_TX_DESC_ANTSEL_C_8822B(txdesc) GET_TX_DESC_ANTSEL_C(txdesc)
+#define SET_TX_DESC_ANTSEL_B_8822B(txdesc, value)                              \
+	SET_TX_DESC_ANTSEL_B(txdesc, value)
+#define GET_TX_DESC_ANTSEL_B_8822B(txdesc) GET_TX_DESC_ANTSEL_B(txdesc)
+#define SET_TX_DESC_ANTSEL_A_8822B(txdesc, value)                              \
+	SET_TX_DESC_ANTSEL_A(txdesc, value)
+#define GET_TX_DESC_ANTSEL_A_8822B(txdesc) GET_TX_DESC_ANTSEL_A(txdesc)
+#define SET_TX_DESC_MBSSID_8822B(txdesc, value)                                \
+	SET_TX_DESC_MBSSID(txdesc, value)
+#define GET_TX_DESC_MBSSID_8822B(txdesc) GET_TX_DESC_MBSSID(txdesc)
+#define SET_TX_DESC_SW_DEFINE_8822B(txdesc, value)                             \
+	SET_TX_DESC_SW_DEFINE(txdesc, value)
+#define GET_TX_DESC_SW_DEFINE_8822B(txdesc) GET_TX_DESC_SW_DEFINE(txdesc)
+
+/*TXDESC_WORD7*/
+
+#define SET_TX_DESC_DMA_TXAGG_NUM_8822B(txdesc, value)                         \
+	SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value)
+#define GET_TX_DESC_DMA_TXAGG_NUM_8822B(txdesc)                                \
+	GET_TX_DESC_DMA_TXAGG_NUM(txdesc)
+#define SET_TX_DESC_FINAL_DATA_RATE_8822B(txdesc, value)                       \
+	SET_TX_DESC_FINAL_DATA_RATE(txdesc, value)
+#define GET_TX_DESC_FINAL_DATA_RATE_8822B(txdesc)                              \
+	GET_TX_DESC_FINAL_DATA_RATE(txdesc)
+#define SET_TX_DESC_NTX_MAP_8822B(txdesc, value)                               \
+	SET_TX_DESC_NTX_MAP(txdesc, value)
+#define GET_TX_DESC_NTX_MAP_8822B(txdesc) GET_TX_DESC_NTX_MAP(txdesc)
+#define SET_TX_DESC_TX_BUFF_SIZE_8822B(txdesc, value)                          \
+	SET_TX_DESC_TX_BUFF_SIZE(txdesc, value)
+#define GET_TX_DESC_TX_BUFF_SIZE_8822B(txdesc) GET_TX_DESC_TX_BUFF_SIZE(txdesc)
+#define SET_TX_DESC_TXDESC_CHECKSUM_8822B(txdesc, value)                       \
+	SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value)
+#define GET_TX_DESC_TXDESC_CHECKSUM_8822B(txdesc)                              \
+	GET_TX_DESC_TXDESC_CHECKSUM(txdesc)
+#define SET_TX_DESC_TIMESTAMP_8822B(txdesc, value)                             \
+	SET_TX_DESC_TIMESTAMP(txdesc, value)
+#define GET_TX_DESC_TIMESTAMP_8822B(txdesc) GET_TX_DESC_TIMESTAMP(txdesc)
+
+/*TXDESC_WORD8*/
+
+#define SET_TX_DESC_TXWIFI_CP_8822B(txdesc, value)                             \
+	SET_TX_DESC_TXWIFI_CP(txdesc, value)
+#define GET_TX_DESC_TXWIFI_CP_8822B(txdesc) GET_TX_DESC_TXWIFI_CP(txdesc)
+#define SET_TX_DESC_MAC_CP_8822B(txdesc, value)                                \
+	SET_TX_DESC_MAC_CP(txdesc, value)
+#define GET_TX_DESC_MAC_CP_8822B(txdesc) GET_TX_DESC_MAC_CP(txdesc)
+#define SET_TX_DESC_STW_PKTRE_DIS_8822B(txdesc, value)                         \
+	SET_TX_DESC_STW_PKTRE_DIS(txdesc, value)
+#define GET_TX_DESC_STW_PKTRE_DIS_8822B(txdesc)                                \
+	GET_TX_DESC_STW_PKTRE_DIS(txdesc)
+#define SET_TX_DESC_STW_RB_DIS_8822B(txdesc, value)                            \
+	SET_TX_DESC_STW_RB_DIS(txdesc, value)
+#define GET_TX_DESC_STW_RB_DIS_8822B(txdesc) GET_TX_DESC_STW_RB_DIS(txdesc)
+#define SET_TX_DESC_STW_RATE_DIS_8822B(txdesc, value)                          \
+	SET_TX_DESC_STW_RATE_DIS(txdesc, value)
+#define GET_TX_DESC_STW_RATE_DIS_8822B(txdesc) GET_TX_DESC_STW_RATE_DIS(txdesc)
+#define SET_TX_DESC_STW_ANT_DIS_8822B(txdesc, value)                           \
+	SET_TX_DESC_STW_ANT_DIS(txdesc, value)
+#define GET_TX_DESC_STW_ANT_DIS_8822B(txdesc) GET_TX_DESC_STW_ANT_DIS(txdesc)
+#define SET_TX_DESC_STW_EN_8822B(txdesc, value)                                \
+	SET_TX_DESC_STW_EN(txdesc, value)
+#define GET_TX_DESC_STW_EN_8822B(txdesc) GET_TX_DESC_STW_EN(txdesc)
+#define SET_TX_DESC_SMH_EN_8822B(txdesc, value)                                \
+	SET_TX_DESC_SMH_EN(txdesc, value)
+#define GET_TX_DESC_SMH_EN_8822B(txdesc) GET_TX_DESC_SMH_EN(txdesc)
+#define SET_TX_DESC_TAILPAGE_L_8822B(txdesc, value)                            \
+	SET_TX_DESC_TAILPAGE_L(txdesc, value)
+#define GET_TX_DESC_TAILPAGE_L_8822B(txdesc) GET_TX_DESC_TAILPAGE_L(txdesc)
+#define SET_TX_DESC_SDIO_DMASEQ_8822B(txdesc, value)                           \
+	SET_TX_DESC_SDIO_DMASEQ(txdesc, value)
+#define GET_TX_DESC_SDIO_DMASEQ_8822B(txdesc) GET_TX_DESC_SDIO_DMASEQ(txdesc)
+#define SET_TX_DESC_NEXTHEADPAGE_L_8822B(txdesc, value)                        \
+	SET_TX_DESC_NEXTHEADPAGE_L(txdesc, value)
+#define GET_TX_DESC_NEXTHEADPAGE_L_8822B(txdesc)                               \
+	GET_TX_DESC_NEXTHEADPAGE_L(txdesc)
+#define SET_TX_DESC_EN_HWSEQ_8822B(txdesc, value)                              \
+	SET_TX_DESC_EN_HWSEQ(txdesc, value)
+#define GET_TX_DESC_EN_HWSEQ_8822B(txdesc) GET_TX_DESC_EN_HWSEQ(txdesc)
+#define SET_TX_DESC_EN_HWEXSEQ_8822B(txdesc, value)                            \
+	SET_TX_DESC_EN_HWEXSEQ(txdesc, value)
+#define GET_TX_DESC_EN_HWEXSEQ_8822B(txdesc) GET_TX_DESC_EN_HWEXSEQ(txdesc)
+#define SET_TX_DESC_DATA_RC_8822B(txdesc, value)                               \
+	SET_TX_DESC_DATA_RC(txdesc, value)
+#define GET_TX_DESC_DATA_RC_8822B(txdesc) GET_TX_DESC_DATA_RC(txdesc)
+#define SET_TX_DESC_BAR_RTY_TH_8822B(txdesc, value)                            \
+	SET_TX_DESC_BAR_RTY_TH(txdesc, value)
+#define GET_TX_DESC_BAR_RTY_TH_8822B(txdesc) GET_TX_DESC_BAR_RTY_TH(txdesc)
+#define SET_TX_DESC_RTS_RC_8822B(txdesc, value)                                \
+	SET_TX_DESC_RTS_RC(txdesc, value)
+#define GET_TX_DESC_RTS_RC_8822B(txdesc) GET_TX_DESC_RTS_RC(txdesc)
+
+/*TXDESC_WORD9*/
+
+#define SET_TX_DESC_TAILPAGE_H_8822B(txdesc, value)                            \
+	SET_TX_DESC_TAILPAGE_H(txdesc, value)
+#define GET_TX_DESC_TAILPAGE_H_8822B(txdesc) GET_TX_DESC_TAILPAGE_H(txdesc)
+#define SET_TX_DESC_NEXTHEADPAGE_H_8822B(txdesc, value)                        \
+	SET_TX_DESC_NEXTHEADPAGE_H(txdesc, value)
+#define GET_TX_DESC_NEXTHEADPAGE_H_8822B(txdesc)                               \
+	GET_TX_DESC_NEXTHEADPAGE_H(txdesc)
+#define SET_TX_DESC_SW_SEQ_8822B(txdesc, value)                                \
+	SET_TX_DESC_SW_SEQ(txdesc, value)
+#define GET_TX_DESC_SW_SEQ_8822B(txdesc) GET_TX_DESC_SW_SEQ(txdesc)
+#define SET_TX_DESC_TXBF_PATH_8822B(txdesc, value)                             \
+	SET_TX_DESC_TXBF_PATH(txdesc, value)
+#define GET_TX_DESC_TXBF_PATH_8822B(txdesc) GET_TX_DESC_TXBF_PATH(txdesc)
+#define SET_TX_DESC_PADDING_LEN_8822B(txdesc, value)                           \
+	SET_TX_DESC_PADDING_LEN(txdesc, value)
+#define GET_TX_DESC_PADDING_LEN_8822B(txdesc) GET_TX_DESC_PADDING_LEN(txdesc)
+#define SET_TX_DESC_GROUP_BIT_IE_OFFSET_8822B(txdesc, value)                   \
+	SET_TX_DESC_GROUP_BIT_IE_OFFSET(txdesc, value)
+#define GET_TX_DESC_GROUP_BIT_IE_OFFSET_8822B(txdesc)                          \
+	GET_TX_DESC_GROUP_BIT_IE_OFFSET(txdesc)
+
+/*WORD10*/
+
+#define SET_TX_DESC_MU_DATARATE_8822B(txdesc, value)                           \
+	SET_TX_DESC_MU_DATARATE(txdesc, value)
+#define GET_TX_DESC_MU_DATARATE_8822B(txdesc) GET_TX_DESC_MU_DATARATE(txdesc)
+#define SET_TX_DESC_MU_RC_8822B(txdesc, value) SET_TX_DESC_MU_RC(txdesc, value)
+#define GET_TX_DESC_MU_RC_8822B(txdesc) GET_TX_DESC_MU_RC(txdesc)
+#define SET_TX_DESC_SND_PKT_SEL_8822B(txdesc, value)                           \
+	SET_TX_DESC_SND_PKT_SEL(txdesc, value)
+#define GET_TX_DESC_SND_PKT_SEL_8822B(txdesc) GET_TX_DESC_SND_PKT_SEL(txdesc)
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_nic.h
new file mode 100644
index 000000000000..2fa2381730df
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_tx_desc_nic.h
@@ -0,0 +1,439 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_TX_DESC_NIC_H_
+#define _HALMAC_TX_DESC_NIC_H_
+
+/*TXDESC_WORD0*/
+
+#define SET_TX_DESC_DISQSELSEQ(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 31, 1, value)
+#define GET_TX_DESC_DISQSELSEQ(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 31, 1)
+
+#define SET_TX_DESC_GF(txdesc, value)                                          \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 30, 1, value)
+#define GET_TX_DESC_GF(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 30, 1)
+
+#define SET_TX_DESC_NO_ACM(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 29, 1, value)
+#define GET_TX_DESC_NO_ACM(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 29, 1)
+
+#define SET_TX_DESC_BCNPKT_TSF_CTRL(txdesc, value)                             \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 28, 1, value)
+#define GET_TX_DESC_BCNPKT_TSF_CTRL(txdesc)                                    \
+	LE_BITS_TO_4BYTE(txdesc + 0x00, 28, 1)
+
+#define SET_TX_DESC_AMSDU_PAD_EN(txdesc, value)                                \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 27, 1, value)
+#define GET_TX_DESC_AMSDU_PAD_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 27, 1)
+#define SET_TX_DESC_LS(txdesc, value)                                          \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 26, 1, value)
+#define GET_TX_DESC_LS(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 26, 1)
+#define SET_TX_DESC_HTC(txdesc, value)                                         \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 25, 1, value)
+#define GET_TX_DESC_HTC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 25, 1)
+#define SET_TX_DESC_BMC(txdesc, value)                                         \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 24, 1, value)
+#define GET_TX_DESC_BMC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 24, 1)
+
+#define SET_TX_DESC_OFFSET(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 16, 8, value)
+#define GET_TX_DESC_OFFSET(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 16, 8)
+#define SET_TX_DESC_TXPKTSIZE(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x00, 0, 16, value)
+#define GET_TX_DESC_TXPKTSIZE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x00, 0, 16)
+
+#define SET_TX_DESC_MOREDATA(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 29, 1, value)
+#define GET_TX_DESC_MOREDATA(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 29, 1)
+
+#define SET_TX_DESC_PKT_OFFSET(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 24, 5, value)
+#define GET_TX_DESC_PKT_OFFSET(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 24, 5)
+
+#define SET_TX_DESC_SEC_TYPE(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 22, 2, value)
+#define GET_TX_DESC_SEC_TYPE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 22, 2)
+#define SET_TX_DESC_EN_DESC_ID(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 21, 1, value)
+#define GET_TX_DESC_EN_DESC_ID(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 21, 1)
+#define SET_TX_DESC_RATE_ID(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 16, 5, value)
+#define GET_TX_DESC_RATE_ID(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 16, 5)
+
+#define SET_TX_DESC_PIFS(txdesc, value)                                        \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 15, 1, value)
+#define GET_TX_DESC_PIFS(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 15, 1)
+#define SET_TX_DESC_LSIG_TXOP_EN(txdesc, value)                                \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 14, 1, value)
+#define GET_TX_DESC_LSIG_TXOP_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 14, 1)
+#define SET_TX_DESC_RD_NAV_EXT(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 13, 1, value)
+#define GET_TX_DESC_RD_NAV_EXT(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 13, 1)
+
+#define SET_TX_DESC_QSEL(txdesc, value)                                        \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 8, 5, value)
+#define GET_TX_DESC_QSEL(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 8, 5)
+
+#define SET_TX_DESC_MACID(txdesc, value)                                       \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x04, 0, 7, value)
+#define GET_TX_DESC_MACID(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x04, 0, 7)
+
+/*TXDESC_WORD2*/
+
+#define SET_TX_DESC_HW_AES_IV(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 31, 1, value)
+#define GET_TX_DESC_HW_AES_IV(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 31, 1)
+
+#define SET_TX_DESC_FTM_EN(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 30, 1, value)
+#define GET_TX_DESC_FTM_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 30, 1)
+
+#define SET_TX_DESC_G_ID(txdesc, value)                                        \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 24, 6, value)
+#define GET_TX_DESC_G_ID(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 24, 6)
+
+#define SET_TX_DESC_BT_NULL(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 23, 1, value)
+#define GET_TX_DESC_BT_NULL(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 23, 1)
+#define SET_TX_DESC_AMPDU_DENSITY(txdesc, value)                               \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 20, 3, value)
+#define GET_TX_DESC_AMPDU_DENSITY(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 20, 3)
+#define SET_TX_DESC_SPE_RPT(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 19, 1, value)
+#define GET_TX_DESC_SPE_RPT(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 19, 1)
+#define SET_TX_DESC_RAW(txdesc, value)                                         \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 18, 1, value)
+#define GET_TX_DESC_RAW(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 18, 1)
+#define SET_TX_DESC_MOREFRAG(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 17, 1, value)
+#define GET_TX_DESC_MOREFRAG(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 17, 1)
+#define SET_TX_DESC_BK(txdesc, value)                                          \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 16, 1, value)
+#define GET_TX_DESC_BK(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 16, 1)
+
+#define SET_TX_DESC_NULL_1(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 15, 1, value)
+#define GET_TX_DESC_NULL_1(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 15, 1)
+#define SET_TX_DESC_NULL_0(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 14, 1, value)
+#define GET_TX_DESC_NULL_0(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 14, 1)
+#define SET_TX_DESC_RDG_EN(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 13, 1, value)
+#define GET_TX_DESC_RDG_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 13, 1)
+#define SET_TX_DESC_AGG_EN(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 12, 1, value)
+#define GET_TX_DESC_AGG_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 12, 1)
+#define SET_TX_DESC_CCA_RTS(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 10, 2, value)
+#define GET_TX_DESC_CCA_RTS(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 10, 2)
+
+#define SET_TX_DESC_TRI_FRAME(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 9, 1, value)
+#define GET_TX_DESC_TRI_FRAME(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 9, 1)
+
+#define SET_TX_DESC_P_AID(txdesc, value)                                       \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x08, 0, 9, value)
+#define GET_TX_DESC_P_AID(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x08, 0, 9)
+
+/*TXDESC_WORD3*/
+
+#define SET_TX_DESC_AMPDU_MAX_TIME(txdesc, value)                              \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 24, 8, value)
+#define GET_TX_DESC_AMPDU_MAX_TIME(txdesc)                                     \
+	LE_BITS_TO_4BYTE(txdesc + 0x0C, 24, 8)
+#define SET_TX_DESC_NDPA(txdesc, value)                                        \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 22, 2, value)
+#define GET_TX_DESC_NDPA(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 22, 2)
+#define SET_TX_DESC_MAX_AGG_NUM(txdesc, value)                                 \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 17, 5, value)
+#define GET_TX_DESC_MAX_AGG_NUM(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 17, 5)
+#define SET_TX_DESC_USE_MAX_TIME_EN(txdesc, value)                             \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 16, 1, value)
+#define GET_TX_DESC_USE_MAX_TIME_EN(txdesc)                                    \
+	LE_BITS_TO_4BYTE(txdesc + 0x0C, 16, 1)
+
+#define SET_TX_DESC_NAVUSEHDR(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 15, 1, value)
+#define GET_TX_DESC_NAVUSEHDR(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 15, 1)
+#define SET_TX_DESC_CHK_EN(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 14, 1, value)
+#define GET_TX_DESC_CHK_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 14, 1)
+#define SET_TX_DESC_HW_RTS_EN(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 13, 1, value)
+#define GET_TX_DESC_HW_RTS_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 13, 1)
+#define SET_TX_DESC_RTSEN(txdesc, value)                                       \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 12, 1, value)
+#define GET_TX_DESC_RTSEN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 12, 1)
+#define SET_TX_DESC_CTS2SELF(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 11, 1, value)
+#define GET_TX_DESC_CTS2SELF(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 11, 1)
+
+#define SET_TX_DESC_DISDATAFB(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 10, 1, value)
+#define GET_TX_DESC_DISDATAFB(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 10, 1)
+#define SET_TX_DESC_DISRTSFB(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 9, 1, value)
+#define GET_TX_DESC_DISRTSFB(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 9, 1)
+#define SET_TX_DESC_USE_RATE(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 8, 1, value)
+#define GET_TX_DESC_USE_RATE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 8, 1)
+#define SET_TX_DESC_HW_SSN_SEL(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 6, 2, value)
+#define GET_TX_DESC_HW_SSN_SEL(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 6, 2)
+
+#define SET_TX_DESC_WHEADER_LEN(txdesc, value)                                 \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x0C, 0, 5, value)
+#define GET_TX_DESC_WHEADER_LEN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x0C, 0, 5)
+
+/*TXDESC_WORD4*/
+
+#define SET_TX_DESC_PCTS_MASK_IDX(txdesc, value)                               \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 30, 2, value)
+#define GET_TX_DESC_PCTS_MASK_IDX(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x10, 30, 2)
+#define SET_TX_DESC_PCTS_EN(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 29, 1, value)
+#define GET_TX_DESC_PCTS_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x10, 29, 1)
+#define SET_TX_DESC_RTSRATE(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 24, 5, value)
+#define GET_TX_DESC_RTSRATE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x10, 24, 5)
+#define SET_TX_DESC_RTS_DATA_RTY_LMT(txdesc, value)                            \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 18, 6, value)
+#define GET_TX_DESC_RTS_DATA_RTY_LMT(txdesc)                                   \
+	LE_BITS_TO_4BYTE(txdesc + 0x10, 18, 6)
+#define SET_TX_DESC_RTY_LMT_EN(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 17, 1, value)
+#define GET_TX_DESC_RTY_LMT_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x10, 17, 1)
+#define SET_TX_DESC_RTS_RTY_LOWEST_RATE(txdesc, value)                         \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 13, 4, value)
+#define GET_TX_DESC_RTS_RTY_LOWEST_RATE(txdesc)                                \
+	LE_BITS_TO_4BYTE(txdesc + 0x10, 13, 4)
+#define SET_TX_DESC_DATA_RTY_LOWEST_RATE(txdesc, value)                        \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 8, 5, value)
+#define GET_TX_DESC_DATA_RTY_LOWEST_RATE(txdesc)                               \
+	LE_BITS_TO_4BYTE(txdesc + 0x10, 8, 5)
+#define SET_TX_DESC_TRY_RATE(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 7, 1, value)
+#define GET_TX_DESC_TRY_RATE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x10, 7, 1)
+#define SET_TX_DESC_DATARATE(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x10, 0, 7, value)
+#define GET_TX_DESC_DATARATE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x10, 0, 7)
+
+/*TXDESC_WORD5*/
+
+#define SET_TX_DESC_POLLUTED(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 31, 1, value)
+#define GET_TX_DESC_POLLUTED(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 31, 1)
+
+#define SET_TX_DESC_TXPWR_OFSET(txdesc, value)                                 \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 28, 3, value)
+#define GET_TX_DESC_TXPWR_OFSET(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 28, 3)
+
+#define SET_TX_DESC_TX_ANT(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 24, 4, value)
+#define GET_TX_DESC_TX_ANT(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 24, 4)
+
+#define SET_TX_DESC_PORT_ID(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 21, 3, value)
+#define GET_TX_DESC_PORT_ID(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 21, 3)
+
+#define SET_TX_DESC_MULTIPLE_PORT(txdesc, value)                               \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 18, 3, value)
+#define GET_TX_DESC_MULTIPLE_PORT(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 18, 3)
+
+#define SET_TX_DESC_SIGNALING_TAPKT_EN(txdesc, value)                          \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 17, 1, value)
+#define GET_TX_DESC_SIGNALING_TAPKT_EN(txdesc)                                 \
+	LE_BITS_TO_4BYTE(txdesc + 0x14, 17, 1)
+
+#define SET_TX_DESC_SIGNALING_TA_PKT_SC(txdesc, value)                         \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 13, 4, value)
+#define GET_TX_DESC_SIGNALING_TA_PKT_SC(txdesc)                                \
+	LE_BITS_TO_4BYTE(txdesc + 0x14, 13, 4)
+
+#define SET_TX_DESC_RTS_SHORT(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 12, 1, value)
+#define GET_TX_DESC_RTS_SHORT(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 12, 1)
+#define SET_TX_DESC_VCS_STBC(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 10, 2, value)
+#define GET_TX_DESC_VCS_STBC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 10, 2)
+#define SET_TX_DESC_DATA_STBC(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 8, 2, value)
+#define GET_TX_DESC_DATA_STBC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 8, 2)
+#define SET_TX_DESC_DATA_LDPC(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 7, 1, value)
+#define GET_TX_DESC_DATA_LDPC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 7, 1)
+#define SET_TX_DESC_DATA_BW(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 5, 2, value)
+#define GET_TX_DESC_DATA_BW(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 5, 2)
+#define SET_TX_DESC_DATA_SHORT(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 4, 1, value)
+#define GET_TX_DESC_DATA_SHORT(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 4, 1)
+#define SET_TX_DESC_DATA_SC(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x14, 0, 4, value)
+#define GET_TX_DESC_DATA_SC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x14, 0, 4)
+
+/*TXDESC_WORD6*/
+
+#define SET_TX_DESC_ANTSEL_D(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 30, 2, value)
+#define GET_TX_DESC_ANTSEL_D(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 30, 2)
+
+#define SET_TX_DESC_ANT_MAPD(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 28, 2, value)
+#define GET_TX_DESC_ANT_MAPD(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 28, 2)
+
+#define SET_TX_DESC_ANT_MAPC(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 26, 2, value)
+#define GET_TX_DESC_ANT_MAPC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 26, 2)
+
+#define SET_TX_DESC_ANT_MAPB(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 24, 2, value)
+#define GET_TX_DESC_ANT_MAPB(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 24, 2)
+
+#define SET_TX_DESC_ANT_MAPA(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 22, 2, value)
+#define GET_TX_DESC_ANT_MAPA(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 22, 2)
+#define SET_TX_DESC_ANTSEL_C(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 20, 2, value)
+#define GET_TX_DESC_ANTSEL_C(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 20, 2)
+
+#define SET_TX_DESC_ANTSEL_B(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 18, 2, value)
+#define GET_TX_DESC_ANTSEL_B(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 18, 2)
+#define SET_TX_DESC_ANTSEL_A(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 16, 2, value)
+#define GET_TX_DESC_ANTSEL_A(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 16, 2)
+
+#define SET_TX_DESC_MBSSID(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 12, 4, value)
+#define GET_TX_DESC_MBSSID(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 12, 4)
+
+#define SET_TX_DESC_SW_DEFINE(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x18, 0, 12, value)
+#define GET_TX_DESC_SW_DEFINE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x18, 0, 12)
+
+/*TXDESC_WORD7*/
+
+#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value)                               \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x1C, 24, 8, value)
+#define GET_TX_DESC_DMA_TXAGG_NUM(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x1C, 24, 8)
+#define SET_TX_DESC_FINAL_DATA_RATE(txdesc, value)                             \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x1C, 24, 8, value)
+#define GET_TX_DESC_FINAL_DATA_RATE(txdesc)                                    \
+	LE_BITS_TO_4BYTE(txdesc + 0x1C, 24, 8)
+#define SET_TX_DESC_NTX_MAP(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x1C, 20, 4, value)
+#define GET_TX_DESC_NTX_MAP(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x1C, 20, 4)
+
+#define SET_TX_DESC_TX_BUFF_SIZE(txdesc, value)                                \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x1C, 0, 16, value)
+#define GET_TX_DESC_TX_BUFF_SIZE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x1C, 0, 16)
+#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value)                             \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x1C, 0, 16, value)
+#define GET_TX_DESC_TXDESC_CHECKSUM(txdesc)                                    \
+	LE_BITS_TO_4BYTE(txdesc + 0x1C, 0, 16)
+#define SET_TX_DESC_TIMESTAMP(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x1C, 0, 16, value)
+#define GET_TX_DESC_TIMESTAMP(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x1C, 0, 16)
+
+/*TXDESC_WORD8*/
+
+#define SET_TX_DESC_TXWIFI_CP(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 31, 1, value)
+#define GET_TX_DESC_TXWIFI_CP(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 31, 1)
+#define SET_TX_DESC_MAC_CP(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 30, 1, value)
+#define GET_TX_DESC_MAC_CP(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 30, 1)
+#define SET_TX_DESC_STW_PKTRE_DIS(txdesc, value)                               \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 29, 1, value)
+#define GET_TX_DESC_STW_PKTRE_DIS(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 29, 1)
+#define SET_TX_DESC_STW_RB_DIS(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 28, 1, value)
+#define GET_TX_DESC_STW_RB_DIS(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 28, 1)
+#define SET_TX_DESC_STW_RATE_DIS(txdesc, value)                                \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 27, 1, value)
+#define GET_TX_DESC_STW_RATE_DIS(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 27, 1)
+#define SET_TX_DESC_STW_ANT_DIS(txdesc, value)                                 \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 26, 1, value)
+#define GET_TX_DESC_STW_ANT_DIS(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 26, 1)
+#define SET_TX_DESC_STW_EN(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 25, 1, value)
+#define GET_TX_DESC_STW_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 25, 1)
+#define SET_TX_DESC_SMH_EN(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 24, 1, value)
+#define GET_TX_DESC_SMH_EN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 24, 1)
+#define SET_TX_DESC_TAILPAGE_L(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 24, 8, value)
+#define GET_TX_DESC_TAILPAGE_L(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 24, 8)
+#define SET_TX_DESC_SDIO_DMASEQ(txdesc, value)                                 \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 16, 8, value)
+#define GET_TX_DESC_SDIO_DMASEQ(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 16, 8)
+#define SET_TX_DESC_NEXTHEADPAGE_L(txdesc, value)                              \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 16, 8, value)
+#define GET_TX_DESC_NEXTHEADPAGE_L(txdesc)                                     \
+	LE_BITS_TO_4BYTE(txdesc + 0x20, 16, 8)
+#define SET_TX_DESC_EN_HWSEQ(txdesc, value)                                    \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 15, 1, value)
+#define GET_TX_DESC_EN_HWSEQ(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 15, 1)
+#define SET_TX_DESC_EN_HWEXSEQ(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 14, 1, value)
+#define GET_TX_DESC_EN_HWEXSEQ(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 14, 1)
+#define SET_TX_DESC_DATA_RC(txdesc, value)                                     \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 8, 6, value)
+#define GET_TX_DESC_DATA_RC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 8, 6)
+#define SET_TX_DESC_BAR_RTY_TH(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 6, 2, value)
+#define GET_TX_DESC_BAR_RTY_TH(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 6, 2)
+#define SET_TX_DESC_RTS_RC(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x20, 0, 6, value)
+#define GET_TX_DESC_RTS_RC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x20, 0, 6)
+
+/*TXDESC_WORD9*/
+
+#define SET_TX_DESC_TAILPAGE_H(txdesc, value)                                  \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x24, 28, 4, value)
+#define GET_TX_DESC_TAILPAGE_H(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x24, 28, 4)
+#define SET_TX_DESC_NEXTHEADPAGE_H(txdesc, value)                              \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x24, 24, 4, value)
+#define GET_TX_DESC_NEXTHEADPAGE_H(txdesc)                                     \
+	LE_BITS_TO_4BYTE(txdesc + 0x24, 24, 4)
+#define SET_TX_DESC_SW_SEQ(txdesc, value)                                      \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x24, 12, 12, value)
+#define GET_TX_DESC_SW_SEQ(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x24, 12, 12)
+#define SET_TX_DESC_TXBF_PATH(txdesc, value)                                   \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x24, 11, 1, value)
+#define GET_TX_DESC_TXBF_PATH(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x24, 11, 1)
+#define SET_TX_DESC_PADDING_LEN(txdesc, value)                                 \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x24, 0, 11, value)
+#define GET_TX_DESC_PADDING_LEN(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x24, 0, 11)
+#define SET_TX_DESC_GROUP_BIT_IE_OFFSET(txdesc, value)                         \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x24, 0, 8, value)
+#define GET_TX_DESC_GROUP_BIT_IE_OFFSET(txdesc)                                \
+	LE_BITS_TO_4BYTE(txdesc + 0x24, 0, 8)
+
+/*WORD10*/
+
+#define SET_TX_DESC_MU_DATARATE(txdesc, value)                                 \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x28, 8, 8, value)
+#define GET_TX_DESC_MU_DATARATE(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x28, 8, 8)
+#define SET_TX_DESC_MU_RC(txdesc, value)                                       \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x28, 4, 4, value)
+#define GET_TX_DESC_MU_RC(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x28, 4, 4)
+#define SET_TX_DESC_SND_PKT_SEL(txdesc, value)                                 \
+	SET_BITS_TO_LE_4BYTE(txdesc + 0x28, 0, 2, value)
+#define GET_TX_DESC_SND_PKT_SEL(txdesc) LE_BITS_TO_4BYTE(txdesc + 0x28, 0, 2)
+
+#endif
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 08/17] rtlwifi: halmac: add GPIO pin/pinmux definitions
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (5 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 07/17] rtlwifi: halmac: add definition of TX/RX descriptor pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 09/17] rtlwifi: halmac: add power sequence to turn on/off wifi card pkshih
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

GPIO with pinmux can switch to many functions such as LED, UART, JTAG,
WoWLAN, etc.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../halmac_88xx/halmac_8822b/halmac_gpio_8822b.c   | 847 +++++++++++++++++++++
 .../halmac_88xx/halmac_8822b/halmac_gpio_8822b.h   |  34 +
 .../rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.c  | 415 ++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.h  |  55 ++
 .../realtek/rtlwifi/halmac/halmac_gpio_cmd.h       |  84 ++
 5 files changed, 1435 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_gpio_cmd.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.c
new file mode 100644
index 000000000000..3d43de98bb46
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.c
@@ -0,0 +1,847 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_gpio_8822b.h"
+#include "../halmac_gpio_88xx.h"
+
+/* GPIO0 definition */
+#define GPIO0_BT_GPIO0_8822B	\
+	{HALMAC_BT_GPIO, HALMAC_GPIO0, HALMAC_GPIO_IN_OUT, \
+	 0x66, BIT(2), BIT(2)}
+#define GPIO0_BT_ACT_8822B	\
+	{HALMAC_BT_PTA, HALMAC_GPIO0, HALMAC_GPIO_IN_OUT, \
+	 0x41, BIT(1), 0}
+#define GPIO0_WL_ACT_8822B	\
+	{HALMAC_WL_PTA, HALMAC_GPIO0, HALMAC_GPIO_IN_OUT, \
+	 0x41, BIT(2), BIT(2)}
+#define GPIO0_WLMAC_DBG_GPIO0_8822B	\
+	{HALMAC_WLMAC_DBG, HALMAC_GPIO0, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0)}
+#define GPIO0_WLPHY_DBG_GPIO0_8822B	\
+	{HALMAC_WLPHY_DBG, HALMAC_GPIO0, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(1)}
+#define GPIO0_BT_DBG_GPIO0_8822B	\
+	{HALMAC_BT_DBG, HALMAC_GPIO0, HALMAC_GPIO_OUT, \
+	0x40, BIT(1) | BIT(0), BIT(0) | BIT(1)}
+#define GPIO0_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO0, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO1 definition */
+#define GPIO1_BT_GPIO1_8822B	\
+	{HALMAC_BT_GPIO, HALMAC_GPIO1, HALMAC_GPIO_IN_OUT, \
+	 0x66, BIT(2), BIT(2)}
+#define GPIO1_BT_3DD_SYNC_A_8822B	\
+	{HALMAC_BT_3DDLS_A, HALMAC_GPIO1, HALMAC_GPIO_IN, \
+	 0x66, BIT(2), BIT(2)}
+#define GPIO1_WL_CK_8822B	\
+	{HALMAC_BT_PTA, HALMAC_GPIO1, HALMAC_GPIO_OUT, \
+	 0x41, BIT(1), 0}
+#define GPIO1_BT_CK_8822B	\
+	{HALMAC_WL_PTA, HALMAC_GPIO1, HALMAC_GPIO_OUT, \
+	 0x41, BIT(2), BIT(2)}
+#define GPIO1_WLMAC_DBG_GPIO1_8822B	\
+	{HALMAC_WLMAC_DBG, HALMAC_GPIO1, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0)}
+#define GPIO1_WLPHY_DBG_GPIO1_8822B	\
+	{HALMAC_WLPHY_DBG, HALMAC_GPIO1, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(1)}
+#define GPIO1_BT_DBG_GPIO1_8822B	\
+	{HALMAC_BT_DBG, HALMAC_GPIO1, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0) | BIT(1)}
+#define GPIO1_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO1, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO2 definition */
+#define GPIO2_BT_GPIO2_8822B	\
+	{HALMAC_BT_GPIO, HALMAC_GPIO2, HALMAC_GPIO_IN_OUT, \
+	 0x66, BIT(2), BIT(2)}
+#define GPIO2_WL_STATE_8822B	\
+	{HALMAC_BT_PTA, HALMAC_GPIO2, HALMAC_GPIO_OUT, \
+	 0x41, BIT(1), 0}
+#define GPIO2_BT_STATE_8822B	\
+	{HALMAC_WL_PTA, HALMAC_GPIO2, HALMAC_GPIO_OUT, \
+	 0x41, BIT(2), BIT(2)}
+#define GPIO2_WLMAC_DBG_GPIO2_8822B	\
+	{HALMAC_WLMAC_DBG, HALMAC_GPIO2, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0)}
+#define GPIO2_WLPHY_DBG_GPIO2_8822B	\
+	{HALMAC_WLPHY_DBG, HALMAC_GPIO2, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(1)}
+#define GPIO2_BT_DBG_GPIO2_8822B	\
+	{HALMAC_BT_DBG, HALMAC_GPIO2, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0) | BIT(1)}
+#define GPIO2_RFE_CTRL_5_8822B	\
+	{HALMAC_WLPHY_RFE_CTRL2GPIO, HALMAC_GPIO2, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(2), BIT(2)}
+#define GPIO2_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO2, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO3 definition */
+#define GPIO3_BT_GPIO3_8822B	\
+	{HALMAC_BT_GPIO, HALMAC_GPIO3, HALMAC_GPIO_IN_OUT, \
+	 0x66, BIT(2), BIT(2)}
+#define GPIO3_WL_PRI_8822B	\
+	{HALMAC_BT_PTA, HALMAC_GPIO3, HALMAC_GPIO_OUT, \
+	 0x41, BIT(1), 0}
+#define GPIO3_BT_PRI_8822B	\
+	{HALMAC_WL_PTA, HALMAC_GPIO3, HALMAC_GPIO_OUT, \
+	 0x41, BIT(2), BIT(2)}
+#define GPIO3_WLMAC_DBG_GPIO3_8822B	\
+	{HALMAC_WLMAC_DBG, HALMAC_GPIO3, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0)}
+#define GPIO3_WLPHY_DBG_GPIO3_8822B	\
+	{HALMAC_WLPHY_DBG, HALMAC_GPIO3, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(1)}
+#define GPIO3_BT_DBG_GPIO3_8822B	\
+	{HALMAC_BT_DBG, HALMAC_GPIO3, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0) | BIT(1)}
+#define GPIO3_RFE_CTRL_4_8822B	\
+	{HALMAC_WLPHY_RFE_CTRL2GPIO, HALMAC_GPIO3, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(2), BIT(2)}
+#define GPIO3_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO3, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO4 definition */
+#define GPIO4_BT_SPI_D0_8822B	\
+	{HALMAC_BT_SFLASH, HALMAC_GPIO4, HALMAC_GPIO_IN_OUT, \
+	 0x66, BIT(4), BIT(4)}
+#define GPIO4_WL_SPI_D0_8822B	\
+	{HALMAC_WL_SFLASH, HALMAC_GPIO4, HALMAC_GPIO_IN_OUT, \
+	 0x42, BIT(3), BIT(3)}
+#define GPIO4_SDIO_INT_8822B	\
+	{HALMAC_SDIO_INT, HALMAC_GPIO4, HALMAC_GPIO_OUT, \
+	 0x72, BIT(2), BIT(2)}
+#define GPIO4_JTAG_TRST_8822B	\
+	{HALMAC_JTAG, HALMAC_GPIO4, HALMAC_GPIO_IN, \
+	 0x67, BIT(0), BIT(0)}
+#define GPIO4_DBG_GNT_WL_8822B	\
+	{HALMAC_DBG_GNT_WL_BT, HALMAC_GPIO4, HALMAC_GPIO_OUT, \
+	 0x73, BIT(3), BIT(3)}
+#define GPIO4_WLMAC_DBG_GPIO4_8822B	\
+	{HALMAC_WLMAC_DBG, HALMAC_GPIO4, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0)}
+#define GPIO4_WLPHY_DBG_GPIO4_8822B	\
+	{HALMAC_WLPHY_DBG, HALMAC_GPIO4, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(1)}
+#define GPIO4_BT_DBG_GPIO4_8822B	\
+	{HALMAC_BT_DBG, HALMAC_GPIO4, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0) | BIT(1)}
+#define GPIO4_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO4, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO5 definition */
+#define GPIO5_BT_SPI_D1_8822B	\
+	{HALMAC_BT_SFLASH, HALMAC_GPIO5, HALMAC_GPIO_IN_OUT, \
+	 0x66, BIT(4), BIT(4)}
+#define GPIO5_WL_SPI_D1_8822B	\
+	{HALMAC_WL_SFLASH, HALMAC_GPIO5, HALMAC_GPIO_IN_OUT, \
+	 0x42, BIT(3), BIT(3)}
+#define GPIO5_JTAG_TDI_8822B	\
+	{HALMAC_JTAG, HALMAC_GPIO5, HALMAC_GPIO_IN, \
+	 0x67, BIT(0), BIT(0)}
+#define GPIO5_DBG_GNT_BT_8822B	\
+	{HALMAC_DBG_GNT_WL_BT, HALMAC_GPIO5, HALMAC_GPIO_OUT, \
+	 0x73, BIT(3), BIT(3)}
+#define GPIO5_WLMAC_DBG_GPIO5_8822B	\
+	{HALMAC_WLMAC_DBG, HALMAC_GPIO5, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0)}
+#define GPIO5_WLPHY_DBG_GPIO5_8822B	\
+	{HALMAC_WLPHY_DBG, HALMAC_GPIO5, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(1)}
+#define GPIO5_BT_DBG_GPIO5_8822B	\
+	{HALMAC_BT_DBG, HALMAC_GPIO5, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0) | BIT(1)}
+#define GPIO5_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO5, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO6 definition */
+#define GPIO6_BT_SPI_D2_8822B	\
+	{HALMAC_BT_SFLASH, HALMAC_GPIO6, HALMAC_GPIO_IN_OUT, \
+	 0x66, BIT(4), BIT(4)}
+#define GPIO6_WL_SPI_D2_8822B	\
+	{HALMAC_WL_SFLASH, HALMAC_GPIO6, HALMAC_GPIO_IN_OUT, \
+	 0x42, BIT(3), BIT(3)}
+#define GPIO6_EEDO_8822B	\
+	{HALMAC_EEPROM, HALMAC_GPIO6, HALMAC_GPIO_IN, \
+	 0x40, BIT(4), BIT(4)}
+#define GPIO6_JTAG_TDO_8822B	\
+	{HALMAC_JTAG, HALMAC_GPIO6, HALMAC_GPIO_OUT, \
+	 0x67, BIT(0), BIT(0)}
+#define GPIO6_BT_3DD_SYNC_B_8822B	\
+	{HALMAC_BT_3DDLS_B, HALMAC_GPIO6, HALMAC_GPIO_IN, \
+	 0x67, BIT(1), BIT(1)}
+#define GPIO6_BT_GPIO18_8822B	\
+	{HALMAC_BT_GPIO, HALMAC_GPIO6, HALMAC_GPIO_IN_OUT, \
+	 0x67, BIT(1), BIT(1)}
+#define GPIO6_SIN_8822B	\
+	{HALMAC_WL_UART, HALMAC_GPIO6, HALMAC_GPIO_IN, \
+	 0x41, BIT(0), BIT(0)}
+#define GPIO6_WLMAC_DBG_GPIO6_8822B	\
+	{HALMAC_WLMAC_DBG, HALMAC_GPIO6, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0)}
+#define GPIO6_WLPHY_DBG_GPIO6_8822B	\
+	{HALMAC_WLPHY_DBG, HALMAC_GPIO6, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(1)}
+#define GPIO6_BT_DBG_GPIO6_8822B	\
+	{HALMAC_BT_DBG, HALMAC_GPIO6, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0) | BIT(1)}
+#define GPIO6_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO6, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO7 definition */
+#define GPIO7_BT_SPI_D3_8822B	\
+	{HALMAC_BT_SFLASH, HALMAC_GPIO7, HALMAC_GPIO_IN_OUT, \
+	 0x66, BIT(4), BIT(4)}
+#define GPIO7_WL_SPI_D3_8822B	\
+	{HALMAC_WL_SFLASH, HALMAC_GPIO7, HALMAC_GPIO_IN_OUT, \
+	 0x42, BIT(3), BIT(3)}
+#define GPIO7_EEDI_8822B	\
+	{HALMAC_EEPROM, HALMAC_GPIO7, HALMAC_GPIO_OUT, \
+	 0x40, BIT(4), BIT(4)}
+#define GPIO7_JTAG_TMS_8822B	\
+	{HALMAC_JTAG, HALMAC_GPIO7, HALMAC_GPIO_IN, \
+	 0x67, BIT(0), BIT(0)}
+#define GPIO7_BT_GPIO16_8822B	\
+	{HALMAC_BT_GPIO, HALMAC_GPIO7, HALMAC_GPIO_IN_OUT, \
+	 0x67, BIT(2), BIT(2)}
+#define GPIO7_SOUT_8822B	\
+	{HALMAC_WL_UART, HALMAC_GPIO7, HALMAC_GPIO_OUT, \
+	 0x41, BIT(0), BIT(0)}
+#define GPIO7_WLMAC_DBG_GPIO7_8822B	\
+	{HALMAC_WLMAC_DBG, HALMAC_GPIO7, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0)}
+#define GPIO7_WLPHY_DBG_GPIO7_8822B	\
+	{HALMAC_WLPHY_DBG, HALMAC_GPIO7, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(1)}
+#define GPIO7_BT_DBG_GPIO7_8822B	\
+	{HALMAC_BT_DBG, HALMAC_GPIO7, HALMAC_GPIO_OUT, \
+	 0x40, BIT(1) | BIT(0), BIT(0) | BIT(1)}
+#define GPIO7_SW_IO_8822B \
+	{HALMAC_SW_IO, HALMAC_GPIO7, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO8 definition */
+#define GPIO8_WL_EXT_WOL_8822B	\
+	{HALMAC_WL_HW_EXTWOL, HALMAC_GPIO8, HALMAC_GPIO_IN, \
+	 0x4a, BIT(0) | BIT(1), BIT(0) | BIT(1)}
+#define GPIO8_WL_LED_8822B	\
+	{HALMAC_WL_LED, HALMAC_GPIO8, HALMAC_GPIO_OUT, \
+	 0x4e, BIT(5), BIT(5)}
+#define GPIO8_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO8, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO9 definition */
+#define GPIO9_DIS_WL_N_8822B	\
+	{HALMAC_WL_HWPDN, HALMAC_GPIO9, HALMAC_GPIO_IN, \
+	 0x68, BIT(3) | BIT(0), BIT(3) | BIT(0)}
+#define GPIO9_WL_EXT_WOL_8822B	\
+	{HALMAC_WL_HW_EXTWOL, HALMAC_GPIO9, HALMAC_GPIO_IN, \
+	 0x4a, BIT(0) | BIT(1), BIT(0)}
+#define GPIO9_USCTS0_8822B	\
+	{HALMAC_UART0, HALMAC_GPIO9, HALMAC_GPIO_IN, \
+	 0x66, BIT(6), BIT(6)}
+#define GPIO9_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO9, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO10 definition */
+#define GPIO10_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO10, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO11 definition */
+#define GPIO11_DIS_BT_N_8822B	\
+	{HALMAC_BT_HWPDN, HALMAC_GPIO11, HALMAC_GPIO_IN, \
+	 0x6a, BIT(0), BIT(0)}
+#define GPIO11_USOUT0_8822B	\
+	{HALMAC_UART0, HALMAC_GPIO11, HALMAC_GPIO_OUT, \
+	 0x66, BIT(6), BIT(6)}
+#define GPIO11_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO11, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO12 definition */
+#define GPIO12_USIN0_8822B	\
+	{HALMAC_UART0, HALMAC_GPIO12, HALMAC_GPIO_IN, \
+	 0x66, BIT(6), BIT(6)}
+#define GPIO12_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO12, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO13 definition */
+#define GPIO13_BT_WAKE_8822B	\
+	{HALMAC_GPIO13_14_WL_CTRL_EN, HALMAC_GPIO13, HALMAC_GPIO_IN, \
+	 0x4e, BIT(6), BIT(6)}
+#define GPIO13_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO13, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO14 definition */
+#define GPIO14_UART_WAKE_8822B	\
+	{HALMAC_GPIO13_14_WL_CTRL_EN, HALMAC_GPIO14, HALMAC_GPIO_OUT, \
+	 0x4e, BIT(6), BIT(6)}
+#define GPIO14_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO14, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+/* GPIO15 definition */
+#define GPIO15_EXT_XTAL_8822B	\
+	{HALMAC_EXT_XTAL, HALMAC_GPIO15, HALMAC_GPIO_OUT, \
+	 0x66, BIT(7), BIT(7)}
+#define GPIO15_SW_IO_8822B	\
+	{HALMAC_SW_IO, HALMAC_GPIO15, HALMAC_GPIO_IN_OUT, \
+	 0x40, BIT(1) | BIT(0), 0}
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO0_8822B[] = {
+	GPIO0_BT_GPIO0_8822B,
+	GPIO0_BT_ACT_8822B,
+	GPIO0_WL_ACT_8822B,
+	GPIO0_WLMAC_DBG_GPIO0_8822B,
+	GPIO0_WLPHY_DBG_GPIO0_8822B,
+	GPIO0_BT_DBG_GPIO0_8822B,
+	GPIO0_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO1_8822B[] = {
+	GPIO1_BT_GPIO1_8822B,
+	GPIO1_BT_3DD_SYNC_A_8822B,
+	GPIO1_WL_CK_8822B,
+	GPIO1_BT_CK_8822B,
+	GPIO1_WLMAC_DBG_GPIO1_8822B,
+	GPIO1_WLPHY_DBG_GPIO1_8822B,
+	GPIO1_BT_DBG_GPIO1_8822B,
+	GPIO1_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO2_8822B[] = {
+	GPIO2_BT_GPIO2_8822B,
+	GPIO2_WL_STATE_8822B,
+	GPIO2_BT_STATE_8822B,
+	GPIO2_WLMAC_DBG_GPIO2_8822B,
+	GPIO2_WLPHY_DBG_GPIO2_8822B,
+	GPIO2_BT_DBG_GPIO2_8822B,
+	GPIO2_RFE_CTRL_5_8822B,
+	GPIO2_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO3_8822B[] = {
+	GPIO3_BT_GPIO3_8822B,
+	GPIO3_WL_PRI_8822B,
+	GPIO3_BT_PRI_8822B,
+	GPIO3_WLMAC_DBG_GPIO3_8822B,
+	GPIO3_WLPHY_DBG_GPIO3_8822B,
+	GPIO3_BT_DBG_GPIO3_8822B,
+	GPIO3_RFE_CTRL_4_8822B,
+	GPIO3_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO4_8822B[] = {
+	GPIO4_BT_SPI_D0_8822B,
+	GPIO4_WL_SPI_D0_8822B,
+	GPIO4_SDIO_INT_8822B,
+	GPIO4_JTAG_TRST_8822B,
+	GPIO4_DBG_GNT_WL_8822B,
+	GPIO4_WLMAC_DBG_GPIO4_8822B,
+	GPIO4_WLPHY_DBG_GPIO4_8822B,
+	GPIO4_BT_DBG_GPIO4_8822B,
+	GPIO4_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO5_8822B[] = {
+	GPIO5_BT_SPI_D1_8822B,
+	GPIO5_WL_SPI_D1_8822B,
+	GPIO5_JTAG_TDI_8822B,
+	GPIO5_DBG_GNT_BT_8822B,
+	GPIO5_WLMAC_DBG_GPIO5_8822B,
+	GPIO5_WLPHY_DBG_GPIO5_8822B,
+	GPIO5_BT_DBG_GPIO5_8822B,
+	GPIO5_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO6_8822B[] = {
+	GPIO6_BT_SPI_D2_8822B,
+	GPIO6_WL_SPI_D2_8822B,
+	GPIO6_EEDO_8822B,
+	GPIO6_JTAG_TDO_8822B,
+	GPIO6_BT_3DD_SYNC_B_8822B,
+	GPIO6_BT_GPIO18_8822B,
+	GPIO6_SIN_8822B,
+	GPIO6_WLMAC_DBG_GPIO6_8822B,
+	GPIO6_WLPHY_DBG_GPIO6_8822B,
+	GPIO6_BT_DBG_GPIO6_8822B,
+	GPIO6_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO7_8822B[] = {
+	GPIO7_BT_SPI_D3_8822B,
+	GPIO7_WL_SPI_D3_8822B,
+	GPIO7_EEDI_8822B,
+	GPIO7_JTAG_TMS_8822B,
+	GPIO7_BT_GPIO16_8822B,
+	GPIO7_SOUT_8822B,
+	GPIO7_WLMAC_DBG_GPIO7_8822B,
+	GPIO7_WLPHY_DBG_GPIO7_8822B,
+	GPIO7_BT_DBG_GPIO7_8822B,
+	GPIO7_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO8_8822B[] = {
+	GPIO8_WL_EXT_WOL_8822B,
+	GPIO8_WL_LED_8822B,
+	GPIO8_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO9_8822B[] = {
+	GPIO9_DIS_WL_N_8822B,
+	GPIO9_WL_EXT_WOL_8822B,
+	GPIO9_USCTS0_8822B,
+	GPIO9_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO10_8822B[] = {
+	GPIO10_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO11_8822B[] = {
+	GPIO11_DIS_BT_N_8822B,
+	GPIO11_USOUT0_8822B,
+	GPIO11_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO12_8822B[] = {
+	GPIO12_USIN0_8822B,
+	GPIO12_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO13_8822B[] = {
+	GPIO13_BT_WAKE_8822B,
+	GPIO13_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO14_8822B[] = {
+	GPIO14_UART_WAKE_8822B,
+	GPIO14_SW_IO_8822B
+};
+
+static const struct halmac_gpio_pimux_list PINMUX_LIST_GPIO15_8822B[] = {
+	GPIO15_EXT_XTAL_8822B,
+	GPIO15_SW_IO_8822B
+};
+
+static enum halmac_ret_status
+get_pinmux_list_8822b(struct halmac_adapter *adapter,
+		      enum halmac_gpio_func gpio_func,
+		      const struct halmac_gpio_pimux_list **list,
+		      u32 *list_size, u32 *gpio_id);
+
+static enum halmac_ret_status
+chk_pinmux_valid_8822b(struct halmac_adapter *adapter,
+		       enum halmac_gpio_func gpio_func);
+
+/**
+ * pinmux_get_func_8822b() -get current gpio status
+ * @adapter : the adapter of halmac
+ * @gpio_func : gpio function
+ * @enable : function is enable(1) or disable(0)
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pinmux_get_func_8822b(struct halmac_adapter *adapter,
+		      enum halmac_gpio_func gpio_func, u8 *enable)
+{
+	u32 list_size;
+	u32 cur_func;
+	u32 gpio_id;
+	enum halmac_ret_status status;
+	const struct halmac_gpio_pimux_list *list = NULL;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = get_pinmux_list_8822b(adapter, gpio_func, &list, &list_size,
+				       &gpio_id);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	status = pinmux_parser_88xx(adapter, list, list_size, gpio_id,
+				    &cur_func);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	switch (gpio_func) {
+	case HALMAC_GPIO_FUNC_WL_LED:
+		*enable = (cur_func == HALMAC_WL_LED) ? 1 : 0;
+		break;
+	case HALMAC_GPIO_FUNC_SDIO_INT:
+		*enable = (cur_func == HALMAC_SDIO_INT) ? 1 : 0;
+		break;
+	case HALMAC_GPIO_FUNC_BT_HOST_WAKE1:
+	case HALMAC_GPIO_FUNC_BT_DEV_WAKE1:
+		*enable = (cur_func == HALMAC_GPIO13_14_WL_CTRL_EN) ? 1 : 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_0:
+	case HALMAC_GPIO_FUNC_SW_IO_1:
+	case HALMAC_GPIO_FUNC_SW_IO_2:
+	case HALMAC_GPIO_FUNC_SW_IO_3:
+	case HALMAC_GPIO_FUNC_SW_IO_4:
+	case HALMAC_GPIO_FUNC_SW_IO_5:
+	case HALMAC_GPIO_FUNC_SW_IO_6:
+	case HALMAC_GPIO_FUNC_SW_IO_7:
+	case HALMAC_GPIO_FUNC_SW_IO_8:
+	case HALMAC_GPIO_FUNC_SW_IO_9:
+	case HALMAC_GPIO_FUNC_SW_IO_10:
+	case HALMAC_GPIO_FUNC_SW_IO_11:
+	case HALMAC_GPIO_FUNC_SW_IO_12:
+	case HALMAC_GPIO_FUNC_SW_IO_13:
+	case HALMAC_GPIO_FUNC_SW_IO_14:
+	case HALMAC_GPIO_FUNC_SW_IO_15:
+		*enable = (cur_func == HALMAC_SW_IO) ? 1 : 0;
+		break;
+	default:
+		*enable = 0;
+		return HALMAC_RET_GET_PINMUX_ERR;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * pinmux_set_func_8822b() -set gpio function
+ * @adapter : the adapter of halmac
+ * @gpio_func : gpio function
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pinmux_set_func_8822b(struct halmac_adapter *adapter,
+		      enum halmac_gpio_func gpio_func)
+{
+	u32 list_size;
+	u32 gpio_id;
+	enum halmac_ret_status status;
+	const struct halmac_gpio_pimux_list *list = NULL;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "func name : %d\n", gpio_func);
+
+	status = chk_pinmux_valid_8822b(adapter, gpio_func);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	status = get_pinmux_list_8822b(adapter, gpio_func, &list, &list_size,
+				       &gpio_id);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	status = pinmux_switch_88xx(adapter, list, list_size, gpio_id,
+				    gpio_func);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	status = pinmux_record_88xx(adapter, gpio_func, 1);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * pinmux_free_func_8822b() -free locked gpio function
+ * @adapter : the adapter of halmac
+ * @gpio_func : gpio function
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pinmux_free_func_8822b(struct halmac_adapter *adapter,
+		       enum halmac_gpio_func gpio_func)
+{
+	struct halmac_pinmux_info *info = &adapter->pinmux_info;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	switch (gpio_func) {
+	case HALMAC_GPIO_FUNC_SW_IO_0:
+		info->sw_io_0 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_1:
+		info->sw_io_1 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_2:
+		info->sw_io_2 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_3:
+		info->sw_io_3 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_4:
+	case HALMAC_GPIO_FUNC_SDIO_INT:
+		info->sw_io_4 = 0;
+		info->sdio_int = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_5:
+		info->sw_io_5 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_6:
+		info->sw_io_6 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_7:
+		info->sw_io_7 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_8:
+	case HALMAC_GPIO_FUNC_WL_LED:
+		info->sw_io_8 = 0;
+		info->wl_led = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_9:
+		info->sw_io_9 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_10:
+		info->sw_io_10 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_11:
+		info->sw_io_11 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_12:
+		info->sw_io_12 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_13:
+	case HALMAC_GPIO_FUNC_BT_DEV_WAKE1:
+		info->bt_dev_wake = 0;
+		info->sw_io_13 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_14:
+	case HALMAC_GPIO_FUNC_BT_HOST_WAKE1:
+		info->bt_host_wake = 0;
+		info->sw_io_14 = 0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_15:
+		info->sw_io_15 = 0;
+		break;
+	default:
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "func : %X\n",
+		 gpio_func);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+get_pinmux_list_8822b(struct halmac_adapter *adapter,
+		      enum halmac_gpio_func gpio_func,
+		      const struct halmac_gpio_pimux_list **list,
+		      u32 *list_size, u32 *gpio_id)
+{
+	switch (gpio_func) {
+	case HALMAC_GPIO_FUNC_SW_IO_0:
+		*list = PINMUX_LIST_GPIO0_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO0_8822B);
+		*gpio_id = HALMAC_GPIO0;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_1:
+		*list = PINMUX_LIST_GPIO1_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO1_8822B);
+		*gpio_id = HALMAC_GPIO1;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_2:
+		*list = PINMUX_LIST_GPIO2_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO2_8822B);
+		*gpio_id = HALMAC_GPIO2;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_3:
+		*list = PINMUX_LIST_GPIO3_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO3_8822B);
+		*gpio_id = HALMAC_GPIO3;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_4:
+	case HALMAC_GPIO_FUNC_SDIO_INT:
+		*list = PINMUX_LIST_GPIO4_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO4_8822B);
+		*gpio_id = HALMAC_GPIO4;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_5:
+		*list = PINMUX_LIST_GPIO5_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO5_8822B);
+		*gpio_id = HALMAC_GPIO5;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_6:
+		*list = PINMUX_LIST_GPIO6_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO6_8822B);
+		*gpio_id = HALMAC_GPIO6;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_7:
+		*list = PINMUX_LIST_GPIO7_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO7_8822B);
+		*gpio_id = HALMAC_GPIO7;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_8:
+	case HALMAC_GPIO_FUNC_WL_LED:
+		*list = PINMUX_LIST_GPIO8_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO8_8822B);
+		*gpio_id = HALMAC_GPIO8;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_9:
+		*list = PINMUX_LIST_GPIO9_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO9_8822B);
+		*gpio_id = HALMAC_GPIO9;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_10:
+		*list = PINMUX_LIST_GPIO10_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO10_8822B);
+		*gpio_id = HALMAC_GPIO10;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_11:
+		*list = PINMUX_LIST_GPIO11_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO11_8822B);
+		*gpio_id = HALMAC_GPIO11;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_12:
+		*list = PINMUX_LIST_GPIO12_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO12_8822B);
+		*gpio_id = HALMAC_GPIO12;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_13:
+	case HALMAC_GPIO_FUNC_BT_DEV_WAKE1:
+		*list = PINMUX_LIST_GPIO13_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO13_8822B);
+		*gpio_id = HALMAC_GPIO13;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_14:
+	case HALMAC_GPIO_FUNC_BT_HOST_WAKE1:
+		*list = PINMUX_LIST_GPIO14_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO14_8822B);
+		*gpio_id = HALMAC_GPIO14;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_15:
+		*list = PINMUX_LIST_GPIO15_8822B;
+		*list_size = ARRAY_SIZE(PINMUX_LIST_GPIO15_8822B);
+		*gpio_id = HALMAC_GPIO15;
+		break;
+	default:
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+chk_pinmux_valid_8822b(struct halmac_adapter *adapter,
+		       enum halmac_gpio_func gpio_func)
+{
+	struct halmac_pinmux_info *info = &adapter->pinmux_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	switch (gpio_func) {
+	case HALMAC_GPIO_FUNC_SW_IO_0:
+		if (info->sw_io_0 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_1:
+		if (info->sw_io_1 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_2:
+		if (info->sw_io_2 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_3:
+		if (info->sw_io_3 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_4:
+	case HALMAC_GPIO_FUNC_SDIO_INT:
+		if (info->sw_io_4 == 1 || info->sdio_int == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_5:
+		if (info->sw_io_5 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_6:
+		if (info->sw_io_6 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_7:
+		if (info->sw_io_7 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_8:
+	case HALMAC_GPIO_FUNC_WL_LED:
+		if (info->sw_io_8 == 1 || info->wl_led == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_9:
+		if (info->sw_io_9 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_10:
+		if (info->sw_io_10 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_11:
+		if (info->sw_io_11 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_12:
+		if (info->sw_io_12 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_13:
+	case HALMAC_GPIO_FUNC_BT_DEV_WAKE1:
+		if (info->sw_io_13 == 1 || info->bt_dev_wake == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_14:
+	case HALMAC_GPIO_FUNC_BT_HOST_WAKE1:
+		if (info->sw_io_14 == 1 || info->bt_host_wake == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_15:
+		if (info->sw_io_15 == 1)
+			status = HALMAC_RET_PINMUX_USED;
+		break;
+	default:
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "chk_pinmux_valid func : %X status : %X\n", gpio_func, status);
+
+	return status;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.h
new file mode 100644
index 000000000000..f5d6d315ac3c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_gpio_8822b.h
@@ -0,0 +1,34 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_GPIO_8822B_H_
+#define _HALMAC_GPIO_8822B_H_
+
+#include "../../halmac_api.h"
+#include "../../halmac_gpio_cmd.h"
+
+enum halmac_ret_status
+pinmux_get_func_8822b(struct halmac_adapter *adapter,
+		      enum halmac_gpio_func gpio_func, u8 *enable);
+
+enum halmac_ret_status
+pinmux_set_func_8822b(struct halmac_adapter *adapter,
+		      enum halmac_gpio_func gpio_func);
+
+enum halmac_ret_status
+pinmux_free_func_8822b(struct halmac_adapter *adapter,
+		       enum halmac_gpio_func gpio_func);
+
+#endif/* _HALMAC_GPIO_8822B_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.c
new file mode 100644
index 000000000000..f95add244d47
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.c
@@ -0,0 +1,415 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_gpio_88xx.h"
+
+/**
+ * pinmux_wl_led_mode_88xx() -control wlan led gpio function
+ * @adapter : the adapter of halmac
+ * @mode : wlan led mode
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pinmux_wl_led_mode_88xx(struct halmac_adapter *adapter,
+			enum halmac_wlled_mode mode)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	value8 = HALMAC_REG_R8(REG_LED_CFG + 2);
+	value8 &= ~(BIT(6));
+	value8 |= BIT(3);
+	value8 &= ~(BIT(0) | BIT(1) | BIT(2));
+
+	switch (mode) {
+	case HALMAC_WLLED_MODE_TRX:
+		value8 |= 2;
+		break;
+	case HALMAC_WLLED_MODE_TX:
+		value8 |= 4;
+		break;
+	case HALMAC_WLLED_MODE_RX:
+		value8 |= 6;
+		break;
+	case HALMAC_WLLED_MODE_SW_CTRL:
+		value8 |= 0;
+		break;
+	default:
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	HALMAC_REG_W8(REG_LED_CFG + 2, value8);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * pinmux_wl_led_sw_ctrl_88xx() -control wlan led on/off
+ * @adapter : the adapter of halmac
+ * @on : on(1), off(0)
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+void
+pinmux_wl_led_sw_ctrl_88xx(struct halmac_adapter *adapter, u8 on)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	value8 = HALMAC_REG_R8(REG_LED_CFG + 2);
+	value8 = (on == 0) ? value8 | BIT(3) : value8 & ~(BIT(3));
+
+	HALMAC_REG_W8(REG_LED_CFG + 2, value8);
+}
+
+/**
+ * pinmux_sdio_int_polarity_88xx() -control sdio int polarity
+ * @adapter : the adapter of halmac
+ * @low_active : low active(1), high active(0)
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+void
+pinmux_sdio_int_polarity_88xx(struct halmac_adapter *adapter, u8 low_active)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	value8 = HALMAC_REG_R8(REG_SYS_SDIO_CTRL + 2);
+	value8 = (low_active == 0) ? value8 | BIT(3) : value8 & ~(BIT(3));
+
+	HALMAC_REG_W8(REG_SYS_SDIO_CTRL + 2, value8);
+}
+
+/**
+ * pinmux_gpio_mode_88xx() -control gpio io mode
+ * @adapter : the adapter of halmac
+ * @gpio_id : gpio0~15(0~15)
+ * @output : output(1), input(0)
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pinmux_gpio_mode_88xx(struct halmac_adapter *adapter, u8 gpio_id, u8 output)
+{
+	u16 value16;
+	u8 in_out;
+	u32 offset;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (gpio_id <= 7)
+		offset = REG_GPIO_PIN_CTRL + 2;
+	else if (gpio_id >= 8 && gpio_id <= 15)
+		offset = REG_GPIO_EXT_CTRL + 2;
+	else
+		return HALMAC_RET_WRONG_GPIO;
+
+	in_out = (output == 0) ? 0 : 1;
+	gpio_id &= (8 - 1);
+
+	value16 = HALMAC_REG_R16(offset);
+	value16 &= ~((1 << gpio_id) | (1 << gpio_id << 8));
+	value16 |= (in_out << gpio_id);
+	HALMAC_REG_W16(offset, value16);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * pinmux_gpio_output_88xx() -control gpio output high/low
+ * @adapter : the adapter of halmac
+ * @gpio_id : gpio0~15(0~15)
+ * @high : high(1), low(0)
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pinmux_gpio_output_88xx(struct halmac_adapter *adapter, u8 gpio_id, u8 high)
+{
+	u8 value8;
+	u8 hi_low;
+	u32 offset;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (gpio_id <= 7)
+		offset = REG_GPIO_PIN_CTRL + 1;
+	else if (gpio_id >= 8 && gpio_id <= 15)
+		offset = REG_GPIO_EXT_CTRL + 1;
+	else
+		return HALMAC_RET_WRONG_GPIO;
+
+	hi_low = (high == 0) ? 0 : 1;
+	gpio_id &= (8 - 1);
+
+	value8 = HALMAC_REG_R8(offset);
+	value8 &= ~(1 << gpio_id);
+	value8 |= (hi_low << gpio_id);
+	HALMAC_REG_W8(offset, value8);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_pinmux_status_88xx() -get current gpio status(high/low)
+ * @adapter : the adapter of halmac
+ * @pin_id : 0~15(0~15)
+ * @phigh : high(1), low(0)
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pinmux_pin_status_88xx(struct halmac_adapter *adapter, u8 pin_id, u8 *high)
+{
+	u8 value8;
+	u32 offset;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (pin_id <= 7)
+		offset = REG_GPIO_PIN_CTRL;
+	else if (pin_id >= 8 && pin_id <= 15)
+		offset = REG_GPIO_EXT_CTRL;
+	else
+		return HALMAC_RET_WRONG_GPIO;
+
+	pin_id &= (8 - 1);
+
+	value8 = HALMAC_REG_R8(offset);
+	*high = (value8 & (1 << pin_id)) >> pin_id;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+pinmux_parser_88xx(struct halmac_adapter *adapter,
+		   const struct halmac_gpio_pimux_list *list, u32 size,
+		   u32 gpio_id, u32 *cur_func)
+{
+	u32 i;
+	u8 value8;
+	const struct halmac_gpio_pimux_list *cur_list = list;
+	enum halmac_gpio_cfg_state *state;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	state = &adapter->halmac_state.gpio_cfg_state;
+
+	if (*state == HALMAC_GPIO_CFG_STATE_BUSY)
+		return HALMAC_RET_BUSY_STATE;
+
+	*state = HALMAC_GPIO_CFG_STATE_BUSY;
+
+	for (i = 0; i < size; i++) {
+		if (gpio_id != cur_list->id) {
+			pr_err("offset:%X, value:%X, func:%X\n",
+			       cur_list->offset, cur_list->value,
+			       cur_list->func);
+			pr_err("id1 : %X, id2 : %X\n", gpio_id, cur_list->id);
+			*state = HALMAC_GPIO_CFG_STATE_IDLE;
+			return HALMAC_RET_GET_PINMUX_ERR;
+		}
+		value8 = HALMAC_REG_R8(cur_list->offset);
+		value8 &= cur_list->msk;
+		if (value8 == cur_list->value) {
+			*cur_func = cur_list->func;
+			break;
+		}
+		cur_list++;
+	}
+
+	*state = HALMAC_GPIO_CFG_STATE_IDLE;
+
+	if (i == size)
+		return HALMAC_RET_GET_PINMUX_ERR;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+pinmux_switch_88xx(struct halmac_adapter *adapter,
+		   const struct halmac_gpio_pimux_list *list, u32 size,
+		   u32 gpio_id, enum halmac_gpio_func gpio_func)
+{
+	u32 i;
+	u8 value8;
+	u16 switch_func;
+	const struct halmac_gpio_pimux_list *cur_list = list;
+	enum halmac_gpio_cfg_state *state;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	state = &adapter->halmac_state.gpio_cfg_state;
+
+	if (*state == HALMAC_GPIO_CFG_STATE_BUSY)
+		return HALMAC_RET_BUSY_STATE;
+
+	switch (gpio_func) {
+	case HALMAC_GPIO_FUNC_WL_LED:
+		switch_func = HALMAC_WL_LED;
+		break;
+	case HALMAC_GPIO_FUNC_SDIO_INT:
+		switch_func = HALMAC_SDIO_INT;
+		break;
+	case HALMAC_GPIO_FUNC_BT_HOST_WAKE1:
+	case HALMAC_GPIO_FUNC_BT_DEV_WAKE1:
+		switch_func = HALMAC_GPIO13_14_WL_CTRL_EN;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_0:
+	case HALMAC_GPIO_FUNC_SW_IO_1:
+	case HALMAC_GPIO_FUNC_SW_IO_2:
+	case HALMAC_GPIO_FUNC_SW_IO_3:
+	case HALMAC_GPIO_FUNC_SW_IO_4:
+	case HALMAC_GPIO_FUNC_SW_IO_5:
+	case HALMAC_GPIO_FUNC_SW_IO_6:
+	case HALMAC_GPIO_FUNC_SW_IO_7:
+	case HALMAC_GPIO_FUNC_SW_IO_8:
+	case HALMAC_GPIO_FUNC_SW_IO_9:
+	case HALMAC_GPIO_FUNC_SW_IO_10:
+	case HALMAC_GPIO_FUNC_SW_IO_11:
+	case HALMAC_GPIO_FUNC_SW_IO_12:
+	case HALMAC_GPIO_FUNC_SW_IO_13:
+	case HALMAC_GPIO_FUNC_SW_IO_14:
+	case HALMAC_GPIO_FUNC_SW_IO_15:
+		switch_func = HALMAC_SW_IO;
+		break;
+	default:
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	for (i = 0; i < size; i++) {
+		if (gpio_id != cur_list->id) {
+			pr_err("offset:%X, value:%X, func:%X\n",
+			       cur_list->offset, cur_list->value,
+			       cur_list->func);
+			pr_err("id1 : %X, id2 : %X\n", gpio_id, cur_list->id);
+			return HALMAC_RET_GET_PINMUX_ERR;
+		}
+
+		if (switch_func == cur_list->func)
+			break;
+
+		cur_list++;
+	}
+
+	if (i == size) {
+		pr_err("gpio func error:%X %X\n", gpio_id, cur_list->id);
+		return HALMAC_RET_GET_PINMUX_ERR;
+	}
+
+	*state = HALMAC_GPIO_CFG_STATE_BUSY;
+
+	cur_list = list;
+	for (i = 0; i < size; i++) {
+		value8 = HALMAC_REG_R8(cur_list->offset);
+		value8 &= ~(cur_list->msk);
+
+		if (switch_func == cur_list->func) {
+			value8 |= (cur_list->value & cur_list->msk);
+			HALMAC_REG_W8(cur_list->offset, value8);
+			break;
+		}
+
+		value8 |= (~cur_list->value & cur_list->msk);
+		HALMAC_REG_W8(cur_list->offset, value8);
+
+		cur_list++;
+	}
+
+	*state = HALMAC_GPIO_CFG_STATE_IDLE;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+pinmux_record_88xx(struct halmac_adapter *adapter,
+		   enum halmac_gpio_func gpio_func, u8 val)
+{
+	switch (gpio_func) {
+	case HALMAC_GPIO_FUNC_WL_LED:
+		adapter->pinmux_info.wl_led = val;
+		break;
+	case HALMAC_GPIO_FUNC_SDIO_INT:
+		adapter->pinmux_info.sdio_int = val;
+		break;
+	case HALMAC_GPIO_FUNC_BT_HOST_WAKE1:
+		adapter->pinmux_info.bt_host_wake = val;
+		break;
+	case HALMAC_GPIO_FUNC_BT_DEV_WAKE1:
+		adapter->pinmux_info.bt_dev_wake = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_0:
+		adapter->pinmux_info.sw_io_0 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_1:
+		adapter->pinmux_info.sw_io_1 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_2:
+		adapter->pinmux_info.sw_io_2 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_3:
+		adapter->pinmux_info.sw_io_3 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_4:
+		adapter->pinmux_info.sw_io_4 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_5:
+		adapter->pinmux_info.sw_io_5 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_6:
+		adapter->pinmux_info.sw_io_6 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_7:
+		adapter->pinmux_info.sw_io_7 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_8:
+		adapter->pinmux_info.sw_io_8 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_9:
+		adapter->pinmux_info.sw_io_9 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_10:
+		adapter->pinmux_info.sw_io_10 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_11:
+		adapter->pinmux_info.sw_io_11 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_12:
+		adapter->pinmux_info.sw_io_12 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_13:
+		adapter->pinmux_info.sw_io_13 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_14:
+		adapter->pinmux_info.sw_io_14 = val;
+		break;
+	case HALMAC_GPIO_FUNC_SW_IO_15:
+		adapter->pinmux_info.sw_io_15 = val;
+		break;
+	default:
+		return HALMAC_RET_GET_PINMUX_ERR;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.h
new file mode 100644
index 000000000000..2b6b5ce345f4
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_gpio_88xx.h
@@ -0,0 +1,55 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_GPIO_88XX_H_
+#define _HALMAC_GPIO_88XX_H_
+
+#include "../halmac_api.h"
+#include "../halmac_gpio_cmd.h"
+
+enum halmac_ret_status
+pinmux_wl_led_mode_88xx(struct halmac_adapter *adapter,
+			enum halmac_wlled_mode mode);
+
+void
+pinmux_wl_led_sw_ctrl_88xx(struct halmac_adapter *adapter, u8 on);
+
+void
+pinmux_sdio_int_polarity_88xx(struct halmac_adapter *adapter, u8 low_active);
+
+enum halmac_ret_status
+pinmux_gpio_mode_88xx(struct halmac_adapter *adapter, u8 gpio_id, u8 output);
+
+enum halmac_ret_status
+pinmux_gpio_output_88xx(struct halmac_adapter *adapter, u8 gpio_id, u8 high);
+
+enum halmac_ret_status
+pinmux_pin_status_88xx(struct halmac_adapter *adapter, u8 pin_id, u8 *high);
+
+enum halmac_ret_status
+pinmux_parser_88xx(struct halmac_adapter *adapter,
+		   const struct halmac_gpio_pimux_list *list, u32 size,
+		   u32 gpio_id, u32 *cur_func);
+
+enum halmac_ret_status
+pinmux_switch_88xx(struct halmac_adapter *adapter,
+		   const struct halmac_gpio_pimux_list *list, u32 size,
+		   u32 gpio_id, enum halmac_gpio_func gpio_func);
+
+enum halmac_ret_status
+pinmux_record_88xx(struct halmac_adapter *adapter,
+		   enum halmac_gpio_func gpio_func, u8 val);
+
+#endif/* _HALMAC_GPIO_88XX_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_gpio_cmd.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_gpio_cmd.h
new file mode 100644
index 000000000000..92283350083a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_gpio_cmd.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef HALMAC_GPIO_CMD
+#define HALMAC_GPIO_CMD
+
+#include "../wifi.h"
+
+/* GPIO ID */
+#define HALMAC_GPIO0		0
+#define HALMAC_GPIO1		1
+#define HALMAC_GPIO2		2
+#define HALMAC_GPIO3		3
+#define HALMAC_GPIO4		4
+#define HALMAC_GPIO5		5
+#define HALMAC_GPIO6		6
+#define HALMAC_GPIO7		7
+#define HALMAC_GPIO8		8
+#define HALMAC_GPIO9		9
+#define HALMAC_GPIO10		10
+#define HALMAC_GPIO11		11
+#define HALMAC_GPIO12		12
+#define HALMAC_GPIO13		13
+#define HALMAC_GPIO14		14
+#define HALMAC_GPIO15		15
+#define HALMAC_GPIO_NUM		16
+
+/* GPIO type */
+#define HALMAC_GPIO_IN		0
+#define HALMAC_GPIO_OUT		1
+#define HALMAC_GPIO_IN_OUT	2
+
+/* Function name */
+#define HALMAC_WL_HWPDN			0
+#define HALMAC_BT_HWPDN			1
+#define HALMAC_BT_GPIO			2
+#define HALMAC_WL_HW_EXTWOL		3
+#define HALMAC_BT_HW_EXTWOL		4
+#define HALMAC_BT_SFLASH		5
+#define HALMAC_WL_SFLASH		6
+#define HALMAC_WL_LED			7
+#define HALMAC_SDIO_INT			8
+#define HALMAC_UART0			9
+#define HALMAC_EEPROM			10
+#define HALMAC_JTAG			11
+#define HALMAC_LTE_COEX_UART		12
+#define HALMAC_3W_LTE_WL_GPIO		13
+#define HALMAC_GPIO2_3_WL_CTRL_EN	14
+#define HALMAC_GPIO13_14_WL_CTRL_EN	15
+#define HALMAC_DBG_GNT_WL_BT		16
+#define HALMAC_BT_3DDLS_A		17
+#define HALMAC_BT_3DDLS_B		18
+#define HALMAC_BT_PTA			19
+#define HALMAC_WL_PTA			20
+#define HALMAC_WL_UART			21
+#define HALMAC_WLMAC_DBG		22
+#define HALMAC_WLPHY_DBG		23
+#define HALMAC_BT_DBG			24
+#define HALMAC_WLPHY_RFE_CTRL2GPIO	25
+#define HALMAC_EXT_XTAL			26
+#define HALMAC_SW_IO			27
+
+struct halmac_gpio_pimux_list {
+	u16 func;
+	u8 id;
+	u8 type;
+	u16 offset;
+	u8 msk;
+	u8 value;
+};
+
+#endif
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 09/17] rtlwifi: halmac: add power sequence to turn on/off wifi card
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (6 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 08/17] rtlwifi: halmac: add GPIO pin/pinmux definitions pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 10/17] rtlwifi: halmac: access efuse through halmac helper functions pkshih
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

Define power sequence command, and fill the sequences of 8822b.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../halmac_8822b/halmac_pwr_seq_8822b.c            | 396 +++++++++++++++++++++
 .../halmac_8822b/halmac_pwr_seq_8822b.h            |  26 ++
 .../realtek/rtlwifi/halmac/halmac_pwr_seq_cmd.h    |  98 +++++
 3 files changed, 520 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pwr_seq_cmd.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c
new file mode 100644
index 000000000000..5aab588eb094
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.c
@@ -0,0 +1,396 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_pwr_seq_8822b.h"
+
+static struct halmac_wlan_pwr_cfg TRANS_CARDDIS_TO_CARDEMU_8822B[] = {
+	/* { offset, cut_msk, interface_msk, base|cmd, msk, value } */
+	{0x0086,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_SDIO,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), 0},
+	{0x0086,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_SDIO,
+	 HALMAC_PWR_CMD_POLLING, BIT(1), BIT(1)},
+	{0x004A,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), 0},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0},
+	{0x0300,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_PCI_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0},
+	{0x0301,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_PCI_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0},
+	{0xFFFF,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 0,
+	 HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wlan_pwr_cfg TRANS_CARDEMU_TO_ACT_8822B[] = {
+	/* { offset, cut_msk, interface_msk, base|cmd, msk, value } */
+	{0x0012,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(1), 0},
+	{0x0012,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), BIT(0)},
+	{0x0020,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), BIT(0)},
+	{0x0001,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_DELAY, 1, HALMAC_PWR_DELAY_MS},
+	{0x0000,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(5), 0},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
+	{0x0075,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_PCI_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), BIT(0)},
+	{0x0006,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_POLLING, BIT(1), BIT(1)},
+	{0x0075,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_PCI_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), 0},
+	{0xFF1A,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0},
+	{0x0006,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), BIT(0)},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(7), 0},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},
+	{0x10C3,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), BIT(0)},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), BIT(0)},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_POLLING, BIT(0), 0},
+	{0x0020,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(3), BIT(3)},
+	{0x10A8,
+	 HALMAC_PWR_CUT_C_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0},
+	{0x10A9,
+	 HALMAC_PWR_CUT_C_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0xef},
+	{0x10AA,
+	 HALMAC_PWR_CUT_C_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0x0c},
+	{0x0068,
+	 HALMAC_PWR_CUT_C_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(4), BIT(4)},
+	{0x0029,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0xF9},
+	{0x0024,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(2), 0},
+	{0x0074,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_PCI_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(5), BIT(5)},
+	{0x00AF,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(5), BIT(5)},
+	{0xFFFF,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 0,
+	 HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wlan_pwr_cfg TRANS_ACT_TO_CARDEMU_8822B[] = {
+	/* { offset, cut_msk, interface_msk, base|cmd, msk, value } */
+	{0x0003,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(2), 0},
+	{0x0093,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(3), 0},
+	{0x001F,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0},
+	{0x00EF,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0},
+	{0xFF1A,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0x30},
+	{0x0049,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(1), 0},
+	{0x0006,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), BIT(0)},
+	{0x0002,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(1), 0},
+	{0x10C3,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), 0},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(1), BIT(1)},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_POLLING, BIT(1), 0},
+	{0x0020,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(3), 0},
+	{0x0000,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(5), BIT(5)},
+	{0xFFFF,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 0,
+	 HALMAC_PWR_CMD_END, 0, 0},
+};
+
+static struct halmac_wlan_pwr_cfg TRANS_CARDEMU_TO_CARDDIS_8822B[] = {
+	/* { offset, cut_msk, interface_msk, base|cmd, msk, value } */
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(7), BIT(7)},
+	{0x0007,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0x20},
+	{0x0067,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(5), 0},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
+	{0x0005,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_PCI_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(2), BIT(2)},
+	{0x004A,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), 0},
+	{0x0067,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(5), 0},
+	{0x0067,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(4), 0},
+	{0x004F,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), 0},
+	{0x0067,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(1), 0},
+	{0x0046,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(6), BIT(6)},
+	{0x0067,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(2), 0},
+	{0x0046,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(7), BIT(7)},
+	{0x0062,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(4), BIT(4)},
+	{0x0081,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(7), 0},
+	{0x0086,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_SDIO,
+	 HALMAC_PWR_CMD_WRITE, BIT(0), BIT(0)},
+	{0x0086,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_SDIO,
+	 HALMAC_PWR_CMD_POLLING, BIT(1), 0},
+	{0x0090,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_USB_MSK | HALMAC_PWR_INTF_PCI_MSK,
+	 HALMAC_PWR_ADDR_MAC,
+	 HALMAC_PWR_CMD_WRITE, BIT(1), 0},
+	{0x0044,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_SDIO,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0},
+	{0x0040,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_SDIO,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0x90},
+	{0x0041,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_SDIO,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0x00},
+	{0x0042,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_SDIO_MSK,
+	 HALMAC_PWR_ADDR_SDIO,
+	 HALMAC_PWR_CMD_WRITE, 0xFF, 0x04},
+	{0xFFFF,
+	 HALMAC_PWR_CUT_ALL_MSK,
+	 HALMAC_PWR_INTF_ALL_MSK,
+	 0,
+	 HALMAC_PWR_CMD_END, 0, 0},
+};
+
+/* Card Enable Array */
+struct halmac_wlan_pwr_cfg *card_en_flow_8822b[] = {
+	TRANS_CARDDIS_TO_CARDEMU_8822B,
+	TRANS_CARDEMU_TO_ACT_8822B,
+	NULL
+};
+
+/* Card Disable Array */
+struct halmac_wlan_pwr_cfg *card_dis_flow_8822b[] = {
+	TRANS_ACT_TO_CARDEMU_8822B,
+	TRANS_CARDEMU_TO_CARDDIS_8822B,
+	NULL
+};
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h
new file mode 100644
index 000000000000..76d39b944a02
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.h
@@ -0,0 +1,26 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef HALMAC_POWER_SEQUENCE_8822B
+#define HALMAC_POWER_SEQUENCE_8822B
+
+#include "../../halmac_pwr_seq_cmd.h"
+
+#define HALMAC_8822B_PWR_SEQ_VER  "V25"
+
+extern struct halmac_wlan_pwr_cfg *card_en_flow_8822b[];
+extern struct halmac_wlan_pwr_cfg *card_dis_flow_8822b[];
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pwr_seq_cmd.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pwr_seq_cmd.h
new file mode 100644
index 000000000000..9b64397dc8cf
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pwr_seq_cmd.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef HALMAC_POWER_SEQUENCE_CMD
+#define HALMAC_POWER_SEQUENCE_CMD
+
+#include "../wifi.h"
+
+#define HALMAC_PWR_POLLING_CNT 20000
+
+/* The value of cmd : 4 bits */
+
+/* offset : the read register offset
+ * msk : the mask of the read value
+ * value : N/A, left by 0
+ * Note : dirver shall implement this function by read & msk
+ */
+#define	HALMAC_PWR_CMD_READ		0x00
+/* offset: the read register offset
+ * msk: the mask of the write bits
+ * value: write value
+ * Note: driver shall implement this cmd by read & msk after write
+ */
+#define	HALMAC_PWR_CMD_WRITE	0x01
+/* offset: the read register offset
+ * msk: the mask of the polled value
+ * value: the value to be polled, masked by the msd field.
+ * Note: driver shall implement this cmd by
+ * do{
+ * if( (Read(offset) & msk) == (value & msk) )
+ * break;
+ * } while(not timeout);
+ */
+#define	HALMAC_PWR_CMD_POLLING	0x02
+/* offset: the value to delay
+ * msk: N/A
+ * value: the unit of delay, 0: us, 1: ms
+ */
+#define	HALMAC_PWR_CMD_DELAY	0x03
+/* offset: N/A
+ * msk: N/A
+ * value: N/A
+ */
+#define	HALMAC_PWR_CMD_END	0x04
+
+/* The value of base : 4 bits */
+
+/* define the base address of each block */
+#define   HALMAC_PWR_ADDR_MAC	0x00
+#define   HALMAC_PWR_ADDR_USB	0x01
+#define   HALMAC_PWR_ADDR_PCIE	0x02
+#define   HALMAC_PWR_ADDR_SDIO	0x03
+
+/* The value of interface_msk : 4 bits */
+#define	HALMAC_PWR_INTF_SDIO_MSK	BIT(0)
+#define	HALMAC_PWR_INTF_USB_MSK		BIT(1)
+#define	HALMAC_PWR_INTF_PCI_MSK		BIT(2)
+#define	HALMAC_PWR_INTF_ALL_MSK		(BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+/* The value of cut_msk : 8 bits */
+#define	HALMAC_PWR_CUT_TESTCHIP_MSK		BIT(0)
+#define	HALMAC_PWR_CUT_A_MSK			BIT(1)
+#define	HALMAC_PWR_CUT_B_MSK			BIT(2)
+#define	HALMAC_PWR_CUT_C_MSK			BIT(3)
+#define	HALMAC_PWR_CUT_D_MSK			BIT(4)
+#define	HALMAC_PWR_CUT_E_MSK			BIT(5)
+#define	HALMAC_PWR_CUT_F_MSK			BIT(6)
+#define	HALMAC_PWR_CUT_G_MSK			BIT(7)
+#define	HALMAC_PWR_CUT_ALL_MSK			0xFF
+
+enum halmac_pwrseq_cmd_delay_unit {
+	HALMAC_PWR_DELAY_US,
+	HALMAC_PWR_DELAY_MS,
+};
+
+struct halmac_wlan_pwr_cfg {
+	u16 offset;
+	u8 cut_msk;
+	u8 interface_msk;
+	u8 base:4;
+	u8 cmd:4;
+	u8 msk;
+	u8 value;
+};
+
+#endif
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 10/17] rtlwifi: halmac: access efuse through halmac helper functions
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (7 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 09/17] rtlwifi: halmac: add power sequence to turn on/off wifi card pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 11/17] rtlwifi: halmac: add files to implement halmac ops pkshih
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

This file provides interfaces to read and write efuse contents.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.c | 1918 ++++++++++++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.h |  101 ++
 2 files changed, 2019 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.c
new file mode 100644
index 000000000000..3d51acb5857e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.c
@@ -0,0 +1,1918 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_efuse_88xx.h"
+#include "halmac_88xx_cfg.h"
+#include "halmac_common_88xx.h"
+#include "halmac_init_88xx.h"
+
+#define RSVD_EFUSE_SIZE		16
+#define RSVD_CS_EFUSE_SIZE	24
+#define PROTECT_EFUSE_SIZE	96
+#define FEATURE_DUMP_PHY_EFUSE	HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE
+#define FEATURE_DUMP_LOG_EFUSE	HALMAC_FEATURE_DUMP_LOGICAL_EFUSE
+
+static enum halmac_cmd_construct_state
+efuse_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+proc_dump_efuse_88xx(struct halmac_adapter *adapter,
+		     enum halmac_efuse_read_cfg cfg);
+
+static enum halmac_ret_status
+read_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+		   u8 *map);
+
+static enum halmac_ret_status
+eeprom_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map, u8 *log_map);
+
+static enum halmac_ret_status
+read_log_efuse_map_88xx(struct halmac_adapter *adapter, u8 *map);
+
+static enum halmac_ret_status
+proc_pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
+			  struct halmac_pg_efuse_info *info,
+			  enum halmac_efuse_read_cfg cfg);
+
+static enum halmac_ret_status
+dump_efuse_fw_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+dump_efuse_drv_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+proc_write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value);
+
+static enum halmac_ret_status
+update_eeprom_mask_88xx(struct halmac_adapter *adapter,
+			struct halmac_pg_efuse_info *info, u8 *updated_mask);
+
+static enum halmac_ret_status
+check_efuse_enough_88xx(struct halmac_adapter *adapter,
+			struct halmac_pg_efuse_info *info, u8 *updated_mask);
+
+static enum halmac_ret_status
+pg_extend_efuse_88xx(struct halmac_adapter *adapter,
+		     struct halmac_pg_efuse_info *info, u8 word_en,
+		     u8 pre_word_en, u32 eeprom_offset);
+
+static enum halmac_ret_status
+proc_pg_efuse_88xx(struct halmac_adapter *adapter,
+		   struct halmac_pg_efuse_info *info, u8 word_en,
+		   u8 pre_word_en, u32 eeprom_offset);
+
+static enum halmac_ret_status
+program_efuse_88xx(struct halmac_adapter *adapter,
+		   struct halmac_pg_efuse_info *info, u8 *updated_mask);
+
+static void
+mask_eeprom_88xx(struct halmac_adapter *adapter,
+		 struct halmac_pg_efuse_info *info);
+
+/**
+ * dump_efuse_map_88xx() - dump "physical" efuse map
+ * @adapter : the adapter of halmac
+ * @cfg : dump efuse method
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+dump_efuse_map_88xx(struct halmac_adapter *adapter,
+		    enum halmac_efuse_read_cfg cfg)
+{
+	u8 *map = NULL;
+	u8 *efuse_map;
+	u32 efuse_size = adapter->hw_cfg_info.efuse_size;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	if (cfg == HALMAC_EFUSE_R_FW &&
+	    halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "cfg = %d\n",
+		 cfg);
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Wait event(efuse)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Not idle(efuse)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
+		pr_err("Dump efuse in suspend\n");
+
+	*proc_status = HALMAC_CMD_PROCESS_IDLE;
+	adapter->evnt.phy_efuse_map = 1;
+
+	status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("switch efuse bank!!\n");
+		return status;
+	}
+
+	status = proc_dump_efuse_88xx(adapter, cfg);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("dump efuse!!\n");
+		return status;
+	}
+
+	if (adapter->efuse_map_valid == 1) {
+		*proc_status = HALMAC_CMD_PROCESS_DONE;
+		efuse_map = adapter->efuse_map;
+
+		map = kzalloc(efuse_size, GFP_KERNEL);
+		if (!map)
+			return HALMAC_RET_MALLOC_FAIL;
+		memset(map, 0xFF, efuse_size);
+		mutex_lock(&adapter->efuse_mutex);
+		memcpy(map, efuse_map, efuse_size - PROTECT_EFUSE_SIZE);
+		memcpy(map + efuse_size - PROTECT_EFUSE_SIZE +
+		       RSVD_CS_EFUSE_SIZE,
+		       efuse_map + efuse_size - PROTECT_EFUSE_SIZE +
+		       RSVD_CS_EFUSE_SIZE,
+		       PROTECT_EFUSE_SIZE - RSVD_EFUSE_SIZE -
+		       RSVD_CS_EFUSE_SIZE);
+		mutex_unlock(&adapter->efuse_mutex);
+
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
+				*proc_status, map, efuse_size);
+		adapter->evnt.phy_efuse_map = 0;
+
+		kfree(map);
+	}
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * dump_efuse_map_bt_88xx() - dump "BT physical" efuse map
+ * @adapter : the adapter of halmac
+ * @bank : bt efuse bank
+ * @size : bt efuse map size. get from halmac_get_efuse_size API
+ * @map : bt efuse map
+ * Author : Soar / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+dump_efuse_map_bt_88xx(struct halmac_adapter *adapter,
+		       enum halmac_efuse_bank bank, u32 size, u8 *map)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (adapter->hw_cfg_info.bt_efuse_size != size)
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+
+	if (bank >= HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
+		pr_err("Undefined BT bank\n");
+		return HALMAC_RET_EFUSE_BANK_INCORRECT;
+	}
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Wait event(efuse)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Not idle(efuse)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	status = switch_efuse_bank_88xx(adapter, bank);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("switch efuse bank!!\n");
+		return status;
+	}
+
+	status = read_hw_efuse_88xx(adapter, 0, size, map);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("read hw efuse\n");
+		return status;
+	}
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * write_efuse_bt_88xx() - write "BT physical" efuse offset
+ * @adapter : the adapter of halmac
+ * @offset : offset
+ * @value : Write value
+ * @map : bt efuse map
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+write_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 value,
+		    enum halmac_efuse_bank bank)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Wait event(efuse)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Not idle(efuse)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	if (offset >= adapter->hw_cfg_info.efuse_size) {
+		pr_err("Offset is too large\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if (bank > HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
+		pr_err("Undefined BT bank\n");
+		return HALMAC_RET_EFUSE_BANK_INCORRECT;
+	}
+
+	status = switch_efuse_bank_88xx(adapter, bank);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("switch efuse bank!!\n");
+		return status;
+	}
+
+	status = write_hw_efuse_88xx(adapter, offset, value);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("write efuse\n");
+		return status;
+	}
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * read_efuse_bt_88xx() - read "BT physical" efuse offset
+ * @adapter : the adapter of halmac
+ * @offset : offset
+ * @value : 1 byte efuse value
+ * @bank : efuse bank
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+read_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value,
+		   enum halmac_efuse_bank bank)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Wait event(efuse)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Not idle(efuse)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	if (offset >= adapter->hw_cfg_info.efuse_size) {
+		pr_err("Offset is too large\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if (bank > HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
+		pr_err("Undefined BT bank\n");
+		return HALMAC_RET_EFUSE_BANK_INCORRECT;
+	}
+
+	status = switch_efuse_bank_88xx(adapter, bank);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("switch efuse bank\n");
+		return status;
+	}
+
+	status = read_efuse_88xx(adapter, offset, 1, value);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("read efuse\n");
+		return status;
+	}
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_efuse_auto_check_88xx() - check efuse after writing it
+ * @adapter : the adapter of halmac
+ * @enable : 1, enable efuse auto check. others, disable
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_efuse_auto_check_88xx(struct halmac_adapter *adapter, u8 enable)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	adapter->efuse_auto_check_en = enable;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * get_efuse_available_size_88xx() - get efuse available size
+ * @adapter : the adapter of halmac
+ * @size : physical efuse available size
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_efuse_available_size_88xx(struct halmac_adapter *adapter, u32 *size)
+{
+	enum halmac_ret_status status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = dump_log_efuse_map_88xx(adapter, HALMAC_EFUSE_R_DRV);
+
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	*size = adapter->hw_cfg_info.efuse_size - PROTECT_EFUSE_SIZE -
+		adapter->efuse_end;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * get_efuse_size_88xx() - get "physical" efuse size
+ * @adapter : the adapter of halmac
+ * @size : physical efuse size
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_efuse_size_88xx(struct halmac_adapter *adapter, u32 *size)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	*size = adapter->hw_cfg_info.efuse_size;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * get_log_efuse_size_88xx() - get "logical" efuse size
+ * @adapter : the adapter of halmac
+ * @size : logical efuse size
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_log_efuse_size_88xx(struct halmac_adapter *adapter, u32 *size)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	*size = adapter->hw_cfg_info.eeprom_size;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * dump_log_efuse_map_88xx() - dump "logical" efuse map
+ * @adapter : the adapter of halmac
+ * @cfg : dump efuse method
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+dump_log_efuse_map_88xx(struct halmac_adapter *adapter,
+			enum halmac_efuse_read_cfg cfg)
+{
+	u8 *map = NULL;
+	u32 size = adapter->hw_cfg_info.eeprom_size;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	if (cfg == HALMAC_EFUSE_R_FW &&
+	    halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "cfg = %d\n",
+		 cfg);
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Wait event(efuse)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Not idle(efuse)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
+		pr_err("Dump efuse in suspend\n");
+
+	*proc_status = HALMAC_CMD_PROCESS_IDLE;
+	adapter->evnt.log_efuse_map = 1;
+
+	status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("switch efuse bank\n");
+		return status;
+	}
+
+	status = proc_dump_efuse_88xx(adapter, cfg);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("dump efuse\n");
+		return status;
+	}
+
+	if (adapter->efuse_map_valid == 1) {
+		*proc_status = HALMAC_CMD_PROCESS_DONE;
+
+		map = kzalloc(size, GFP_KERNEL);
+		if (!map)
+			return HALMAC_RET_MALLOC_FAIL;
+		memset(map, 0xFF, size);
+
+		if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
+		    HALMAC_RET_SUCCESS) {
+			kfree(map);
+			return HALMAC_RET_EEPROM_PARSING_FAIL;
+		}
+
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
+				*proc_status, map, size);
+		adapter->evnt.log_efuse_map = 0;
+
+		kfree(map);
+	}
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * read_logical_efuse_88xx() - read logical efuse map 1 byte
+ * @adapter : the adapter of halmac
+ * @offset : offset
+ * @value : 1 byte efuse value
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+read_logical_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value)
+{
+	u8 *map = NULL;
+	u32 size = adapter->hw_cfg_info.eeprom_size;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (offset >= size) {
+		pr_err("Offset is too large\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Wait event(efuse)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+	if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Not idle(efuse)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("switch efuse bank\n");
+		return status;
+	}
+
+	map = kzalloc(size, GFP_KERNEL);
+	if (!map)
+		return HALMAC_RET_MALLOC_FAIL;
+	memset(map, 0xFF, size);
+
+	status = read_log_efuse_map_88xx(adapter, map);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("read logical efuse\n");
+		kfree(map);
+		return status;
+	}
+
+	*value = *(map + offset);
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS) {
+		kfree(map);
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	kfree(map);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * write_log_efuse_88xx() - write "logical" efuse offset
+ * @adapter : the adapter of halmac
+ * @offset : offset
+ * @value : value
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (offset >= adapter->hw_cfg_info.eeprom_size) {
+		pr_err("Offset is too large\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Wait event(efuse)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Not idle(efuse)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("switch efuse bank\n");
+		return status;
+	}
+
+	status = proc_write_log_efuse_88xx(adapter, offset, value);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("write logical efuse\n");
+		return status;
+	}
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * pg_efuse_by_map_88xx() - pg logical efuse by map
+ * @adapter : the adapter of halmac
+ * @info : efuse map information
+ * @cfg : dump efuse method
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
+		     struct halmac_pg_efuse_info *info,
+		     enum halmac_efuse_read_cfg cfg)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (info->efuse_map_size != adapter->hw_cfg_info.eeprom_size) {
+		pr_err("map size error\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if ((info->efuse_map_size & 0xF) > 0) {
+		pr_err("not multiple of 16\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if (info->efuse_mask_size != info->efuse_map_size >> 4) {
+		pr_err("mask size error\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if (!info->efuse_map) {
+		pr_err("map is NULL\n");
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	if (!info->efuse_mask) {
+		pr_err("mask is NULL\n");
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Wait event(efuse)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Not idle(efuse)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("switch efuse bank\n");
+		return status;
+	}
+
+	status = proc_pg_efuse_by_map_88xx(adapter, info, cfg);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("pg efuse\n");
+		return status;
+	}
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * mask_log_efuse_88xx() - mask logical efuse
+ * @adapter : the adapter of halmac
+ * @info : efuse map information
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+mask_log_efuse_88xx(struct halmac_adapter *adapter,
+		    struct halmac_pg_efuse_info *info)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (info->efuse_map_size != adapter->hw_cfg_info.eeprom_size) {
+		pr_err("map size error\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if ((info->efuse_map_size & 0xF) > 0) {
+		pr_err("not multiple of 16\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if (info->efuse_mask_size != info->efuse_map_size >> 4) {
+		pr_err("mask size error\n");
+		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
+	}
+
+	if (!info->efuse_map) {
+		pr_err("map is NULL\n");
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	if (!info->efuse_mask) {
+		pr_err("mask is NULL\n");
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	mask_eeprom_88xx(adapter, info);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_cmd_construct_state
+efuse_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
+{
+	return adapter->halmac_state.efuse_state.cmd_cnstr_state;
+}
+
+enum halmac_ret_status
+switch_efuse_bank_88xx(struct halmac_adapter *adapter,
+		       enum halmac_efuse_bank bank)
+{
+	u8 reg_value;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_BUSY) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	reg_value = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 1);
+
+	if (bank == (reg_value & (BIT(0) | BIT(1))))
+		return HALMAC_RET_SUCCESS;
+
+	reg_value &= ~(BIT(0) | BIT(1));
+	reg_value |= bank;
+	HALMAC_REG_W8(REG_LDO_EFUSE_CTRL + 1, reg_value);
+
+	reg_value = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 1);
+	if ((reg_value & (BIT(0) | BIT(1))) != bank)
+		return HALMAC_RET_SWITCH_EFUSE_BANK_FAIL;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+proc_dump_efuse_88xx(struct halmac_adapter *adapter,
+		     enum halmac_efuse_read_cfg cfg)
+{
+	u32 h2c_init;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.efuse_state.proc_status;
+
+	*proc_status = HALMAC_CMD_PROCESS_SENDING;
+
+	if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	if (cfg == HALMAC_EFUSE_R_AUTO) {
+		h2c_init = HALMAC_REG_R32(REG_H2C_PKT_READADDR);
+		if (adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE ||
+		    h2c_init == 0)
+			status = dump_efuse_drv_88xx(adapter);
+		else
+			status = dump_efuse_fw_88xx(adapter);
+	} else if (cfg == HALMAC_EFUSE_R_FW) {
+		status = dump_efuse_fw_88xx(adapter);
+	} else {
+		status = dump_efuse_drv_88xx(adapter);
+	}
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("dump efsue drv/fw\n");
+		return status;
+	}
+
+	return status;
+}
+
+enum halmac_ret_status
+cnv_efuse_state_88xx(struct halmac_adapter *adapter,
+		     enum halmac_cmd_construct_state dest_state)
+{
+	struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
+
+	if (state->cmd_cnstr_state != HALMAC_CMD_CNSTR_IDLE &&
+	    state->cmd_cnstr_state != HALMAC_CMD_CNSTR_BUSY &&
+	    state->cmd_cnstr_state != HALMAC_CMD_CNSTR_H2C_SENT)
+		return HALMAC_RET_ERROR_STATE;
+
+	if (state->cmd_cnstr_state == dest_state)
+		return HALMAC_RET_ERROR_STATE;
+
+	if (dest_state == HALMAC_CMD_CNSTR_BUSY) {
+		if (state->cmd_cnstr_state == HALMAC_CMD_CNSTR_H2C_SENT)
+			return HALMAC_RET_ERROR_STATE;
+	} else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
+		if (state->cmd_cnstr_state == HALMAC_CMD_CNSTR_IDLE)
+			return HALMAC_RET_ERROR_STATE;
+	}
+
+	state->cmd_cnstr_state = dest_state;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+read_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+		   u8 *map)
+{
+	u8 enable;
+	u32 value32;
+	u32 addr;
+	u32 tmp32;
+	u32 cnt;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	/* Read efuse no need 2.5V LDO */
+	enable = 0;
+	status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("dis ldo25\n");
+		return status;
+	}
+	value32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
+
+	for (addr = offset; addr < offset + size; addr++) {
+		value32 &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR);
+		value32 |= ((addr & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR);
+		HALMAC_REG_W32(REG_EFUSE_CTRL, value32 & (~BIT_EF_FLAG));
+
+		cnt = 1000000;
+		do {
+			udelay(1);
+			tmp32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
+			cnt--;
+			if (cnt == 0) {
+				pr_err("read\n");
+				return HALMAC_RET_EFUSE_R_FAIL;
+			}
+		} while ((tmp32 & BIT_EF_FLAG) == 0);
+
+		*(map + addr - offset) = (u8)(tmp32 & BIT_MASK_EF_DATA);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+write_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
+{
+	const u8 unlock_code = 0x69;
+	u8 value_read = 0;
+	u8 enable;
+	u32 value32;
+	u32 tmp32;
+	u32 cnt;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	mutex_lock(&adapter->efuse_mutex);
+	adapter->efuse_map_valid = 0;
+	mutex_unlock(&adapter->efuse_mutex);
+
+	HALMAC_REG_W8(REG_PMC_DBG_CTRL2 + 3, unlock_code);
+
+	/* Enable 2.5V LDO */
+	enable = 1;
+	status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("en ldo25\n");
+		return status;
+	}
+
+	value32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
+	value32 &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR);
+	value32 = value32 | ((offset & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR) |
+			(value & BIT_MASK_EF_DATA);
+	HALMAC_REG_W32(REG_EFUSE_CTRL, value32 | BIT_EF_FLAG);
+
+	cnt = 1000000;
+	do {
+		udelay(1);
+		tmp32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
+		cnt--;
+		if (cnt == 0) {
+			pr_err("write!!\n");
+			return HALMAC_RET_EFUSE_W_FAIL;
+		}
+	} while (BIT_EF_FLAG == (tmp32 & BIT_EF_FLAG));
+
+	HALMAC_REG_W8(REG_PMC_DBG_CTRL2 + 3, 0x00);
+
+	/* Disable 2.5V LDO */
+	enable = 0;
+	status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("dis ldo25\n");
+		return status;
+	}
+
+	if (adapter->efuse_auto_check_en == 1) {
+		if (read_hw_efuse_88xx(adapter, offset, 1, &value_read) !=
+		    HALMAC_RET_SUCCESS)
+			return HALMAC_RET_EFUSE_R_FAIL;
+		if (value_read != value) {
+			pr_err("efuse compare\n");
+			return HALMAC_RET_EFUSE_W_FAIL;
+		}
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+eeprom_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map, u8 *log_map)
+{
+	u8 i;
+	u8 value8;
+	u8 blk_idx;
+	u8 word_en;
+	u8 valid;
+	u8 hdr;
+	u8 hdr2 = 0;
+	u32 eeprom_idx;
+	u32 efuse_idx = 0;
+	struct halmac_hw_cfg_info *hw_info = &adapter->hw_cfg_info;
+
+	memset(log_map, 0xFF, hw_info->eeprom_size);
+
+	do {
+		value8 = *(phy_map + efuse_idx);
+		hdr = value8;
+
+		if ((hdr & 0x1f) == 0x0f) {
+			efuse_idx++;
+			value8 = *(phy_map + efuse_idx);
+			hdr2 = value8;
+			if (hdr2 == 0xff)
+				break;
+			blk_idx = ((hdr2 & 0xF0) >> 1) | ((hdr >> 5) & 0x07);
+			word_en = hdr2 & 0x0F;
+		} else {
+			blk_idx = (hdr & 0xF0) >> 4;
+			word_en = hdr & 0x0F;
+		}
+
+		if (hdr == 0xff)
+			break;
+
+		efuse_idx++;
+
+		if (efuse_idx >= hw_info->efuse_size - PROTECT_EFUSE_SIZE - 1)
+			return HALMAC_RET_EEPROM_PARSING_FAIL;
+
+		for (i = 0; i < 4; i++) {
+			valid = (u8)((~(word_en >> i)) & BIT(0));
+			if (valid == 1) {
+				eeprom_idx = (blk_idx << 3) + (i << 1);
+
+				if ((eeprom_idx + 1) > hw_info->eeprom_size) {
+					pr_err("efuse idx:0x%X\n",
+					       efuse_idx - 1);
+
+					pr_err("read hdr:0x%X\n", hdr);
+
+					pr_err("rad hdr2:0x%X\n", hdr2);
+
+					return HALMAC_RET_EEPROM_PARSING_FAIL;
+				}
+
+				value8 = *(phy_map + efuse_idx);
+				*(log_map + eeprom_idx) = value8;
+
+				eeprom_idx++;
+				efuse_idx++;
+
+				if (efuse_idx > hw_info->efuse_size -
+				    PROTECT_EFUSE_SIZE - 1)
+					return HALMAC_RET_EEPROM_PARSING_FAIL;
+
+				value8 = *(phy_map + efuse_idx);
+				*(log_map + eeprom_idx) = value8;
+
+				efuse_idx++;
+
+				if (efuse_idx > hw_info->efuse_size -
+				    PROTECT_EFUSE_SIZE)
+					return HALMAC_RET_EEPROM_PARSING_FAIL;
+			}
+		}
+	} while (1);
+
+	adapter->efuse_end = efuse_idx;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+read_log_efuse_map_88xx(struct halmac_adapter *adapter, u8 *map)
+{
+	u8 *local_map = NULL;
+	u32 efuse_size;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (adapter->efuse_map_valid == 0) {
+		efuse_size = adapter->hw_cfg_info.efuse_size;
+
+		local_map = kzalloc(efuse_size, GFP_KERNEL);
+		if (!local_map)
+			return HALMAC_RET_MALLOC_FAIL;
+
+		status = read_efuse_88xx(adapter, 0, efuse_size, local_map);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("read efuse\n");
+			kfree(local_map);
+			return status;
+		}
+
+		if (!adapter->efuse_map) {
+			adapter->efuse_map = kzalloc(efuse_size, GFP_KERNEL);
+			if (!adapter->efuse_map) {
+				kfree(local_map);
+				return HALMAC_RET_MALLOC_FAIL;
+			}
+		}
+
+		mutex_lock(&adapter->efuse_mutex);
+		memcpy(adapter->efuse_map, local_map, efuse_size);
+		adapter->efuse_map_valid = 1;
+		mutex_unlock(&adapter->efuse_mutex);
+
+		kfree(local_map);
+	}
+
+	if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_EEPROM_PARSING_FAIL;
+
+	return status;
+}
+
+static enum halmac_ret_status
+proc_pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
+			  struct halmac_pg_efuse_info *info,
+			  enum halmac_efuse_read_cfg cfg)
+{
+	u8 *updated_mask = NULL;
+	u32 mask_size = adapter->hw_cfg_info.eeprom_size >> 4;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	updated_mask = kzalloc(mask_size, GFP_KERNEL);
+	if (!updated_mask)
+		return HALMAC_RET_MALLOC_FAIL;
+	memset(updated_mask, 0x00, mask_size);
+
+	status = update_eeprom_mask_88xx(adapter, info, updated_mask);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("update eeprom mask\n");
+		kfree(updated_mask);
+		return status;
+	}
+
+	status = check_efuse_enough_88xx(adapter, info, updated_mask);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("chk efuse enough\n");
+		kfree(updated_mask);
+		return status;
+	}
+
+	status = program_efuse_88xx(adapter, info, updated_mask);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("pg efuse\n");
+		kfree(updated_mask);
+		return status;
+	}
+
+	kfree(updated_mask);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+dump_efuse_drv_88xx(struct halmac_adapter *adapter)
+{
+	u8 *map = NULL;
+	u32 efuse_size = adapter->hw_cfg_info.efuse_size;
+
+	if (!adapter->efuse_map) {
+		adapter->efuse_map = kzalloc(efuse_size, GFP_KERNEL);
+		if (!adapter->efuse_map) {
+			reset_ofld_feature_88xx(adapter,
+						FEATURE_DUMP_PHY_EFUSE);
+			return HALMAC_RET_MALLOC_FAIL;
+		}
+	}
+
+	if (adapter->efuse_map_valid == 0) {
+		map = kzalloc(efuse_size, GFP_KERNEL);
+		if (!map)
+			return HALMAC_RET_MALLOC_FAIL;
+
+		if (read_hw_efuse_88xx(adapter, 0, efuse_size, map) !=
+		    HALMAC_RET_SUCCESS) {
+			kfree(map);
+			return HALMAC_RET_EFUSE_R_FAIL;
+		}
+
+		mutex_lock(&adapter->efuse_mutex);
+		memcpy(adapter->efuse_map, map, efuse_size);
+		adapter->efuse_map_valid = 1;
+		mutex_unlock(&adapter->efuse_mutex);
+
+		kfree(map);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+dump_efuse_fw_88xx(struct halmac_adapter *adapter)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	u32 efuse_size = adapter->hw_cfg_info.efuse_size;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_DUMP_PHYSICAL_EFUSE;
+	hdr_info.content_size = 0;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	adapter->halmac_state.efuse_state.seq_num = seq_num;
+
+	if (!adapter->efuse_map) {
+		adapter->efuse_map = kzalloc(efuse_size, GFP_KERNEL);
+		if (!adapter->efuse_map) {
+			reset_ofld_feature_88xx(adapter,
+						FEATURE_DUMP_PHY_EFUSE);
+			return HALMAC_RET_MALLOC_FAIL;
+		}
+	}
+
+	if (adapter->efuse_map_valid == 0) {
+		status = send_h2c_pkt_88xx(adapter, h2c_buf);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("send h2c pkt\n");
+			reset_ofld_feature_88xx(adapter,
+						FEATURE_DUMP_PHY_EFUSE);
+			return status;
+		}
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+proc_write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
+{
+	u8 byte1;
+	u8 byte2;
+	u8 blk;
+	u8 blk_idx;
+	u8 hdr;
+	u8 hdr2;
+	u8 *map = NULL;
+	u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
+	u32 end;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	map = kzalloc(eeprom_size, GFP_KERNEL);
+	if (!map)
+		return HALMAC_RET_MALLOC_FAIL;
+	memset(map, 0xFF, eeprom_size);
+
+	status = read_log_efuse_map_88xx(adapter, map);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("read logical efuse\n");
+		kfree(map);
+		return status;
+	}
+
+	if (*(map + offset) != value) {
+		end = adapter->efuse_end;
+		blk = (u8)(offset >> 3);
+		blk_idx = (u8)((offset & (8 - 1)) >> 1);
+
+		if (offset > 0x7f) {
+			hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
+			hdr2 = (u8)(((blk & 0x78) << 1) +
+						((0x1 << blk_idx) ^ 0x0F));
+		} else {
+			hdr = (u8)((blk << 4) + ((0x01 << blk_idx) ^ 0x0F));
+		}
+
+		if ((offset & 1) == 0) {
+			byte1 = value;
+			byte2 = *(map + offset + 1);
+		} else {
+			byte1 = *(map + offset - 1);
+			byte2 = value;
+		}
+
+		if (offset > 0x7f) {
+			if (adapter->hw_cfg_info.efuse_size <=
+			    4 + PROTECT_EFUSE_SIZE + end) {
+				kfree(map);
+				return HALMAC_RET_EFUSE_NOT_ENOUGH;
+			}
+
+			status = write_hw_efuse_88xx(adapter, end, hdr);
+			if (status != HALMAC_RET_SUCCESS) {
+				kfree(map);
+				return status;
+			}
+
+			status = write_hw_efuse_88xx(adapter, end + 1, hdr2);
+			if (status != HALMAC_RET_SUCCESS) {
+				kfree(map);
+				return status;
+			}
+
+			status = write_hw_efuse_88xx(adapter, end + 2, byte1);
+			if (status != HALMAC_RET_SUCCESS) {
+				kfree(map);
+				return status;
+			}
+
+			status = write_hw_efuse_88xx(adapter, end + 3, byte2);
+			if (status != HALMAC_RET_SUCCESS) {
+				kfree(map);
+				return status;
+			}
+		} else {
+			if (adapter->hw_cfg_info.efuse_size <=
+			    3 + PROTECT_EFUSE_SIZE + end) {
+				kfree(map);
+				return HALMAC_RET_EFUSE_NOT_ENOUGH;
+			}
+
+			status = write_hw_efuse_88xx(adapter, end, hdr);
+			if (status != HALMAC_RET_SUCCESS) {
+				kfree(map);
+				return status;
+			}
+
+			status = write_hw_efuse_88xx(adapter, end + 1, byte1);
+			if (status != HALMAC_RET_SUCCESS) {
+				kfree(map);
+				return status;
+			}
+
+			status = write_hw_efuse_88xx(adapter, end + 2, byte2);
+			if (status != HALMAC_RET_SUCCESS) {
+				kfree(map);
+				return status;
+			}
+		}
+	}
+
+	kfree(map);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+read_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size, u8 *map)
+{
+	if (!map) {
+		pr_err("malloc map\n");
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	if (adapter->efuse_map_valid == 1) {
+		memcpy(map, adapter->efuse_map + offset, size);
+	} else {
+		if (read_hw_efuse_88xx(adapter, offset, size, map) !=
+		    HALMAC_RET_SUCCESS)
+			return HALMAC_RET_EFUSE_R_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+update_eeprom_mask_88xx(struct halmac_adapter *adapter,
+			struct halmac_pg_efuse_info *info, u8 *updated_mask)
+{
+	u8 *map = NULL;
+	u8 clr_bit = 0;
+	u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
+	u8 *map_pg;
+	u8 *efuse_mask;
+	u16 i;
+	u16 j;
+	u16 map_offset;
+	u16 mask_offset;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	map = kzalloc(eeprom_size, GFP_KERNEL);
+	if (!map)
+		return HALMAC_RET_MALLOC_FAIL;
+	memset(map, 0xFF, eeprom_size);
+
+	memset(updated_mask, 0x00, info->efuse_mask_size);
+
+	status = read_log_efuse_map_88xx(adapter, map);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		kfree(map);
+		return status;
+	}
+
+	map_pg = info->efuse_map;
+	efuse_mask = info->efuse_mask;
+
+	for (i = 0; i < info->efuse_mask_size; i++)
+		*(updated_mask + i) = *(efuse_mask + i);
+
+	for (i = 0; i < info->efuse_map_size; i += 16) {
+		for (j = 0; j < 16; j += 2) {
+			map_offset = i + j;
+			mask_offset = i >> 4;
+			if (*(u16 *)(map_pg + map_offset) ==
+			    *(u16 *)(map + map_offset)) {
+				switch (j) {
+				case 0:
+					clr_bit = BIT(4);
+					break;
+				case 2:
+					clr_bit = BIT(5);
+					break;
+				case 4:
+					clr_bit = BIT(6);
+					break;
+				case 6:
+					clr_bit = BIT(7);
+					break;
+				case 8:
+					clr_bit = BIT(0);
+					break;
+				case 10:
+					clr_bit = BIT(1);
+					break;
+				case 12:
+					clr_bit = BIT(2);
+					break;
+				case 14:
+					clr_bit = BIT(3);
+					break;
+				default:
+					break;
+				}
+				*(updated_mask + mask_offset) &= ~clr_bit;
+			}
+		}
+	}
+
+	kfree(map);
+
+	return status;
+}
+
+static enum halmac_ret_status
+check_efuse_enough_88xx(struct halmac_adapter *adapter,
+			struct halmac_pg_efuse_info *info, u8 *updated_mask)
+{
+	u8 pre_word_en;
+	u16 i;
+	u16 j;
+	u32 eeprom_offset;
+	u32 pg_num = 0;
+
+	for (i = 0; i < info->efuse_map_size; i = i + 8) {
+		eeprom_offset = i;
+
+		if ((eeprom_offset & 7) > 0)
+			pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
+		else
+			pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
+
+		if (pre_word_en > 0) {
+			if (eeprom_offset > 0x7f) {
+				pg_num += 2;
+				for (j = 0; j < 4; j++) {
+					if (((pre_word_en >> j) & 0x1) > 0)
+						pg_num += 2;
+				}
+			} else {
+				pg_num++;
+				for (j = 0; j < 4; j++) {
+					if (((pre_word_en >> j) & 0x1) > 0)
+						pg_num += 2;
+				}
+			}
+		}
+	}
+
+	if (adapter->hw_cfg_info.efuse_size <=
+	    (pg_num + PROTECT_EFUSE_SIZE + adapter->efuse_end))
+		return HALMAC_RET_EFUSE_NOT_ENOUGH;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+pg_extend_efuse_88xx(struct halmac_adapter *adapter,
+		     struct halmac_pg_efuse_info *info, u8 word_en,
+		     u8 pre_word_en, u32 eeprom_offset)
+{
+	u8 blk;
+	u8 hdr;
+	u8 hdr2;
+	u16 i;
+	u32 efuse_end;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	efuse_end = adapter->efuse_end;
+
+	blk = (u8)(eeprom_offset >> 3);
+	hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
+	hdr2 = (u8)(((blk & 0x78) << 1) + word_en);
+
+	status = write_hw_efuse_88xx(adapter, efuse_end, hdr);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("write efuse\n");
+		return status;
+	}
+
+	status = write_hw_efuse_88xx(adapter, efuse_end + 1, hdr2);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("write efuse(+1)\n");
+		return status;
+	}
+
+	efuse_end = efuse_end + 2;
+	for (i = 0; i < 4; i++) {
+		if (((pre_word_en >> i) & 0x1) > 0) {
+			status = write_hw_efuse_88xx(adapter, efuse_end,
+						     *(info->efuse_map +
+						     eeprom_offset +
+						     (i << 1)));
+			if (status != HALMAC_RET_SUCCESS) {
+				pr_err("write efuse(<<1)\n");
+				return status;
+			}
+
+			status = write_hw_efuse_88xx(adapter, efuse_end + 1,
+						     *(info->efuse_map +
+						     eeprom_offset + (i << 1)
+						     + 1));
+			if (status != HALMAC_RET_SUCCESS) {
+				pr_err("write efuse(<<1)+1\n");
+				return status;
+			}
+			efuse_end = efuse_end + 2;
+		}
+	}
+	adapter->efuse_end = efuse_end;
+	return status;
+}
+
+static enum halmac_ret_status
+proc_pg_efuse_88xx(struct halmac_adapter *adapter,
+		   struct halmac_pg_efuse_info *info, u8 word_en,
+		   u8 pre_word_en, u32 eeprom_offset)
+{
+	u8 blk;
+	u8 hdr;
+	u16 i;
+	u32 efuse_end;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	efuse_end = adapter->efuse_end;
+
+	blk = (u8)(eeprom_offset >> 3);
+	hdr = (u8)((blk << 4) + word_en);
+
+	status = write_hw_efuse_88xx(adapter, efuse_end, hdr);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("write efuse\n");
+		return status;
+	}
+	efuse_end = efuse_end + 1;
+	for (i = 0; i < 4; i++) {
+		if (((pre_word_en >> i) & 0x1) > 0) {
+			status = write_hw_efuse_88xx(adapter, efuse_end,
+						     *(info->efuse_map +
+						     eeprom_offset +
+						     (i << 1)));
+			if (status != HALMAC_RET_SUCCESS) {
+				pr_err("write efuse(<<1)\n");
+				return status;
+			}
+			status = write_hw_efuse_88xx(adapter, efuse_end + 1,
+						     *(info->efuse_map +
+						     eeprom_offset + (i << 1)
+						     + 1));
+			if (status != HALMAC_RET_SUCCESS) {
+				pr_err("write efuse(<<1)+1\n");
+				return status;
+			}
+			efuse_end = efuse_end + 2;
+		}
+	}
+	adapter->efuse_end = efuse_end;
+	return status;
+}
+
+static enum halmac_ret_status
+program_efuse_88xx(struct halmac_adapter *adapter,
+		   struct halmac_pg_efuse_info *info, u8 *updated_mask)
+{
+	u8 pre_word_en;
+	u8 word_en;
+	u16 i;
+	u32 eeprom_offset;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	for (i = 0; i < info->efuse_map_size; i = i + 8) {
+		eeprom_offset = i;
+
+		if (((eeprom_offset >> 3) & 1) > 0) {
+			pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
+			word_en = pre_word_en ^ 0x0F;
+		} else {
+			pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
+			word_en = pre_word_en ^ 0x0F;
+		}
+
+		if (pre_word_en > 0) {
+			if (eeprom_offset > 0x7f) {
+				status = pg_extend_efuse_88xx(adapter, info,
+							      word_en,
+							      pre_word_en,
+							      eeprom_offset);
+				if (status != HALMAC_RET_SUCCESS) {
+					pr_err("extend efuse\n");
+					return status;
+				}
+			} else {
+				status = proc_pg_efuse_88xx(adapter, info,
+							    word_en,
+							    pre_word_en,
+							    eeprom_offset);
+				if (status != HALMAC_RET_SUCCESS) {
+					pr_err("extend efuse");
+					return status;
+				}
+			}
+		}
+	}
+
+	return status;
+}
+
+static void
+mask_eeprom_88xx(struct halmac_adapter *adapter,
+		 struct halmac_pg_efuse_info *info)
+{
+	u8 pre_word_en;
+	u8 *updated_mask;
+	u8 *efuse_map;
+	u16 i;
+	u16 j;
+	u32 offset;
+
+	updated_mask = info->efuse_mask;
+	efuse_map = info->efuse_map;
+
+	for (i = 0; i < info->efuse_map_size; i = i + 8) {
+		offset = i;
+
+		if (((offset >> 3) & 1) > 0)
+			pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
+		else
+			pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
+
+		for (j = 0; j < 4; j++) {
+			if (((pre_word_en >> j) & 0x1) == 0) {
+				*(efuse_map + offset + (j << 1)) = 0xFF;
+				*(efuse_map + offset + (j << 1) + 1) = 0xFF;
+			}
+		}
+	}
+}
+
+enum halmac_ret_status
+get_efuse_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seg_id;
+	u8 seg_size;
+	u8 seq_num;
+	u8 fw_rc;
+	u8 *map = NULL;
+	u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
+	struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
+	enum halmac_cmd_process_status proc_status;
+
+	seq_num = (u8)EFUSE_DATA_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Seq num : h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("Seq num mismatch : h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not cmd sending\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	seg_id = (u8)EFUSE_DATA_GET_SEGMENT_ID(buf);
+	seg_size = (u8)EFUSE_DATA_GET_SEGMENT_SIZE(buf);
+	if (seg_id == 0)
+		adapter->efuse_seg_size = seg_size;
+
+	map = kzalloc(eeprom_size, GFP_KERNEL);
+	if (!map)
+		return HALMAC_RET_MALLOC_FAIL;
+	memset(map, 0xFF, eeprom_size);
+
+	mutex_lock(&adapter->efuse_mutex);
+	memcpy(adapter->efuse_map + seg_id * adapter->efuse_seg_size,
+	       buf + C2H_DATA_OFFSET_88XX, seg_size);
+	mutex_unlock(&adapter->efuse_mutex);
+
+	if (EFUSE_DATA_GET_END_SEGMENT(buf) == 0) {
+		kfree(map);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	fw_rc = state->fw_rc;
+
+	if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
+		proc_status = HALMAC_CMD_PROCESS_DONE;
+		state->proc_status = proc_status;
+
+		mutex_lock(&adapter->efuse_mutex);
+		adapter->efuse_map_valid = 1;
+		mutex_unlock(&adapter->efuse_mutex);
+
+		if (adapter->evnt.phy_efuse_map == 1) {
+			PLTFM_EVENT_SIG(FEATURE_DUMP_PHY_EFUSE,
+					proc_status, adapter->efuse_map,
+					adapter->hw_cfg_info.efuse_size);
+			adapter->evnt.phy_efuse_map = 0;
+		}
+
+		if (adapter->evnt.log_efuse_map == 1) {
+			if (eeprom_parser_88xx(adapter, adapter->efuse_map,
+					       map) != HALMAC_RET_SUCCESS) {
+				kfree(map);
+				return HALMAC_RET_EEPROM_PARSING_FAIL;
+			}
+			PLTFM_EVENT_SIG(FEATURE_DUMP_LOG_EFUSE, proc_status,
+					map, eeprom_size);
+			adapter->evnt.log_efuse_map = 0;
+		}
+	} else {
+		proc_status = HALMAC_CMD_PROCESS_ERROR;
+		state->proc_status = proc_status;
+
+		if (adapter->evnt.phy_efuse_map == 1) {
+			PLTFM_EVENT_SIG(FEATURE_DUMP_PHY_EFUSE, proc_status,
+					&state->fw_rc, 1);
+			adapter->evnt.phy_efuse_map = 0;
+		}
+
+		if (adapter->evnt.log_efuse_map == 1) {
+			PLTFM_EVENT_SIG(FEATURE_DUMP_LOG_EFUSE, proc_status,
+					&state->fw_rc, 1);
+			adapter->evnt.log_efuse_map = 0;
+		}
+	}
+
+	kfree(map);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_dump_phy_efuse_status_88xx(struct halmac_adapter *adapter,
+			       enum halmac_cmd_process_status *proc_status,
+			       u8 *data, u32 *size)
+{
+	u8 *map = NULL;
+	u32 efuse_size = adapter->hw_cfg_info.efuse_size;
+	struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
+
+	*proc_status = state->proc_status;
+
+	if (!data)
+		return HALMAC_RET_NULL_POINTER;
+
+	if (!size)
+		return HALMAC_RET_NULL_POINTER;
+
+	if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
+		if (*size < efuse_size) {
+			*size = efuse_size;
+			return HALMAC_RET_BUFFER_TOO_SMALL;
+		}
+
+		*size = efuse_size;
+
+		map = kzalloc(efuse_size, GFP_KERNEL);
+		if (!map)
+			return HALMAC_RET_MALLOC_FAIL;
+		memset(map, 0xFF, efuse_size);
+		mutex_lock(&adapter->efuse_mutex);
+		memcpy(map, adapter->efuse_map,
+		       efuse_size - PROTECT_EFUSE_SIZE);
+		memcpy(map + efuse_size - PROTECT_EFUSE_SIZE +
+		       RSVD_CS_EFUSE_SIZE,
+		       adapter->efuse_map + efuse_size - PROTECT_EFUSE_SIZE +
+		       RSVD_CS_EFUSE_SIZE,
+		       PROTECT_EFUSE_SIZE - RSVD_EFUSE_SIZE -
+		       RSVD_CS_EFUSE_SIZE);
+		mutex_unlock(&adapter->efuse_mutex);
+
+		memcpy(data, map, *size);
+
+		kfree(map);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_dump_log_efuse_status_88xx(struct halmac_adapter *adapter,
+			       enum halmac_cmd_process_status *proc_status,
+			       u8 *data, u32 *size)
+{
+	u8 *map = NULL;
+	u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
+	struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
+
+	*proc_status = state->proc_status;
+
+	if (!data)
+		return HALMAC_RET_NULL_POINTER;
+
+	if (!size)
+		return HALMAC_RET_NULL_POINTER;
+
+	if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
+		if (*size < eeprom_size) {
+			*size = eeprom_size;
+			return HALMAC_RET_BUFFER_TOO_SMALL;
+		}
+
+		*size = eeprom_size;
+
+		map = kzalloc(eeprom_size, GFP_KERNEL);
+		if (!map)
+			return HALMAC_RET_MALLOC_FAIL;
+		memset(map, 0xFF, eeprom_size);
+
+		if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
+		    HALMAC_RET_SUCCESS) {
+			kfree(map);
+			return HALMAC_RET_EEPROM_PARSING_FAIL;
+		}
+
+		memcpy(data, map, *size);
+
+		kfree(map);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_h2c_ack_phy_efuse_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seq_num = 0;
+	u8 fw_rc;
+	struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
+
+	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Seq num : h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("Seq num mismatch : h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not cmd sending\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
+	state->fw_rc = fw_rc;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+u32
+get_rsvd_efuse_size_88xx(struct halmac_adapter *adapter)
+{
+	return PROTECT_EFUSE_SIZE;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.h
new file mode 100644
index 000000000000..2b1f0b199b76
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_efuse_88xx.h
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_EFUSE_88XX_H_
+#define _HALMAC_EFUSE_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+dump_efuse_map_88xx(struct halmac_adapter *adapter,
+		    enum halmac_efuse_read_cfg cfg);
+
+enum halmac_ret_status
+dump_efuse_map_bt_88xx(struct halmac_adapter *adapter,
+		       enum halmac_efuse_bank bank, u32 size, u8 *map);
+
+enum halmac_ret_status
+write_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 value,
+		    enum halmac_efuse_bank bank);
+
+enum halmac_ret_status
+read_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value,
+		   enum halmac_efuse_bank bank);
+
+enum halmac_ret_status
+cfg_efuse_auto_check_88xx(struct halmac_adapter *adapter, u8 enable);
+
+enum halmac_ret_status
+get_efuse_available_size_88xx(struct halmac_adapter *adapter, u32 *size);
+
+enum halmac_ret_status
+get_efuse_size_88xx(struct halmac_adapter *adapter, u32 *size);
+
+enum halmac_ret_status
+get_log_efuse_size_88xx(struct halmac_adapter *adapter, u32 *size);
+
+enum halmac_ret_status
+dump_log_efuse_map_88xx(struct halmac_adapter *adapter,
+			enum halmac_efuse_read_cfg cfg);
+
+enum halmac_ret_status
+read_logical_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value);
+
+enum halmac_ret_status
+write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value);
+
+enum halmac_ret_status
+pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
+		     struct halmac_pg_efuse_info *info,
+		     enum halmac_efuse_read_cfg cfg);
+
+enum halmac_ret_status
+mask_log_efuse_88xx(struct halmac_adapter *adapter,
+		    struct halmac_pg_efuse_info *info);
+
+enum halmac_ret_status
+read_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size, u8 *map);
+
+enum halmac_ret_status
+write_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value);
+
+enum halmac_ret_status
+switch_efuse_bank_88xx(struct halmac_adapter *adapter,
+		       enum halmac_efuse_bank bank);
+
+enum halmac_ret_status
+get_efuse_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+enum halmac_ret_status
+cnv_efuse_state_88xx(struct halmac_adapter *adapter,
+		     enum halmac_cmd_construct_state dest_state);
+
+enum halmac_ret_status
+get_dump_phy_efuse_status_88xx(struct halmac_adapter *adapter,
+			       enum halmac_cmd_process_status *proc_status,
+			       u8 *data, u32 *size);
+
+enum halmac_ret_status
+get_dump_log_efuse_status_88xx(struct halmac_adapter *adapter,
+			       enum halmac_cmd_process_status *proc_status,
+			       u8 *data, u32 *size);
+
+enum halmac_ret_status
+get_h2c_ack_phy_efuse_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+u32
+get_rsvd_efuse_size_88xx(struct halmac_adapter *adapter);
+
+#endif/* _HALMAC_EFUSE_88XX_H_ */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 11/17] rtlwifi: halmac: add files to implement halmac ops
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (8 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 10/17] rtlwifi: halmac: access efuse through halmac helper functions pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 12/17] rtlwifi: halmac: add halmac init/deinit functions pkshih
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

The structure halmac_ops defined in wifi.h, and this commit implements and
hooks ops to the structure, so a symbol rtl_halmac_get_ops_pointer is
expoerted to access this module. Meanwhile, we implement ops defined and
needed by this module.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../wireless/realtek/rtlwifi/halmac/rtl_halmac.c   | 1403 ++++++++++++++++++++
 .../wireless/realtek/rtlwifi/halmac/rtl_halmac.h   |   77 ++
 2 files changed, 1480 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.c b/drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.c
new file mode 100644
index 000000000000..d9b81824728d
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.c
@@ -0,0 +1,1403 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_api.h"
+#include "rtl_halmac.h"
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+
+#define rtlpriv_to_halmac(priv)                                                \
+	((struct halmac_adapter *)((priv)->halmac.internal))
+
+#define DEFAULT_INDICATOR_TIMELMT msecs_to_jiffies(1000) /* ms */
+
+const struct rtl_halmac_ops rtl_halmac_operation = {
+	.halmac_init_adapter = rtl_halmac_init_adapter,
+	.halmac_deinit_adapter = rtl_halmac_deinit_adapter,
+	.halmac_init_hal = rtl_halmac_init_hal,
+	.halmac_deinit_hal = rtl_halmac_deinit_hal,
+	.halmac_poweron = rtl_halmac_poweron,
+	.halmac_poweroff = rtl_halmac_poweroff,
+
+	.halmac_phy_power_switch = rtl_halmac_phy_power_switch,
+	.halmac_set_mac_address = rtl_halmac_set_mac_address,
+	.halmac_set_bssid = rtl_halmac_set_bssid,
+
+	.halmac_get_physical_efuse_size = rtl_halmac_get_physical_efuse_size,
+	.halmac_read_physical_efuse_map = rtl_halmac_read_physical_efuse_map,
+	.halmac_get_logical_efuse_size = rtl_halmac_get_logical_efuse_size,
+	.halmac_read_logical_efuse_map = rtl_halmac_read_logical_efuse_map,
+
+	.halmac_set_bandwidth = rtl_halmac_set_bandwidth,
+
+	.halmac_c2h_handle = rtl_halmac_c2h_handle,
+
+	.halmac_chk_txdesc = rtl_halmac_chk_txdesc,
+	.halmac_iqk = rtl_halmac_iqk,
+};
+EXPORT_SYMBOL(rtl_halmac_operation);
+
+enum pltfm_ret_status {
+	FLTFM_RET_FAIL = 0,
+	FLTFM_RET_SUCCESS = 1,
+};
+
+static u8 _halmac_reg_read_8(void *p, u32 offset)
+{
+	struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+	return rtl_read_byte(rtlpriv, offset);
+}
+
+static u16 _halmac_reg_read_16(void *p, u32 offset)
+{
+	struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+	return rtl_read_word(rtlpriv, offset);
+}
+
+static u32 _halmac_reg_read_32(void *p, u32 offset)
+{
+	struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+	return rtl_read_dword(rtlpriv, offset);
+}
+
+static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
+{
+	struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+	rtl_write_byte(rtlpriv, offset, val);
+}
+
+static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
+{
+	struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+	rtl_write_word(rtlpriv, offset, val);
+}
+
+static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
+{
+	struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+	rtl_write_dword(rtlpriv, offset, val);
+}
+
+static u8 _halmac_write_data_rsvd_page(void *p, u8 *buf, u32 size)
+{
+	struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+	if (rtlpriv->cfg->ops->halmac_cb_write_data_rsvd_page &&
+	    rtlpriv->cfg->ops->halmac_cb_write_data_rsvd_page(rtlpriv, buf,
+							      size))
+		return FLTFM_RET_SUCCESS;
+
+	return FLTFM_RET_FAIL;
+}
+
+static u8 _halmac_write_data_h2c(void *p, u8 *buf, u32 size)
+{
+	struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
+
+	if (rtlpriv->cfg->ops->halmac_cb_write_data_h2c &&
+	    rtlpriv->cfg->ops->halmac_cb_write_data_h2c(rtlpriv, buf, size))
+		return FLTFM_RET_SUCCESS;
+
+	return FLTFM_RET_FAIL;
+}
+
+static const char *const RTL_HALMAC_FEATURE_NAME[] = {
+	"HALMAC_FEATURE_CFG_PARA",
+	"HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
+	"HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
+	"HALMAC_FEATURE_UPDATE_PACKET",
+	"HALMAC_FEATURE_UPDATE_DATAPACK",
+	"HALMAC_FEATURE_RUN_DATAPACK",
+	"HALMAC_FEATURE_CHANNEL_SWITCH",
+	"HALMAC_FEATURE_IQK",
+	"HALMAC_FEATURE_POWER_TRACKING",
+	"HALMAC_FEATURE_PSD",
+	"HALMAC_FEATURE_ALL"};
+
+static inline bool is_valid_id_status(struct rtl_priv *rtlpriv,
+				      enum halmac_feature_id id,
+				      enum halmac_cmd_process_status status)
+{
+	switch (id) {
+	case HALMAC_FEATURE_CFG_PARA:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		if (status != HALMAC_CMD_PROCESS_DONE) {
+			RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+				 "%s: <WARN> id(%d) unspecified status(%d)!\n",
+				 __func__, id, status);
+		}
+		break;
+	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		if (status != HALMAC_CMD_PROCESS_DONE) {
+			RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+				 "%s: <WARN> id(%d) unspecified status(%d)!\n",
+				 __func__, id, status);
+		}
+		break;
+	case HALMAC_FEATURE_UPDATE_PACKET:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	case HALMAC_FEATURE_UPDATE_DATAPACK:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	case HALMAC_FEATURE_RUN_DATAPACK:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	case HALMAC_FEATURE_CHANNEL_SWITCH:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	case HALMAC_FEATURE_IQK:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	case HALMAC_FEATURE_POWER_TRACKING:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	case HALMAC_FEATURE_PSD:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	case HALMAC_FEATURE_ALL:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
+			 RTL_HALMAC_FEATURE_NAME[id]);
+		break;
+	default:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+			 "%s: unknown feature id(%d)\n", __func__, id);
+		return false;
+	}
+
+	return true;
+}
+
+static int init_halmac_event_with_waittime(struct rtl_priv *rtlpriv,
+					   enum halmac_feature_id id, u8 *buf,
+					   u32 size, u32 time)
+{
+	struct rtl_halmac_indicator *indicator = &rtlpriv->halmac.indicator[id];
+	struct completion *comp = indicator->comp;
+
+	if (!comp) {
+		comp = kzalloc(sizeof(*comp), GFP_KERNEL);
+		if (!comp)
+			return -ENOMEM;
+	} else {
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+			 "%s: <WARN> id(%d) sctx is not NULL!!\n", __func__,
+			 id);
+		indicator->comp = NULL;
+	}
+
+	init_completion(comp);
+	indicator->wait_ms = time;
+	indicator->buffer = buf;
+	indicator->buf_size = size;
+	indicator->ret_size = 0;
+	indicator->status = 0;
+
+	/* fill sctx at least to sure other variables are all ready! */
+	indicator->comp = comp;
+
+	return 0;
+}
+
+static inline int init_halmac_event(struct rtl_priv *rtlpriv,
+				    enum halmac_feature_id id, u8 *buf,
+				    u32 size)
+{
+	return init_halmac_event_with_waittime(rtlpriv, id, buf, size,
+					       DEFAULT_INDICATOR_TIMELMT);
+}
+
+static void free_halmac_event(struct rtl_priv *rtlpriv,
+			      enum halmac_feature_id id)
+{
+	struct rtl_halmac_indicator *indicator = &rtlpriv->halmac.indicator[id];
+	struct completion *comp = indicator->comp;
+
+	if (!comp)
+		return;
+
+	indicator->comp = NULL;
+	kfree(comp);
+}
+
+static int wait_halmac_event(struct rtl_priv *rtlpriv,
+			     enum halmac_feature_id id)
+{
+	struct rtl_halmac_indicator *indicator;
+	int ret;
+
+	indicator = &rtlpriv->halmac.indicator[id];
+
+	if (!indicator->comp)
+		return -EINVAL;
+
+	ret = wait_for_completion_timeout(indicator->comp, indicator->wait_ms);
+
+	free_halmac_event(rtlpriv, id);
+	if (ret > 0)
+		return 0;
+
+	return -ETIME;
+}
+
+static u8
+_halmac_event_indication(void *p, enum halmac_feature_id feature_id,
+			 enum halmac_cmd_process_status process_status, u8 *buf,
+			 u32 size)
+{
+	struct rtl_priv *rtlpriv;
+	struct rtl_halmac_indicator *tbl, *indicator;
+	struct completion *comp;
+	u32 cpsz;
+
+	rtlpriv = (struct rtl_priv *)p;
+	tbl = rtlpriv->halmac.indicator;
+
+	if (!is_valid_id_status(rtlpriv, feature_id, process_status))
+		return FLTFM_RET_FAIL;
+
+	indicator = &tbl[feature_id];
+	indicator->status = process_status;
+	indicator->ret_size = size;
+	if (!indicator->comp) {
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+			 "%s: No feature id(%d) waiting!!\n", __func__,
+			 feature_id);
+		return FLTFM_RET_FAIL;
+	}
+	comp = indicator->comp;
+
+	if (process_status == HALMAC_CMD_PROCESS_ERROR) {
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+			 "%s: Something wrong id(%d)!!\n", __func__,
+			 feature_id);
+		complete(comp); /* may provide error code */
+		return FLTFM_RET_SUCCESS;
+	}
+
+	if (size > indicator->buf_size) {
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+			 "%s: <WARN> id(%d) buffer is not enough(%d<%d), data will be truncated!\n",
+			 __func__, feature_id, indicator->buf_size, size);
+		cpsz = indicator->buf_size;
+	} else {
+		cpsz = size;
+	}
+
+	if (cpsz && indicator->buffer)
+		memcpy(indicator->buffer, buf, cpsz);
+
+	complete(comp);
+
+	return FLTFM_RET_SUCCESS;
+}
+
+static struct halmac_platform_api rtl_halmac_platform_api = {
+	/* R/W register */
+	.REG_READ_8 = _halmac_reg_read_8,
+	.REG_READ_16 = _halmac_reg_read_16,
+	.REG_READ_32 = _halmac_reg_read_32,
+	.REG_WRITE_8 = _halmac_reg_write_8,
+	.REG_WRITE_16 = _halmac_reg_write_16,
+	.REG_WRITE_32 = _halmac_reg_write_32,
+
+	/* impletement in HAL-IC level */
+	.SEND_RSVD_PAGE = _halmac_write_data_rsvd_page,
+	.SEND_H2C_PKT = _halmac_write_data_h2c,
+	.EVENT_INDICATION = _halmac_event_indication,
+};
+
+static int init_priv(struct rtl_halmac *halmac)
+{
+	struct rtl_halmac_indicator *indicator;
+	u32 count, size;
+
+	count = HALMAC_FEATURE_ALL + 1;
+	size = sizeof(*indicator) * count;
+	indicator = kzalloc(size, GFP_KERNEL);
+	if (!indicator)
+		return -EINVAL;
+	halmac->indicator = indicator;
+
+	return 0;
+}
+
+static void deinit_priv(struct rtl_halmac *halmac)
+{
+	struct rtl_halmac_indicator *indicator;
+
+	indicator = halmac->indicator;
+	halmac->indicator = NULL;
+	kfree(indicator);
+}
+
+int rtl_halmac_init_adapter(struct rtl_priv *rtlpriv)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	enum halmac_interface intf;
+	enum halmac_ret_status status;
+	int err = 0;
+	struct halmac_platform_api *pf_api = &rtl_halmac_platform_api;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	if (halmac) {
+		err = 0;
+		goto out;
+	}
+
+	err = init_priv(&rtlpriv->halmac);
+	if (err)
+		goto out;
+
+	intf = HALMAC_INTERFACE_PCIE;
+	status = halmac_init_adapter(rtlpriv, pf_api, intf, &halmac, &api);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("%s: halmac_init_adapter fail!(status=%d)\n",
+		       __func__, status);
+		err = -EINVAL;
+		goto out;
+	}
+
+	rtlpriv->halmac.internal = halmac;
+
+	status = api->halmac_interface_integration_tuning(halmac);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("%s: halmac_interface_integration_tuning fail!(status=%d)\n",
+		       __func__, status);
+		err = -EINVAL;
+		goto out;
+	}
+
+	status = api->halmac_phy_cfg(halmac, HALMAC_INTF_PHY_PLATFORM_ALL);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("%s: halmac_phy_cfg fail!(status=%d)\n",
+		       __func__, status);
+		err = -EINVAL;
+		goto out;
+	}
+
+out:
+	if (err)
+		rtl_halmac_deinit_adapter(rtlpriv);
+
+	return err;
+}
+
+int rtl_halmac_deinit_adapter(struct rtl_priv *rtlpriv)
+{
+	struct halmac_adapter *halmac;
+	enum halmac_ret_status status;
+	int err = 0;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	if (!halmac) {
+		err = 0;
+		goto out;
+	}
+
+	deinit_priv(&rtlpriv->halmac);
+
+	halmac_halt_api(halmac);
+
+	status = halmac_deinit_adapter(halmac);
+	rtlpriv->halmac.internal = NULL;
+	if (status != HALMAC_RET_SUCCESS) {
+		err = -EINVAL;
+		goto out;
+	}
+
+out:
+	return err;
+}
+
+int rtl_halmac_poweron(struct rtl_priv *rtlpriv)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	int err = -EINVAL;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	if (!halmac)
+		goto out;
+
+	api = HALMAC_GET_API(halmac);
+
+	status = api->halmac_pre_init_system_cfg(halmac);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	status = api->halmac_init_system_cfg(halmac);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = 0;
+out:
+	return err;
+}
+
+int rtl_halmac_poweroff(struct rtl_priv *rtlpriv)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	int err = -EINVAL;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	if (!halmac)
+		goto out;
+
+	api = HALMAC_GET_API(halmac);
+
+	status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = 0;
+out:
+	return err;
+}
+
+int rtl_halmac_config_rx_info(struct rtl_priv *rtlpriv,
+			      enum halmac_drv_info info)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	int err = -EINVAL;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(halmac);
+
+	status = api->halmac_cfg_drv_info(halmac, info);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = 0;
+out:
+	return err;
+}
+
+static enum halmac_ret_status init_mac_flow(struct rtl_priv *rtlpriv)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	enum halmac_trx_mode trx_mode;
+	enum halmac_wireless_mode mode;
+	u8 wifi_test = 0;
+	int err;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(halmac);
+
+	if (wifi_test)
+		trx_mode = HALMAC_TRX_MODE_WMM;
+	else
+		trx_mode = HALMAC_TRX_MODE_NORMAL;
+
+	status = api->halmac_init_mac_cfg(halmac, trx_mode);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = rtl_halmac_rx_agg_switch(rtlpriv, true);
+	if (err)
+		goto out;
+
+	if (rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS7])
+		mode = HALMAC_WIRELESS_MODE_AC;
+	else if (rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7])
+		mode = HALMAC_WIRELESS_MODE_N;
+	else if (rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M])
+		mode = HALMAC_WIRELESS_MODE_G;
+	else
+		mode = HALMAC_WIRELESS_MODE_B;
+
+	status = api->halmac_cfg_operation_mode(halmac, mode);
+
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+out:
+	return status;
+}
+
+static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv)
+{
+	enum halmac_rf_type rf_mac;
+
+	switch (rf_drv) {
+	case RF_1T2R:
+		rf_mac = HALMAC_RF_1T2R;
+		break;
+	case RF_2T2R:
+		rf_mac = HALMAC_RF_2T2R;
+		break;
+	case RF_1T1R:
+		rf_mac = HALMAC_RF_1T1R;
+		break;
+	case RF_2T2R_GREEN:
+		rf_mac = HALMAC_RF_2T2R_GREEN;
+		break;
+	default:
+		rf_mac = HALMAC_RF_1T1R;
+		break;
+	}
+
+	return rf_mac;
+}
+
+static enum bb_path _rf_type_to_ant_path(enum rf_type rf)
+{
+	enum bb_path path;
+
+	switch (rf) {
+	case RF_1T1R:
+	case RF_1T2R:
+		path = BB_PATH_A;
+		break;
+	case RF_2T2R:
+	case RF_2T3R:
+	case RF_2T4R:
+		path = BB_PATH_AB;
+		break;
+	case RF_3T3R:
+	case RF_3T4R:
+		path = BB_PATH_ABC;
+		break;
+	case RF_4T4R:
+	default:
+		path = BB_PATH_ABCD;
+		break;
+	}
+
+	return path;
+}
+
+static int _send_general_info(struct rtl_priv *rtlpriv)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	struct halmac_general_info info;
+	enum halmac_ret_status status;
+	enum bb_path path = BB_PATH_A;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	if (!halmac)
+		return -EINVAL;
+	api = HALMAC_GET_API(halmac);
+
+	memset(&info, 0, sizeof(info));
+	info.rfe_type = rtlpriv->rtlhal.rfe_type;
+	info.rf_type = _rf_type_drv2halmac(rtlpriv->phy.rf_type);
+	path = _rf_type_to_ant_path(rtlpriv->phy.rf_type);
+	info.tx_ant_status = (u8)path;
+	info.rx_ant_status = (u8)path;
+
+	status = api->halmac_send_general_info(halmac, &info);
+	switch (status) {
+	case HALMAC_RET_SUCCESS:
+		break;
+	case HALMAC_RET_NO_DLFW:
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_WARNING,
+			 "%s: halmac_send_general_info() fail because fw not dl!\n",
+			 __func__);
+	/* fall through */
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int _halmac_init_hal(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	bool ok;
+	bool fw_ok = false;
+	int err, err_ret = -EINVAL;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	if (!halmac)
+		goto out;
+	api = HALMAC_GET_API(halmac);
+
+	/* StatePowerOff */
+	err = rtl_halmac_poweron(rtlpriv);
+	if (err)
+		goto out;
+
+	/* StatePowerOn */
+
+	/* DownloadFW */
+	if (fw && fwsize) {
+		err = rtl_halmac_dlfw(rtlpriv, fw, fwsize, 0);
+		if (err)
+			goto out;
+		fw_ok = true;
+	}
+
+	/* InitMACFlow */
+	status = init_mac_flow(rtlpriv);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	/* halmac_send_general_info */
+	if (fw_ok) {
+		err = _send_general_info(rtlpriv);
+		if (err)
+			goto out;
+	}
+
+	/* Init Phy parameter-MAC */
+	if (rtlpriv->cfg->ops->halmac_cb_init_mac_register)
+		ok = rtlpriv->cfg->ops->halmac_cb_init_mac_register(rtlpriv);
+	else
+		ok = false;
+
+	if (!ok)
+		goto out;
+
+	/* StateMacInitialized */
+
+	/* halmac_cfg_drv_info */
+	err = rtl_halmac_config_rx_info(rtlpriv, HALMAC_DRV_INFO_PHY_STATUS);
+	if (err)
+		goto out;
+
+	/* Init BB, RF */
+	if (rtlpriv->cfg->ops->halmac_cb_init_bb_rf_register)
+		ok = rtlpriv->cfg->ops->halmac_cb_init_bb_rf_register(rtlpriv);
+	else
+		ok = false;
+
+	if (!ok)
+		goto out;
+
+	status = api->halmac_init_interface_cfg(halmac);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	/* StateRxIdle */
+
+	err_ret = 0;
+out:
+	return err_ret;
+}
+
+int rtl_halmac_init_hal(struct rtl_priv *rtlpriv)
+{
+	if (!rtlpriv->rtlhal.pfirmware || rtlpriv->rtlhal.fwsize == 0)
+		return -EINVAL;
+
+	return _halmac_init_hal(rtlpriv, rtlpriv->rtlhal.pfirmware,
+				rtlpriv->rtlhal.fwsize);
+}
+
+int rtl_halmac_deinit_hal(struct rtl_priv *rtlpriv)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	int err = -EINVAL;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	if (!halmac)
+		goto out;
+	api = HALMAC_GET_API(halmac);
+
+	status = api->halmac_deinit_interface_cfg(halmac);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = 0;
+out:
+	return err;
+}
+
+int rtl_halmac_self_verify(struct rtl_priv *rtlpriv)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	int err = -EINVAL;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	status = api->halmac_verify_platform_api(mac);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	status = api->halmac_h2c_lb(mac);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = 0;
+out:
+	return err;
+}
+
+int rtl_halmac_dlfw(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize, bool redl)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	struct halmac_fw_version fw_version;
+	int err = 0;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	if (!fw || fwsize == 0)
+		return -EINVAL;
+
+	/* 1. Driver Stop Tx */
+	/* ToDo */
+
+	/* 2. Driver Check Tx FIFO is empty */
+	/* ToDo */
+
+	/* 3. Config MAX download size */
+	api->halmac_cfg_max_dl_size(mac, 0x1000);
+
+	/* 4. Download Firmware */
+	status = api->halmac_download_firmware(mac, fw, fwsize);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	status = api->halmac_get_fw_version(mac, &fw_version);
+	if (status == HALMAC_RET_SUCCESS) {
+		rtlpriv->rtlhal.fw_version = fw_version.version;
+		rtlpriv->rtlhal.fw_subversion =
+			(fw_version.sub_version << 8) | (fw_version.sub_index);
+
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_DMESG,
+			 "halmac report firmware version %04X.%04X\n",
+			 rtlpriv->rtlhal.fw_version,
+			 rtlpriv->rtlhal.fw_subversion);
+	}
+
+	if (redl)
+		err = _send_general_info(rtlpriv);
+
+	/* 5. Driver resume TX if needed */
+	/* ToDo */
+
+	/* 6. Reset driver variables if needed */
+
+	return err;
+}
+
+int rtl_halmac_phy_power_switch(struct rtl_priv *rtlpriv, u8 enable)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	if (!halmac)
+		return -EINVAL;
+	api = HALMAC_GET_API(halmac);
+
+	status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &enable);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	return 0;
+}
+
+static bool _is_fw_read_cmd_down(struct rtl_priv *rtlpriv, u8 msgbox_num)
+{
+	bool read_down = false;
+	int retry_cnts = 100;
+	u8 valid;
+
+	RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+		 "%s, reg_1cc(%x), msg_box(%d)...\n", __func__,
+		 rtl_read_byte(rtlpriv, REG_HMETFR), msgbox_num);
+
+	do {
+		valid = rtl_read_byte(rtlpriv, REG_HMETFR) & BIT(msgbox_num);
+		if (valid == 0)
+			read_down = true;
+		else
+			schedule();
+	} while ((!read_down) && (retry_cnts--));
+
+	return read_down;
+}
+
+/* for H2C cmd */
+#define MAX_H2C_BOX_NUMS 4
+#define MESSAGE_BOX_SIZE 4
+#define EX_MESSAGE_BOX_SIZE 4
+
+int rtl_halmac_send_h2c(struct rtl_priv *rtlpriv, u8 *h2c)
+{
+	u8 h2c_box_num = 0;
+	u32 msgbox_addr = 0;
+	u32 msgbox_ex_addr = 0;
+	__le32 h2c_cmd = 0;
+	__le32 h2c_cmd_ex = 0;
+	s32 ret = -EINVAL;
+	unsigned long flag = 0;
+	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+	if (!h2c) {
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: pbuf is NULL\n",
+			 __func__);
+		return ret;
+	}
+
+	spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+
+	/* pay attention to if race condition happened in  H2C cmd setting */
+	h2c_box_num = rtlhal->last_hmeboxnum;
+
+	if (!_is_fw_read_cmd_down(rtlpriv, h2c_box_num)) {
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+			 " fw read cmd failed...\n");
+		goto exit;
+	}
+
+	/* Write Ext command(byte 4 -7) */
+	msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
+	memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
+	rtl_write_dword(rtlpriv, msgbox_ex_addr, le32_to_cpu(h2c_cmd_ex));
+
+	/* Write command (byte 0 -3 ) */
+	msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
+	memcpy((u8 *)(&h2c_cmd), h2c, 4);
+	rtl_write_dword(rtlpriv, msgbox_addr, le32_to_cpu(h2c_cmd));
+
+	/* update last msg box number */
+	rtlhal->last_hmeboxnum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
+	ret = 0;
+
+exit:
+	spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+	return ret;
+}
+
+int rtl_halmac_c2h_handle(struct rtl_priv *rtlpriv, u8 *c2h, u32 size)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	status = api->halmac_get_c2h_info(mac, c2h, size);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rtl_halmac_get_physical_efuse_size(struct rtl_priv *rtlpriv, u32 *size)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	u32 val;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	status = api->halmac_get_efuse_size(mac, &val);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	*size = val;
+	return 0;
+}
+
+int rtl_halmac_read_physical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+				       u32 size)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	enum halmac_feature_id id;
+	int ret;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+	id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
+
+	ret = init_halmac_event(rtlpriv, id, map, size);
+	if (ret)
+		return -EINVAL;
+
+	status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
+	if (status != HALMAC_RET_SUCCESS) {
+		free_halmac_event(rtlpriv, id);
+		return -EINVAL;
+	}
+
+	ret = wait_halmac_event(rtlpriv, id);
+	if (ret)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rtl_halmac_read_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+				   u32 cnt, u8 *data)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	u8 v;
+	u32 i;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	for (i = 0; i < cnt; i++) {
+		status = api->halmac_read_efuse(mac, offset + i, &v);
+		if (status != HALMAC_RET_SUCCESS)
+			return -EINVAL;
+		data[i] = v;
+	}
+
+	return 0;
+}
+
+int rtl_halmac_write_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+				    u32 cnt, u8 *data)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	u32 i;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	for (i = 0; i < cnt; i++) {
+		status = api->halmac_write_efuse(mac, offset + i, data[i]);
+		if (status != HALMAC_RET_SUCCESS)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+int rtl_halmac_get_logical_efuse_size(struct rtl_priv *rtlpriv, u32 *size)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	u32 val;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	status = api->halmac_get_logical_efuse_size(mac, &val);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	*size = val;
+	return 0;
+}
+
+int rtl_halmac_read_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+				      u32 size)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	enum halmac_feature_id id;
+	int ret;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+	id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
+
+	ret = init_halmac_event(rtlpriv, id, map, size);
+	if (ret)
+		return -EINVAL;
+
+	status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_AUTO);
+	if (status != HALMAC_RET_SUCCESS) {
+		free_halmac_event(rtlpriv, id);
+		return -EINVAL;
+	}
+
+	ret = wait_halmac_event(rtlpriv, id);
+	if (ret)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rtl_halmac_write_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+				       u32 size, u8 *maskmap, u32 masksize)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	struct halmac_pg_efuse_info pginfo;
+	enum halmac_ret_status status;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	pginfo.efuse_map = map;
+	pginfo.efuse_map_size = size;
+	pginfo.efuse_mask = maskmap;
+	pginfo.efuse_mask_size = masksize;
+
+	status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rtl_halmac_read_logical_efuse(struct rtl_priv *rtlpriv, u32 offset, u32 cnt,
+				  u8 *data)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	u8 v;
+	u32 i;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	for (i = 0; i < cnt; i++) {
+		status = api->halmac_read_logical_efuse(mac, offset + i, &v);
+		if (status != HALMAC_RET_SUCCESS)
+			return -EINVAL;
+		data[i] = v;
+	}
+
+	return 0;
+}
+
+int rtl_halmac_write_logical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+				   u32 cnt, u8 *data)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	u32 i;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	for (i = 0; i < cnt; i++) {
+		status = api->halmac_write_logical_efuse(mac, offset + i,
+							 data[i]);
+		if (status != HALMAC_RET_SUCCESS)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+int rtl_halmac_set_mac_address(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	u8 port;
+	union halmac_wlan_addr hwa;
+	enum halmac_ret_status status;
+	int err = -EINVAL;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(halmac);
+
+	port = hwport;
+	memset(&hwa, 0, sizeof(hwa));
+	ether_addr_copy(hwa.addr, addr);
+
+	status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = 0;
+out:
+	return err;
+}
+
+int rtl_halmac_set_bssid(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	u8 port;
+	union halmac_wlan_addr hwa;
+	enum halmac_ret_status status;
+	int err = -EINVAL;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(halmac);
+	port = hwport;
+
+	memset(&hwa, 0, sizeof(hwa));
+	ether_addr_copy(hwa.addr, addr);
+	status = api->halmac_cfg_bssid(halmac, port, &hwa);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = 0;
+out:
+	return err;
+}
+
+int rtl_halmac_set_bandwidth(struct rtl_priv *rtlpriv, u8 channel,
+			     u8 pri_ch_idx, u8 bw)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rtl_halmac_get_hw_value(struct rtl_priv *rtlpriv, enum halmac_hw_id hw_id,
+			    void *pvalue)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	status = api->halmac_get_hw_value(mac, hw_id, pvalue);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rtl_halmac_dump_fifo(struct rtl_priv *rtlpriv,
+			 enum hal_fifo_sel halmac_fifo_sel)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	u8 *pfifo_map = NULL;
+	u32 fifo_size = 0;
+	s8 ret = 0;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
+	if (fifo_size)
+		pfifo_map = vmalloc(fifo_size);
+	if (!pfifo_map)
+		return -EINVAL;
+
+	status = api->halmac_dump_fifo(mac, halmac_fifo_sel, 0, fifo_size,
+				       pfifo_map);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		ret = -EINVAL;
+		goto _exit;
+	}
+
+_exit:
+	if (pfifo_map)
+		vfree(pfifo_map);
+	return ret;
+}
+
+int rtl_halmac_rx_agg_switch(struct rtl_priv *rtlpriv, bool enable)
+{
+	struct halmac_adapter *halmac;
+	struct halmac_api *api;
+	struct halmac_rxagg_cfg rxaggcfg;
+	enum halmac_ret_status status;
+	int err = -EINVAL;
+
+	halmac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(halmac);
+	memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
+
+	if (enable) {
+		/* enable RX agg. */
+		/* PCIE do nothing */
+	} else {
+		/* disable RX agg. */
+		rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
+	}
+
+	status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
+	if (status != HALMAC_RET_SUCCESS)
+		goto out;
+
+	err = 0;
+out:
+	return err;
+}
+
+int rtl_halmac_get_wow_reason(struct rtl_priv *rtlpriv, u8 *reason)
+{
+	u8 val8;
+	int err = -EINVAL;
+
+	val8 = rtl_read_byte(rtlpriv, 0x1C7);
+	if (val8 == 0xEA)
+		goto out;
+
+	*reason = val8;
+	err = 0;
+out:
+	return err;
+}
+
+int rtl_halmac_get_drv_info_sz(struct rtl_priv *rtlpriv, u8 *sz)
+{
+	u8 dw = 6; /* max number */
+
+	*sz = dw * 8;
+	return 0;
+}
+
+int rtl_halmac_get_rsvd_drv_pg_bndy(struct rtl_priv *rtlpriv, u16 *drv_pg)
+{
+	enum halmac_ret_status status;
+	struct halmac_adapter *halmac = rtlpriv_to_halmac(rtlpriv);
+	struct halmac_api *api = HALMAC_GET_API(halmac);
+
+	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY,
+					  drv_pg);
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rtl_halmac_chk_txdesc(struct rtl_priv *rtlpriv, u8 *txdesc, u32 size)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+
+	status = api->halmac_chk_txdesc(mac, txdesc, size);
+
+	if (status != HALMAC_RET_SUCCESS)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rtl_halmac_iqk(struct rtl_priv *rtlpriv, u8 clear, u8 segment)
+{
+	struct halmac_adapter *mac;
+	struct halmac_api *api;
+	enum halmac_ret_status status;
+	enum halmac_feature_id id;
+	struct halmac_iqk_para para;
+	int ret;
+	u8 retry = 3;
+	u8 delay = 1; /* ms */
+	unsigned long us;
+
+	mac = rtlpriv_to_halmac(rtlpriv);
+	api = HALMAC_GET_API(mac);
+	id = HALMAC_FEATURE_IQK;
+
+	ret = init_halmac_event(rtlpriv, id, NULL, 0);
+	if (ret)
+		return -EINVAL;
+
+	para.clear = clear;
+	para.segment_iqk = segment;
+
+	do {
+		status = api->halmac_start_iqk(mac, &para);
+		if (status != HALMAC_RET_BUSY_STATE)
+			break;
+		RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
+			 "%s: Fail to start IQK, status is BUSY! retry=%d\n",
+			 __func__, retry);
+
+		if (!retry)
+			break;
+		retry--;
+
+		if (delay < 20) {
+			us = delay * 1000UL;
+			usleep_range(us, us + 1000UL);
+		} else {
+			msleep(delay);
+		}
+
+	} while (1);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		free_halmac_event(rtlpriv, id);
+		return -EINVAL;
+	}
+
+	ret = wait_halmac_event(rtlpriv, id);
+	if (ret)
+		return -EINVAL;
+
+	return 0;
+}
+
+MODULE_AUTHOR("Ping-Ke Shih	<pkshih@realtek.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 802.11n PCI wireless module hamlac");
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.h b/drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.h
new file mode 100644
index 000000000000..33cd2f913697
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/rtl_halmac.h
@@ -0,0 +1,77 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _RTL_HALMAC_H_
+#define _RTL_HALMAC_H_
+
+#include "halmac_api.h"
+
+int rtl_halmac_init_adapter(struct rtl_priv *rtlpriv);
+int rtl_halmac_deinit_adapter(struct rtl_priv *rtlpriv);
+int rtl_halmac_poweron(struct rtl_priv *rtlpriv);
+int rtl_halmac_poweroff(struct rtl_priv *rtlpriv);
+int rtl_halmac_init_hal(struct rtl_priv *rtlpriv);
+int rtl_halmac_init_hal_fw(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize);
+int rtl_halmac_init_hal_fw_file(struct rtl_priv *rtlpriv, u8 *fwpath);
+int rtl_halmac_deinit_hal(struct rtl_priv *rtlpriv);
+int rtl_halmac_self_verify(struct rtl_priv *rtlpriv);
+int rtl_halmac_dlfw(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize, bool redl);
+int rtl_halmac_dlfw_from_file(struct rtl_priv *rtlpriv, u8 *fwpath);
+int rtl_halmac_phy_power_switch(struct rtl_priv *rtlpriv, u8 enable);
+int rtl_halmac_send_h2c(struct rtl_priv *rtlpriv, u8 *h2c);
+int rtl_halmac_c2h_handle(struct rtl_priv *rtlpriv, u8 *c2h, u32 size);
+
+int rtl_halmac_get_physical_efuse_size(struct rtl_priv *rtlpriv, u32 *size);
+int rtl_halmac_read_physical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+				       u32 size);
+int rtl_halmac_read_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+				   u32 cnt, u8 *data);
+int rtl_halmac_write_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+				    u32 cnt, u8 *data);
+int rtl_halmac_get_logical_efuse_size(struct rtl_priv *rtlpriv, u32 *size);
+int rtl_halmac_read_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+				      u32 size);
+int rtl_halmac_write_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
+				       u32 size, u8 *maskmap, u32 masksize);
+int rtl_halmac_read_logical_efuse(struct rtl_priv *rtlpriv, u32 offset, u32 cnt,
+				  u8 *data);
+int rtl_halmac_write_logical_efuse(struct rtl_priv *rtlpriv, u32 offset,
+				   u32 cnt, u8 *data);
+
+int rtl_halmac_config_rx_info(struct rtl_priv *rtlpriv, enum halmac_drv_info);
+int rtl_halmac_set_mac_address(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr);
+int rtl_halmac_set_bssid(struct rtl_priv *d, u8 hwport, u8 *addr);
+
+int rtl_halmac_set_bandwidth(struct rtl_priv *rtlpriv, u8 channel,
+			     u8 pri_ch_idx, u8 bw);
+int rtl_halmac_rx_agg_switch(struct rtl_priv *rtlpriv, bool enable);
+int rtl_halmac_get_hw_value(struct rtl_priv *d, enum halmac_hw_id hw_id,
+			    void *pvalue);
+int rtl_halmac_dump_fifo(struct rtl_priv *rtlpriv,
+			 enum hal_fifo_sel halmac_fifo_sel);
+
+int rtl_halmac_get_wow_reason(struct rtl_priv *rtlpriv, u8 *reason);
+int rtl_halmac_get_drv_info_sz(struct rtl_priv *d, u8 *sz);
+
+int rtl_halmac_get_rsvd_drv_pg_bndy(struct rtl_priv *dvobj, u16 *drv_pg);
+int rtl_halmac_download_rsvd_page(struct rtl_priv *dvobj, u8 pg_offset,
+				  u8 *pbuf, u32 size);
+
+int rtl_halmac_chk_txdesc(struct rtl_priv *rtlpriv, u8 *txdesc, u32 size);
+int rtl_halmac_iqk(struct rtl_priv *rtlpriv, u8 clear, u8 segment);
+
+extern const struct rtl_halmac_ops rtl_halmac_operation;
+
+#endif /* _RTL_HALMAC_H_ */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 12/17] rtlwifi: halmac: add halmac init/deinit functions
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (9 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 11/17] rtlwifi: halmac: add files to implement halmac ops pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 13/17] rtlwifi: halmac: add firmware related functions and definitions pkshih
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

Add files to initialize and free halmac context. Since halmac is an three
levels hierarchy file structure, so the added files provide interfaces of
halmac, 88xx and 8822b.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../halmac_88xx/halmac_8822b/halmac_init_8822b.c   |  688 +++++++++++++
 .../halmac_88xx/halmac_8822b/halmac_init_8822b.h   |   33 +
 .../rtlwifi/halmac/halmac_88xx/halmac_init_88xx.c  | 1071 ++++++++++++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_init_88xx.h  |   70 ++
 .../wireless/realtek/rtlwifi/halmac/halmac_api.c   |  438 ++++++++
 .../wireless/realtek/rtlwifi/halmac/halmac_api.h   |   65 ++
 6 files changed, 2365 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c
new file mode 100644
index 000000000000..57509fd5942a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.c
@@ -0,0 +1,688 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_init_8822b.h"
+#include "halmac_8822b_cfg.h"
+#include "halmac_pcie_8822b.h"
+#include "halmac_sdio_8822b.h"
+#include "halmac_usb_8822b.h"
+#include "halmac_gpio_8822b.h"
+#include "halmac_common_8822b.h"
+#include "halmac_cfg_wmac_8822b.h"
+#include "../halmac_common_88xx.h"
+#include "../halmac_init_88xx.h"
+
+#define RSVD_PG_DRV_NUM			16
+#define RSVD_PG_H2C_EXTRAINFO_NUM	24
+#define RSVD_PG_H2C_STATICINFO_NUM	8
+#define RSVD_PG_H2CQ_NUM		8
+#define RSVD_PG_CPU_INSTRUCTION_NUM	0
+#define RSVD_PG_FW_TXBUF_NUM		4
+#define RSVD_PG_CSIBUF_NUM		0
+#define RSVD_PG_DLLB_NUM		(TX_FIFO_SIZE_8822B / 3 >> \
+					TX_PAGE_SIZE_SHIFT_88XX)
+
+#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 BLK_DESC_NUM	0x3
+
+#define WLAN_AMPDU_MAX_TIME		0x70
+#define WLAN_RTS_LEN_TH			0xFF
+#define WLAN_RTS_TX_TIME_TH		0x08
+#define WLAN_MAX_AGG_PKT_LIMIT		0x20
+#define WLAN_RTS_MAX_AGG_PKT_LIMIT	0x20
+#define WALN_FAST_EDCA_VO_TH		0x06
+#define WLAN_FAST_EDCA_VI_TH		0x06
+#define WLAN_FAST_EDCA_BE_TH		0x06
+#define WLAN_FAST_EDCA_BK_TH		0x06
+#define WLAN_BAR_RETRY_LIMIT		0x01
+#define WLAN_RA_TRY_RATE_AGG_LIMIT	0x08
+
+/*SDIO RQPN Mapping*/
+static struct halmac_rqpn HALMAC_RQPN_SDIO_8822B[] = {
+	/* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+	{HALMAC_TRX_MODE_NORMAL,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_TRXSHARE,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_WMM,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_P2P,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_LOOPBACK,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+};
+
+/*PCIE RQPN Mapping*/
+static struct halmac_rqpn HALMAC_RQPN_PCIE_8822B[] = {
+	/* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+	{HALMAC_TRX_MODE_NORMAL,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_TRXSHARE,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_WMM,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_P2P,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_LOOPBACK,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+};
+
+/*USB 2 Bulkout RQPN Mapping*/
+static struct halmac_rqpn HALMAC_RQPN_2BULKOUT_8822B[] = {
+	/* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+	{HALMAC_TRX_MODE_NORMAL,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_HQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_TRXSHARE,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_HQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_WMM,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_HQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_P2P,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_LOOPBACK,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+};
+
+/*USB 3 Bulkout RQPN Mapping*/
+static struct halmac_rqpn HALMAC_RQPN_3BULKOUT_8822B[] = {
+	/* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+	{HALMAC_TRX_MODE_NORMAL,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_TRXSHARE,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_WMM,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_P2P,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_LQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_LOOPBACK,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_LQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ, HALMAC_MAP2_LQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_HQ},
+};
+
+/*USB 4 Bulkout RQPN Mapping*/
+static struct halmac_rqpn HALMAC_RQPN_4BULKOUT_8822B[] = {
+	/* { mode, vo_map, vi_map, be_map, bk_map, mg_map, hi_map } */
+	{HALMAC_TRX_MODE_NORMAL,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_TRXSHARE,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_WMM,
+	 HALMAC_MAP2_HQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_NQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_P2P,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_LOOPBACK,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK,
+	 HALMAC_MAP2_NQ, HALMAC_MAP2_NQ, HALMAC_MAP2_LQ, HALMAC_MAP2_LQ,
+	 HALMAC_MAP2_EXQ, HALMAC_MAP2_HQ},
+};
+
+/*SDIO Page Number*/
+static struct halmac_pg_num HALMAC_PG_NUM_SDIO_8822B[] = {
+	/* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+	{HALMAC_TRX_MODE_NORMAL, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_TRXSHARE, 32, 32, 32, 32, 1},
+	{HALMAC_TRX_MODE_WMM, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_P2P, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_LOOPBACK, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 64, 64, 1},
+};
+
+/*PCIE Page Number*/
+static struct halmac_pg_num HALMAC_PG_NUM_PCIE_8822B[] = {
+	/* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+	{HALMAC_TRX_MODE_NORMAL, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_TRXSHARE, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_WMM, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_P2P, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_LOOPBACK, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 64, 64, 1},
+};
+
+/*USB 2 Bulkout Page Number*/
+static struct halmac_pg_num HALMAC_PG_NUM_2BULKOUT_8822B[] = {
+	/* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+	{HALMAC_TRX_MODE_NORMAL, 64, 64, 0, 0, 1},
+	{HALMAC_TRX_MODE_TRXSHARE, 64, 64, 0, 0, 1},
+	{HALMAC_TRX_MODE_WMM, 64, 64, 0, 0, 1},
+	{HALMAC_TRX_MODE_P2P, 64, 64, 0, 0, 1},
+	{HALMAC_TRX_MODE_LOOPBACK, 64, 64, 0, 0, 1},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 0, 0, 1},
+};
+
+/*USB 3 Bulkout Page Number*/
+static struct halmac_pg_num HALMAC_PG_NUM_3BULKOUT_8822B[] = {
+	/* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+	{HALMAC_TRX_MODE_NORMAL, 64, 64, 64, 0, 1},
+	{HALMAC_TRX_MODE_TRXSHARE, 64, 64, 64, 0, 1},
+	{HALMAC_TRX_MODE_WMM, 64, 64, 64, 0, 1},
+	{HALMAC_TRX_MODE_P2P, 64, 64, 64, 0, 1},
+	{HALMAC_TRX_MODE_LOOPBACK, 64, 64, 64, 0, 1},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 64, 0, 1},
+};
+
+/*USB 4 Bulkout Page Number*/
+static struct halmac_pg_num HALMAC_PG_NUM_4BULKOUT_8822B[] = {
+	/* { mode, hq_num, nq_num, lq_num, exq_num, gap_num} */
+	{HALMAC_TRX_MODE_NORMAL, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_TRXSHARE, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_WMM, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_P2P, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_LOOPBACK, 64, 64, 64, 64, 1},
+	{HALMAC_TRX_MODE_DELAY_LOOPBACK, 64, 64, 64, 64, 1},
+};
+
+static enum halmac_ret_status
+txdma_queue_mapping_8822b(struct halmac_adapter *adapter,
+			  enum halmac_trx_mode mode);
+
+static enum halmac_ret_status
+priority_queue_cfg_8822b(struct halmac_adapter *adapter,
+			 enum halmac_trx_mode mode);
+
+static enum halmac_ret_status
+set_trx_fifo_info_8822b(struct halmac_adapter *adapter,
+			enum halmac_trx_mode mode);
+enum halmac_ret_status
+mount_api_8822b(struct halmac_adapter *adapter)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	adapter->chip_id = HALMAC_CHIP_ID_8822B;
+	adapter->hw_cfg_info.efuse_size = EFUSE_SIZE_8822B;
+	adapter->hw_cfg_info.eeprom_size = EEPROM_SIZE_8822B;
+	adapter->hw_cfg_info.bt_efuse_size = BT_EFUSE_SIZE_8822B;
+	adapter->hw_cfg_info.cam_entry_num = SEC_CAM_NUM_8822B;
+	adapter->hw_cfg_info.tx_fifo_size = TX_FIFO_SIZE_8822B;
+	adapter->hw_cfg_info.rx_fifo_size = RX_FIFO_SIZE_8822B;
+	adapter->hw_cfg_info.ac_oqt_size = OQT_ENTRY_AC_8822B;
+	adapter->hw_cfg_info.non_ac_oqt_size = OQT_ENTRY_NOAC_8822B;
+	adapter->hw_cfg_info.usb_txagg_num = BLK_DESC_NUM;
+	adapter->txff_alloc.rsvd_drv_pg_num = RSVD_PG_DRV_NUM;
+
+	api->halmac_init_trx_cfg = init_trx_cfg_8822b;
+	api->halmac_init_protocol_cfg = init_protocol_cfg_8822b;
+	api->halmac_init_h2c = init_h2c_8822b;
+	api->halmac_pinmux_get_func = pinmux_get_func_8822b;
+	api->halmac_pinmux_set_func = pinmux_set_func_8822b;
+	api->halmac_pinmux_free_func = pinmux_free_func_8822b;
+	api->halmac_get_hw_value = get_hw_value_8822b;
+	api->halmac_set_hw_value = set_hw_value_8822b;
+	api->halmac_cfg_drv_info = cfg_drv_info_8822b;
+	api->halmac_fill_txdesc_checksum = fill_txdesc_check_sum_8822b;
+	api->halmac_init_low_pwr = init_low_pwr_8822b;
+
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		api->halmac_mac_power_switch = mac_pwr_switch_sdio_8822b;
+		api->halmac_phy_cfg = phy_cfg_sdio_8822b;
+		api->halmac_pcie_switch = pcie_switch_sdio_8822b;
+		api->halmac_interface_integration_tuning = intf_tun_sdio_8822b;
+		api->halmac_tx_allowed_sdio = tx_allowed_sdio_8822b;
+		api->halmac_get_sdio_tx_addr = get_sdio_tx_addr_8822b;
+		api->halmac_reg_read_8 = reg_r8_sdio_8822b;
+		api->halmac_reg_write_8 = reg_w8_sdio_8822b;
+		api->halmac_reg_read_16 = reg_r16_sdio_8822b;
+		api->halmac_reg_write_16 = reg_w16_sdio_8822b;
+		api->halmac_reg_read_32 = reg_r32_sdio_8822b;
+		api->halmac_reg_write_32 = reg_w32_sdio_8822b;
+
+		adapter->sdio_fs.macid_map_size = MACID_MAX_8822B * 2;
+		if (!adapter->sdio_fs.macid_map) {
+			adapter->sdio_fs.macid_map =
+			kzalloc(adapter->sdio_fs.macid_map_size, GFP_KERNEL);
+			if (!adapter->sdio_fs.macid_map)
+				pr_err("allocate macid_map!!\n");
+		}
+	} else if (adapter->intf == HALMAC_INTERFACE_USB) {
+		api->halmac_mac_power_switch = mac_pwr_switch_usb_8822b;
+		api->halmac_phy_cfg = phy_cfg_usb_8822b;
+		api->halmac_pcie_switch = pcie_switch_usb_8822b;
+		api->halmac_interface_integration_tuning = intf_tun_usb_8822b;
+	} else if (adapter->intf == HALMAC_INTERFACE_PCIE) {
+		api->halmac_mac_power_switch = mac_pwr_switch_pcie_8822b;
+		api->halmac_phy_cfg = phy_cfg_pcie_8822b;
+		api->halmac_pcie_switch = pcie_switch_8822b;
+		api->halmac_interface_integration_tuning = intf_tun_pcie_8822b;
+	} else {
+		pr_err("Undefined IC\n");
+		return HALMAC_RET_CHIP_NOT_SUPPORT;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * init_trx_cfg_8822b() - config trx dma register
+ * @adapter : the adapter of halmac
+ * @mode : trx mode selection
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_trx_cfg_8822b(struct halmac_adapter *adapter, enum halmac_trx_mode mode)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	adapter->trx_mode = mode;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = txdma_queue_mapping_8822b(adapter, mode);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("queue mapping\n");
+		return status;
+	}
+
+	value8 = 0;
+	HALMAC_REG_W8(REG_CR, value8);
+	value8 = MAC_TRX_ENABLE;
+	HALMAC_REG_W8(REG_CR, value8);
+	HALMAC_REG_W32(REG_H2CQ_CSR, BIT(31));
+
+	status = priority_queue_cfg_8822b(adapter, mode);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("halmac_txdma_queue_mapping fail!\n");
+		return status;
+	}
+
+	if (adapter->txff_alloc.rx_fifo_exp_mode !=
+	    HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE)
+		HALMAC_REG_W8(REG_RX_DRVINFO_SZ, RX_DESC_DUMMY_SIZE_8822B >> 3);
+
+	status = init_h2c_8822b(adapter);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("init h2cq!\n");
+		return status;
+	}
+
+	if (adapter->intf == HALMAC_INTERFACE_USB)
+		HALMAC_REG_W8_SET(REG_TXDMA_PQ_MAP, BIT(0));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+txdma_queue_mapping_8822b(struct halmac_adapter *adapter,
+			  enum halmac_trx_mode mode)
+{
+	u16 value16;
+	struct halmac_rqpn *cur_rqpn_sel = NULL;
+	enum halmac_ret_status status;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		cur_rqpn_sel = HALMAC_RQPN_SDIO_8822B;
+	} else if (adapter->intf == HALMAC_INTERFACE_PCIE) {
+		cur_rqpn_sel = HALMAC_RQPN_PCIE_8822B;
+	} else if (adapter->intf == HALMAC_INTERFACE_USB) {
+		if (adapter->bulkout_num == 2) {
+			cur_rqpn_sel = HALMAC_RQPN_2BULKOUT_8822B;
+		} else if (adapter->bulkout_num == 3) {
+			cur_rqpn_sel = HALMAC_RQPN_3BULKOUT_8822B;
+		} else if (adapter->bulkout_num == 4) {
+			cur_rqpn_sel = HALMAC_RQPN_4BULKOUT_8822B;
+		} else {
+			pr_err("invalid intf\n");
+			return HALMAC_RET_NOT_SUPPORT;
+		}
+	} else {
+		return HALMAC_RET_NOT_SUPPORT;
+	}
+
+	status = rqpn_parser_88xx(adapter, mode, cur_rqpn_sel);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	value16 = 0;
+	value16 |= BIT_TXDMA_HIQ_MAP(adapter->pq_map[HALMAC_PQ_MAP_HI]);
+	value16 |= BIT_TXDMA_MGQ_MAP(adapter->pq_map[HALMAC_PQ_MAP_MG]);
+	value16 |= BIT_TXDMA_BKQ_MAP(adapter->pq_map[HALMAC_PQ_MAP_BK]);
+	value16 |= BIT_TXDMA_BEQ_MAP(adapter->pq_map[HALMAC_PQ_MAP_BE]);
+	value16 |= BIT_TXDMA_VIQ_MAP(adapter->pq_map[HALMAC_PQ_MAP_VI]);
+	value16 |= BIT_TXDMA_VOQ_MAP(adapter->pq_map[HALMAC_PQ_MAP_VO]);
+	HALMAC_REG_W16(REG_TXDMA_PQ_MAP, value16);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+priority_queue_cfg_8822b(struct halmac_adapter *adapter,
+			 enum halmac_trx_mode mode)
+{
+	u8 transfer_mode = 0;
+	u8 value8;
+	u32 cnt;
+	struct halmac_txff_allocation *txff_info = &adapter->txff_alloc;
+	enum halmac_ret_status status;
+	struct halmac_pg_num *cur_pg_num = NULL;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	status = set_trx_fifo_info_8822b(adapter, mode);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("set trx fifo!!\n");
+		return status;
+	}
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		cur_pg_num = HALMAC_PG_NUM_SDIO_8822B;
+	} else if (adapter->intf == HALMAC_INTERFACE_PCIE) {
+		cur_pg_num = HALMAC_PG_NUM_PCIE_8822B;
+	} else if (adapter->intf == HALMAC_INTERFACE_USB) {
+		if (adapter->bulkout_num == 2) {
+			cur_pg_num = HALMAC_PG_NUM_2BULKOUT_8822B;
+		} else if (adapter->bulkout_num == 3) {
+			cur_pg_num = HALMAC_PG_NUM_3BULKOUT_8822B;
+		} else if (adapter->bulkout_num == 4) {
+			cur_pg_num = HALMAC_PG_NUM_4BULKOUT_8822B;
+		} else {
+			pr_err("interface not support\n");
+			return HALMAC_RET_NOT_SUPPORT;
+		}
+	} else {
+		return HALMAC_RET_NOT_SUPPORT;
+	}
+
+	status = pg_num_parser_88xx(adapter, mode, cur_pg_num);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	HALMAC_REG_W16(REG_FIFOPAGE_INFO_1, txff_info->high_queue_pg_num);
+	HALMAC_REG_W16(REG_FIFOPAGE_INFO_2, txff_info->low_queue_pg_num);
+	HALMAC_REG_W16(REG_FIFOPAGE_INFO_3, txff_info->normal_queue_pg_num);
+	HALMAC_REG_W16(REG_FIFOPAGE_INFO_4, txff_info->extra_queue_pg_num);
+	HALMAC_REG_W16(REG_FIFOPAGE_INFO_5, txff_info->pub_queue_pg_num);
+	HALMAC_REG_W32_SET(REG_RQPN_CTRL_2, BIT(31));
+
+	adapter->sdio_fs.hiq_pg_num = txff_info->high_queue_pg_num;
+	adapter->sdio_fs.miq_pg_num = txff_info->normal_queue_pg_num;
+	adapter->sdio_fs.lowq_pg_num = txff_info->low_queue_pg_num;
+	adapter->sdio_fs.pubq_pg_num = txff_info->pub_queue_pg_num;
+	adapter->sdio_fs.exq_pg_num = txff_info->extra_queue_pg_num;
+
+	HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, txff_info->rsvd_boundary);
+	HALMAC_REG_W8_SET(REG_FWHW_TXQ_CTRL + 2, BIT(4));
+
+	/*20170411 Soar*/
+	/* SDIO sometimes use two CMD52 to do HALMAC_REG_W16 */
+	/* and may cause a mismatch between HW status and Reg value. */
+	/* A patch is to write high byte first, suggested by Argis */
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		value8 = (u8)(txff_info->rsvd_boundary >> 8 & 0xFF);
+		HALMAC_REG_W8(REG_BCNQ_BDNY_V1 + 1, value8);
+		value8 = (u8)(txff_info->rsvd_boundary & 0xFF);
+		HALMAC_REG_W8(REG_BCNQ_BDNY_V1, value8);
+	} else {
+		HALMAC_REG_W16(REG_BCNQ_BDNY_V1, txff_info->rsvd_boundary);
+	}
+
+	HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2 + 2, txff_info->rsvd_boundary);
+
+	/*20170411 Soar*/
+	/* SDIO sometimes use two CMD52 to do HALMAC_REG_W16 */
+	/* and may cause a mismatch between HW status and Reg value. */
+	/* A patch is to write high byte first, suggested by Argis */
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		value8 = (u8)(txff_info->rsvd_boundary >> 8 & 0xFF);
+		HALMAC_REG_W8(REG_BCNQ1_BDNY_V1 + 1, value8);
+		value8 = (u8)(txff_info->rsvd_boundary & 0xFF);
+		HALMAC_REG_W8(REG_BCNQ1_BDNY_V1, value8);
+	} else {
+		HALMAC_REG_W16(REG_BCNQ1_BDNY_V1, txff_info->rsvd_boundary);
+	}
+
+	HALMAC_REG_W32(REG_RXFF_BNDY,
+		       adapter->hw_cfg_info.rx_fifo_size -
+		       C2H_PKT_BUF_88XX - 1);
+
+	if (adapter->intf == HALMAC_INTERFACE_USB) {
+		value8 = HALMAC_REG_R8(REG_AUTO_LLT_V1);
+		value8 &= ~(BIT_MASK_BLK_DESC_NUM << BIT_SHIFT_BLK_DESC_NUM);
+		value8 |= (BLK_DESC_NUM << BIT_SHIFT_BLK_DESC_NUM);
+		HALMAC_REG_W8(REG_AUTO_LLT_V1, value8);
+
+		HALMAC_REG_W8(REG_AUTO_LLT_V1 + 3, BLK_DESC_NUM);
+		HALMAC_REG_W8_SET(REG_TXDMA_OFFSET_CHK + 1, BIT(1));
+	}
+
+	HALMAC_REG_W8_SET(REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1);
+	cnt = 1000;
+	while (HALMAC_REG_R8(REG_AUTO_LLT_V1) & BIT_AUTO_INIT_LLT_V1) {
+		cnt--;
+		if (cnt == 0)
+			return HALMAC_RET_INIT_LLT_FAIL;
+	}
+
+	if (mode == HALMAC_TRX_MODE_DELAY_LOOPBACK) {
+		transfer_mode = HALMAC_TRNSFER_LOOPBACK_DELAY;
+		HALMAC_REG_W16(REG_WMAC_LBK_BUF_HD_V1,
+			       adapter->txff_alloc.rsvd_boundary);
+	} else if (mode == HALMAC_TRX_MODE_LOOPBACK) {
+		transfer_mode = HALMAC_TRNSFER_LOOPBACK_DIRECT;
+	} else {
+		transfer_mode = HALMAC_TRNSFER_NORMAL;
+	}
+
+	adapter->hw_cfg_info.trx_mode = transfer_mode;
+	HALMAC_REG_W8(REG_CR + 3, transfer_mode);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+set_trx_fifo_info_8822b(struct halmac_adapter *adapter,
+			enum halmac_trx_mode mode)
+{
+	u16 cur_pg_addr;
+	u32 txff_size = TX_FIFO_SIZE_8822B;
+	u32 rxff_size = RX_FIFO_SIZE_8822B;
+	struct halmac_txff_allocation *info = &adapter->txff_alloc;
+
+	if (info->rx_fifo_exp_mode == HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK) {
+		txff_size = TX_FIFO_SIZE_RX_EXPAND_1BLK_8822B;
+		rxff_size = RX_FIFO_SIZE_RX_EXPAND_1BLK_8822B;
+	}
+
+	if (info->la_mode != HALMAC_LA_MODE_DISABLE) {
+		txff_size = TX_FIFO_SIZE_LA_8822B;
+		rxff_size = RX_FIFO_SIZE_8822B;
+	}
+
+	adapter->hw_cfg_info.tx_fifo_size = txff_size;
+	adapter->hw_cfg_info.rx_fifo_size = rxff_size;
+	info->tx_fifo_pg_num = (u16)(txff_size >> TX_PAGE_SIZE_SHIFT_88XX);
+
+	info->rsvd_pg_num = info->rsvd_drv_pg_num +
+					RSVD_PG_H2C_EXTRAINFO_NUM +
+					RSVD_PG_H2C_STATICINFO_NUM +
+					RSVD_PG_H2CQ_NUM +
+					RSVD_PG_CPU_INSTRUCTION_NUM +
+					RSVD_PG_FW_TXBUF_NUM +
+					RSVD_PG_CSIBUF_NUM;
+
+	if (mode == HALMAC_TRX_MODE_DELAY_LOOPBACK)
+		info->rsvd_pg_num += RSVD_PG_DLLB_NUM;
+
+	if (info->rsvd_pg_num > info->tx_fifo_pg_num)
+		return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
+
+	info->acq_pg_num = info->tx_fifo_pg_num - info->rsvd_pg_num;
+	info->rsvd_boundary = info->tx_fifo_pg_num - info->rsvd_pg_num;
+
+	cur_pg_addr = info->tx_fifo_pg_num;
+	cur_pg_addr -= RSVD_PG_CSIBUF_NUM;
+	info->rsvd_csibuf_addr = cur_pg_addr;
+	cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM;
+	info->rsvd_fw_txbuf_addr = cur_pg_addr;
+	cur_pg_addr -= RSVD_PG_CPU_INSTRUCTION_NUM;
+	info->rsvd_cpu_instr_addr = cur_pg_addr;
+	cur_pg_addr -= RSVD_PG_H2CQ_NUM;
+	info->rsvd_h2cq_addr = cur_pg_addr;
+	cur_pg_addr -= RSVD_PG_H2C_STATICINFO_NUM;
+	info->rsvd_h2c_sta_info_addr = cur_pg_addr;
+	cur_pg_addr -= RSVD_PG_H2C_EXTRAINFO_NUM;
+	info->rsvd_h2c_info_addr = cur_pg_addr;
+	cur_pg_addr -= info->rsvd_drv_pg_num;
+	info->rsvd_drv_addr = cur_pg_addr;
+
+	if (mode == HALMAC_TRX_MODE_DELAY_LOOPBACK)
+		info->rsvd_drv_addr -= RSVD_PG_DLLB_NUM;
+
+	if (info->rsvd_boundary != info->rsvd_drv_addr)
+		return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * init_protocol_cfg_8822b() - config protocol register
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_protocol_cfg_8822b(struct halmac_adapter *adapter)
+{
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	HALMAC_REG_W8_CLR(REG_SW_AMPDU_BURST_MODE_CTRL, BIT(6));
+
+	HALMAC_REG_W8(REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME);
+	HALMAC_REG_W8_SET(REG_TX_HANG_CTRL, BIT_EN_EOF_V1);
+
+	value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) |
+					(WLAN_MAX_AGG_PKT_LIMIT << 16) |
+					(WLAN_RTS_MAX_AGG_PKT_LIMIT << 24);
+	HALMAC_REG_W32(REG_PROT_MODE_CTRL, value32);
+
+	HALMAC_REG_W16(REG_BAR_MODE_CTRL + 2,
+		       WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8);
+
+	HALMAC_REG_W8(REG_FAST_EDCA_VOVI_SETTING, WALN_FAST_EDCA_VO_TH);
+	HALMAC_REG_W8(REG_FAST_EDCA_VOVI_SETTING + 2, WLAN_FAST_EDCA_VI_TH);
+	HALMAC_REG_W8(REG_FAST_EDCA_BEBK_SETTING, WLAN_FAST_EDCA_BE_TH);
+	HALMAC_REG_W8(REG_FAST_EDCA_BEBK_SETTING + 2, WLAN_FAST_EDCA_BK_TH);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * init_h2c_8822b() - config h2c packet buffer
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_h2c_8822b(struct halmac_adapter *adapter)
+{
+	u8 value8;
+	u32 value32;
+	u32 h2cq_addr;
+	u32 h2cq_size;
+	struct halmac_txff_allocation *txff_info = &adapter->txff_alloc;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	h2cq_addr = txff_info->rsvd_h2cq_addr << TX_PAGE_SIZE_SHIFT_88XX;
+	h2cq_size = RSVD_PG_H2CQ_NUM << TX_PAGE_SIZE_SHIFT_88XX;
+
+	value32 = HALMAC_REG_R32(REG_H2C_HEAD);
+	value32 = (value32 & 0xFFFC0000) | h2cq_addr;
+	HALMAC_REG_W32(REG_H2C_HEAD, value32);
+
+	value32 = HALMAC_REG_R32(REG_H2C_READ_ADDR);
+	value32 = (value32 & 0xFFFC0000) | h2cq_addr;
+	HALMAC_REG_W32(REG_H2C_READ_ADDR, value32);
+
+	value32 = HALMAC_REG_R32(REG_H2C_TAIL);
+	value32 &= 0xFFFC0000;
+	value32 |= (h2cq_addr + h2cq_size);
+	HALMAC_REG_W32(REG_H2C_TAIL, value32);
+
+	value8 = HALMAC_REG_R8(REG_H2C_INFO);
+	value8 = (u8)((value8 & 0xFC) | 0x01);
+	HALMAC_REG_W8(REG_H2C_INFO, value8);
+
+	value8 = HALMAC_REG_R8(REG_H2C_INFO);
+	value8 = (u8)((value8 & 0xFB) | 0x04);
+	HALMAC_REG_W8(REG_H2C_INFO, value8);
+
+	value8 = HALMAC_REG_R8(REG_TXDMA_OFFSET_CHK + 1);
+	value8 = (u8)((value8 & 0x7f) | 0x80);
+	HALMAC_REG_W8(REG_TXDMA_OFFSET_CHK + 1, value8);
+
+	adapter->h2c_info.buf_size = h2cq_size;
+	get_h2c_buf_free_space_88xx(adapter);
+
+	if (adapter->h2c_info.buf_size != adapter->h2c_info.buf_fs) {
+		pr_err("get h2c free space error!\n");
+		return HALMAC_RET_GET_H2C_SPACE_ERR;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "h2c fs : %d\n",
+		 adapter->h2c_info.buf_fs);
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.h
new file mode 100644
index 000000000000..384a4890313f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_init_8822b.h
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_INIT_8822B_H_
+#define _HALMAC_INIT_8822B_H_
+
+#include "../../halmac_api.h"
+
+enum halmac_ret_status
+mount_api_8822b(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+init_trx_cfg_8822b(struct halmac_adapter *adapter, enum halmac_trx_mode mode);
+
+enum halmac_ret_status
+init_protocol_cfg_8822b(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+init_h2c_8822b(struct halmac_adapter *adapter);
+
+#endif/* _HALMAC_INIT_8822B_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.c
new file mode 100644
index 000000000000..a939c3237efa
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.c
@@ -0,0 +1,1071 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_init_88xx.h"
+#include "halmac_88xx_cfg.h"
+#include "halmac_fw_88xx.h"
+#include "halmac_common_88xx.h"
+#include "halmac_cfg_wmac_88xx.h"
+#include "halmac_efuse_88xx.h"
+#include "halmac_mimo_88xx.h"
+#include "halmac_bb_rf_88xx.h"
+#include "halmac_sdio_88xx.h"
+#include "halmac_usb_88xx.h"
+#include "halmac_pcie_88xx.h"
+#include "halmac_gpio_88xx.h"
+#include "halmac_flash_88xx.h"
+
+#include "halmac_8822b/halmac_init_8822b.h"
+
+#define PLTFM_INFO_MALLOC_MAX_SIZE	16384
+#define PLTFM_INFO_RSVD_PG_SIZE		16384
+#define DLFW_PKT_MAX_SIZE		8192 /* need multiple of 2 */
+
+#define SYS_FUNC_EN		0xDC
+#define WLAN_SLOT_TIME		0x05
+#define WLAN_PIFS_TIME		0x19
+#define WLAN_SIFS_CCK_CONT_TX	0xA
+#define WLAN_SIFS_OFDM_CONT_TX	0xA
+#define WLAN_SIFS_CCK_TRX	0x10
+#define WLAN_SIFS_OFDM_TRX	0x10
+#define WLAN_VO_TXOP_LIMIT	0x186 /* unit : 32us */
+#define WLAN_VI_TXOP_LIMIT	0x3BC /* unit : 32us */
+#define WLAN_RDG_NAV		0x05
+#define WLAN_TXOP_NAV		0x1B
+#define WLAN_CCK_RX_TSF		0x30
+#define WLAN_OFDM_RX_TSF	0x30
+#define WLAN_TBTT_PROHIBIT	0x04 /* unit : 32us */
+#define WLAN_TBTT_HOLD_TIME	0x064 /* unit : 32us */
+#define WLAN_DRV_EARLY_INT	0x04
+#define WLAN_BCN_DMA_TIME	0x02
+#define WLAN_ACK_TO_CCK		0x40
+
+#define WLAN_RX_FILTER0		0x0FFFFFFF
+#define WLAN_RX_FILTER2		0xFFFF
+#define WLAN_RCR_CFG		0xE400220E
+#define WLAN_RXPKT_MAX_SZ	12288
+#define WLAN_RXPKT_MAX_SZ_512	(WLAN_RXPKT_MAX_SZ >> 9)
+
+#define WLAN_TX_FUNC_CFG1		0x30
+#define WLAN_TX_FUNC_CFG2		0x30
+#define WLAN_MAC_OPT_NORM_FUNC1		0x98
+#define WLAN_MAC_OPT_LB_FUNC1		0x80
+#define WLAN_MAC_OPT_FUNC2		0x30810041
+
+#define WLAN_SIFS_CFG	(WLAN_SIFS_CCK_CONT_TX | \
+			(WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
+			(WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
+			(WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
+
+#define WLAN_TBTT_TIME	(WLAN_TBTT_PROHIBIT |\
+			(WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
+
+#define WLAN_NAV_CFG		(WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
+#define WLAN_RX_TSF_CFG		(WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
+
+static void
+init_state_machine_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+verify_io_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+verify_send_rsvd_page_88xx(struct halmac_adapter *adapter);
+
+void
+init_adapter_param_88xx(struct halmac_adapter *adapter)
+{
+	adapter->api_registry.rx_exp_en = 1;
+	adapter->api_registry.la_mode_en = 1;
+	adapter->api_registry.cfg_drv_rsvd_pg_en = 1;
+	adapter->api_registry.sdio_cmd53_4byte_en = 1;
+
+	adapter->efuse_map = (u8 *)NULL;
+	adapter->efuse_map_valid = 0;
+	adapter->efuse_end = 0;
+
+	adapter->dlfw_pkt_size = DLFW_PKT_MAX_SIZE;
+	adapter->pltfm_info.malloc_size = PLTFM_INFO_MALLOC_MAX_SIZE;
+	adapter->pltfm_info.rsvd_pg_size = PLTFM_INFO_RSVD_PG_SIZE;
+
+	adapter->cfg_param_info.buf = NULL;
+	adapter->cfg_param_info.buf_wptr = NULL;
+	adapter->cfg_param_info.num = 0;
+	adapter->cfg_param_info.full_fifo_mode = 0;
+	adapter->cfg_param_info.buf_size = 0;
+	adapter->cfg_param_info.avl_buf_size = 0;
+	adapter->cfg_param_info.offset_accum = 0;
+	adapter->cfg_param_info.value_accum = 0;
+
+	adapter->ch_sw_info.buf = NULL;
+	adapter->ch_sw_info.buf_wptr = NULL;
+	adapter->ch_sw_info.extra_info_en = 0;
+	adapter->ch_sw_info.buf_size = 0;
+	adapter->ch_sw_info.avl_buf_size = 0;
+	adapter->ch_sw_info.total_size = 0;
+	adapter->ch_sw_info.ch_num = 0;
+
+	adapter->drv_info_size = 0;
+	adapter->tx_desc_transfer = 0;
+
+	adapter->txff_alloc.tx_fifo_pg_num = 0;
+	adapter->txff_alloc.acq_pg_num = 0;
+	adapter->txff_alloc.rsvd_boundary = 0;
+	adapter->txff_alloc.rsvd_drv_addr = 0;
+	adapter->txff_alloc.rsvd_h2c_info_addr = 0;
+	adapter->txff_alloc.rsvd_h2cq_addr = 0;
+	adapter->txff_alloc.rsvd_cpu_instr_addr = 0;
+	adapter->txff_alloc.rsvd_fw_txbuf_addr = 0;
+	adapter->txff_alloc.pub_queue_pg_num = 0;
+	adapter->txff_alloc.high_queue_pg_num = 0;
+	adapter->txff_alloc.low_queue_pg_num = 0;
+	adapter->txff_alloc.normal_queue_pg_num = 0;
+	adapter->txff_alloc.extra_queue_pg_num = 0;
+
+	adapter->txff_alloc.la_mode = HALMAC_LA_MODE_DISABLE;
+	adapter->txff_alloc.rx_fifo_exp_mode =
+					HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
+
+	adapter->hw_cfg_info.chk_security_keyid = 0;
+	adapter->hw_cfg_info.acq_num = 8;
+	adapter->hw_cfg_info.page_size = TX_PAGE_SIZE_88XX;
+	adapter->hw_cfg_info.tx_align_size = TX_ALIGN_SIZE_88XX;
+	adapter->hw_cfg_info.txdesc_size = TX_DESC_SIZE_88XX;
+	adapter->hw_cfg_info.rxdesc_size = RX_DESC_SIZE_88XX;
+	adapter->hw_cfg_info.rx_desc_fifo_size = 0;
+
+	adapter->sdio_cmd53_4byte = HALMAC_SDIO_CMD53_4BYTE_MODE_DISABLE;
+	adapter->sdio_hw_info.io_hi_speed_flag = 0;
+	adapter->sdio_hw_info.io_indir_flag = 0;
+	adapter->sdio_hw_info.spec_ver = HALMAC_SDIO_SPEC_VER_2_00;
+	adapter->sdio_hw_info.clock_speed = 50;
+	adapter->sdio_hw_info.block_size = 512;
+	adapter->sdio_hw_info.tx_seq = 1;
+	adapter->sdio_fs.macid_map = (u8 *)NULL;
+
+	adapter->pinmux_info.wl_led = 0;
+	adapter->pinmux_info.sdio_int = 0;
+	adapter->pinmux_info.sw_io_0 = 0;
+	adapter->pinmux_info.sw_io_1 = 0;
+	adapter->pinmux_info.sw_io_2 = 0;
+	adapter->pinmux_info.sw_io_3 = 0;
+	adapter->pinmux_info.sw_io_4 = 0;
+	adapter->pinmux_info.sw_io_5 = 0;
+	adapter->pinmux_info.sw_io_6 = 0;
+	adapter->pinmux_info.sw_io_7 = 0;
+	adapter->pinmux_info.sw_io_8 = 0;
+	adapter->pinmux_info.sw_io_9 = 0;
+	adapter->pinmux_info.sw_io_10 = 0;
+	adapter->pinmux_info.sw_io_11 = 0;
+	adapter->pinmux_info.sw_io_12 = 0;
+	adapter->pinmux_info.sw_io_13 = 0;
+	adapter->pinmux_info.sw_io_14 = 0;
+	adapter->pinmux_info.sw_io_15 = 0;
+
+	adapter->pcie_refautok_en = 1;
+	adapter->pwr_off_flow_flag = 0;
+
+	adapter->rx_ignore_info.hdr_chk_mask = 1;
+	adapter->rx_ignore_info.fcs_chk_mask = 1;
+	adapter->rx_ignore_info.hdr_chk_en = 0;
+	adapter->rx_ignore_info.fcs_chk_en = 0;
+	adapter->rx_ignore_info.cck_rst_en = 0;
+	adapter->rx_ignore_info.fcs_chk_thr = HALMAC_PSF_FCS_CHK_THR_28;
+
+	init_adapter_dynamic_param_88xx(adapter);
+	init_state_machine_88xx(adapter);
+}
+
+void
+init_adapter_dynamic_param_88xx(struct halmac_adapter *adapter)
+{
+	adapter->h2c_info.seq_num = 0;
+	adapter->h2c_info.buf_fs = 0;
+}
+
+enum halmac_ret_status
+mount_api_88xx(struct halmac_adapter *adapter)
+{
+	struct halmac_api *api = NULL;
+
+	adapter->halmac_api =
+		kzalloc(sizeof(struct halmac_api), GFP_KERNEL);
+	if (!adapter->halmac_api)
+		return HALMAC_RET_MALLOC_FAIL;
+
+	api = (struct halmac_api *)adapter->halmac_api;
+
+	api->halmac_read_efuse = NULL;
+	api->halmac_write_efuse = NULL;
+
+	/* Mount function pointer */
+	api->halmac_register_api = register_api_88xx;
+	api->halmac_download_firmware = download_firmware_88xx;
+	api->halmac_free_download_firmware = free_download_firmware_88xx;
+	api->halmac_get_fw_version = get_fw_version_88xx;
+	api->halmac_cfg_mac_addr = cfg_mac_addr_88xx;
+	api->halmac_cfg_bssid = cfg_bssid_88xx;
+	api->halmac_cfg_transmitter_addr = cfg_transmitter_addr_88xx;
+	api->halmac_cfg_net_type = cfg_net_type_88xx;
+	api->halmac_cfg_tsf_rst = cfg_tsf_rst_88xx;
+	api->halmac_cfg_bcn_space = cfg_bcn_space_88xx;
+	api->halmac_rw_bcn_ctrl = rw_bcn_ctrl_88xx;
+	api->halmac_cfg_multicast_addr = cfg_multicast_addr_88xx;
+	api->halmac_pre_init_system_cfg = pre_init_system_cfg_88xx;
+	api->halmac_init_system_cfg = init_system_cfg_88xx;
+	api->halmac_init_edca_cfg = init_edca_cfg_88xx;
+	api->halmac_cfg_operation_mode = cfg_operation_mode_88xx;
+	api->halmac_cfg_ch_bw = cfg_ch_bw_88xx;
+	api->halmac_cfg_bw = cfg_bw_88xx;
+	api->halmac_init_wmac_cfg = init_wmac_cfg_88xx;
+	api->halmac_init_mac_cfg = init_mac_cfg_88xx;
+	api->halmac_dump_efuse_map = dump_efuse_map_88xx;
+	api->halmac_dump_efuse_map_bt = dump_efuse_map_bt_88xx;
+	api->halmac_write_efuse_bt = write_efuse_bt_88xx;
+	api->halmac_read_efuse_bt = read_efuse_bt_88xx;
+	api->halmac_cfg_efuse_auto_check = cfg_efuse_auto_check_88xx;
+	api->halmac_dump_logical_efuse_map = dump_log_efuse_map_88xx;
+	api->halmac_pg_efuse_by_map = pg_efuse_by_map_88xx;
+	api->halmac_mask_logical_efuse = mask_log_efuse_88xx;
+	api->halmac_get_efuse_size = get_efuse_size_88xx;
+	api->halmac_get_efuse_available_size = get_efuse_available_size_88xx;
+	api->halmac_get_c2h_info = get_c2h_info_88xx;
+
+	api->halmac_get_logical_efuse_size = get_log_efuse_size_88xx;
+
+	api->halmac_write_logical_efuse = write_log_efuse_88xx;
+	api->halmac_read_logical_efuse = read_logical_efuse_88xx;
+
+	api->halmac_ofld_func_cfg = ofld_func_cfg_88xx;
+	api->halmac_h2c_lb = h2c_lb_88xx;
+	api->halmac_debug = mac_debug_88xx;
+	api->halmac_cfg_parameter = cfg_parameter_88xx;
+	api->halmac_update_datapack = update_datapack_88xx;
+	api->halmac_run_datapack = run_datapack_88xx;
+	api->halmac_send_bt_coex = send_bt_coex_88xx;
+	api->halmac_verify_platform_api = verify_platform_api_88xx;
+	api->halmac_update_packet = update_packet_88xx;
+	api->halmac_bcn_ie_filter = bcn_ie_filter_88xx;
+	api->halmac_cfg_txbf = cfg_txbf_88xx;
+	api->halmac_cfg_mumimo = cfg_mumimo_88xx;
+	api->halmac_cfg_sounding = cfg_sounding_88xx;
+	api->halmac_del_sounding = del_sounding_88xx;
+	api->halmac_su_bfer_entry_init = su_bfer_entry_init_88xx;
+	api->halmac_su_bfee_entry_init = su_bfee_entry_init_88xx;
+	api->halmac_mu_bfer_entry_init = mu_bfer_entry_init_88xx;
+	api->halmac_mu_bfee_entry_init = mu_bfee_entry_init_88xx;
+	api->halmac_su_bfer_entry_del = su_bfer_entry_del_88xx;
+	api->halmac_su_bfee_entry_del = su_bfee_entry_del_88xx;
+	api->halmac_mu_bfer_entry_del = mu_bfer_entry_del_88xx;
+	api->halmac_mu_bfee_entry_del = mu_bfee_entry_del_88xx;
+
+	api->halmac_add_ch_info = add_ch_info_88xx;
+	api->halmac_add_extra_ch_info = add_extra_ch_info_88xx;
+	api->halmac_ctrl_ch_switch = ctrl_ch_switch_88xx;
+	api->halmac_p2pps = p2pps_88xx;
+	api->halmac_clear_ch_info = clear_ch_info_88xx;
+	api->halmac_send_general_info = send_general_info_88xx;
+
+	api->halmac_start_iqk = start_iqk_88xx;
+	api->halmac_ctrl_pwr_tracking = ctrl_pwr_tracking_88xx;
+	api->halmac_psd = psd_88xx;
+	api->halmac_cfg_la_mode = cfg_la_mode_88xx;
+	api->halmac_cfg_rxff_expand_mode = cfg_rxfifo_expand_mode_88xx;
+
+	api->halmac_config_security = config_security_88xx;
+	api->halmac_get_used_cam_entry_num = get_used_cam_entry_num_88xx;
+	api->halmac_read_cam_entry = read_cam_entry_88xx;
+	api->halmac_write_cam = write_cam_88xx;
+	api->halmac_clear_cam_entry = clear_cam_entry_88xx;
+
+	api->halmac_cfg_drv_rsvd_pg_num = cfg_drv_rsvd_pg_num_88xx;
+	api->halmac_get_chip_version = get_version_88xx;
+
+	api->halmac_query_status = query_status_88xx;
+	api->halmac_reset_feature = reset_ofld_feature_88xx;
+	api->halmac_check_fw_status = check_fw_status_88xx;
+	api->halmac_dump_fw_dmem = dump_fw_dmem_88xx;
+	api->halmac_cfg_max_dl_size = cfg_max_dl_size_88xx;
+
+	api->halmac_dump_fifo = dump_fifo_88xx;
+	api->halmac_get_fifo_size = get_fifo_size_88xx;
+
+	api->halmac_chk_txdesc = chk_txdesc_88xx;
+	api->halmac_dl_drv_rsvd_page = dl_drv_rsvd_page_88xx;
+	api->halmac_cfg_csi_rate = cfg_csi_rate_88xx;
+
+	api->halmac_sdio_cmd53_4byte = sdio_cmd53_4byte_88xx;
+	api->halmac_sdio_hw_info = sdio_hw_info_88xx;
+
+	api->halmac_init_sdio_cfg = init_sdio_cfg_88xx;
+	api->halmac_init_usb_cfg = init_usb_cfg_88xx;
+	api->halmac_init_pcie_cfg = init_pcie_cfg_88xx;
+	api->halmac_deinit_sdio_cfg = deinit_sdio_cfg_88xx;
+	api->halmac_deinit_usb_cfg = deinit_usb_cfg_88xx;
+	api->halmac_deinit_pcie_cfg = deinit_pcie_cfg_88xx;
+	api->halmac_txfifo_is_empty = txfifo_is_empty_88xx;
+	api->halmac_download_flash = download_flash_88xx;
+	api->halmac_read_flash = read_flash_88xx;
+	api->halmac_erase_flash = erase_flash_88xx;
+	api->halmac_check_flash = check_flash_88xx;
+	api->halmac_cfg_edca_para = cfg_edca_para_88xx;
+	api->halmac_pinmux_wl_led_mode = pinmux_wl_led_mode_88xx;
+	api->halmac_pinmux_wl_led_sw_ctrl = pinmux_wl_led_sw_ctrl_88xx;
+	api->halmac_pinmux_sdio_int_polarity = pinmux_sdio_int_polarity_88xx;
+	api->halmac_pinmux_gpio_mode = pinmux_gpio_mode_88xx;
+	api->halmac_pinmux_gpio_output = pinmux_gpio_output_88xx;
+	api->halmac_pinmux_pin_status = pinmux_pin_status_88xx;
+
+	api->halmac_rx_cut_amsdu_cfg = rx_cut_amsdu_cfg_88xx;
+	api->halmac_fw_snding = fw_snding_88xx;
+	api->halmac_get_mac_addr = get_mac_addr_88xx;
+
+	api->halmac_enter_cpu_sleep_mode = enter_cpu_sleep_mode_88xx;
+	api->halmac_get_cpu_mode = get_cpu_mode_88xx;
+	api->halmac_drv_fwctrl = drv_fwctrl_88xx;
+	api->halmac_en_ref_autok_pcie = en_ref_autok_88xx;
+
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		api->halmac_cfg_rx_aggregation = cfg_sdio_rx_agg_88xx;
+		api->halmac_init_interface_cfg = init_sdio_cfg_88xx;
+		api->halmac_deinit_interface_cfg = deinit_sdio_cfg_88xx;
+		api->halmac_cfg_tx_agg_align = cfg_txagg_sdio_align_88xx;
+		api->halmac_set_bulkout_num = set_sdio_bulkout_num_88xx;
+		api->halmac_get_usb_bulkout_id = get_sdio_bulkout_id_88xx;
+		api->halmac_reg_read_indirect_32 = sdio_indirect_reg_r32_88xx;
+		api->halmac_reg_sdio_cmd53_read_n = sdio_reg_rn_88xx;
+	} else if (adapter->intf == HALMAC_INTERFACE_USB) {
+		api->halmac_cfg_rx_aggregation = cfg_usb_rx_agg_88xx;
+		api->halmac_init_interface_cfg = init_usb_cfg_88xx;
+		api->halmac_deinit_interface_cfg = deinit_usb_cfg_88xx;
+		api->halmac_cfg_tx_agg_align = cfg_txagg_usb_align_88xx;
+		api->halmac_tx_allowed_sdio = tx_allowed_usb_88xx;
+		api->halmac_set_bulkout_num = set_usb_bulkout_num_88xx;
+		api->halmac_get_sdio_tx_addr = get_usb_tx_addr_88xx;
+		api->halmac_get_usb_bulkout_id = get_usb_bulkout_id_88xx;
+		api->halmac_reg_read_8 = reg_r8_usb_88xx;
+		api->halmac_reg_write_8 = reg_w8_usb_88xx;
+		api->halmac_reg_read_16 = reg_r16_usb_88xx;
+		api->halmac_reg_write_16 = reg_w16_usb_88xx;
+		api->halmac_reg_read_32 = reg_r32_usb_88xx;
+		api->halmac_reg_write_32 = reg_w32_usb_88xx;
+		api->halmac_reg_read_indirect_32 = usb_indirect_reg_r32_88xx;
+		api->halmac_reg_sdio_cmd53_read_n = usb_reg_rn_88xx;
+	} else if (adapter->intf == HALMAC_INTERFACE_PCIE) {
+		api->halmac_cfg_rx_aggregation = cfg_pcie_rx_agg_88xx;
+		api->halmac_init_interface_cfg = init_pcie_cfg_88xx;
+		api->halmac_deinit_interface_cfg = deinit_pcie_cfg_88xx;
+		api->halmac_cfg_tx_agg_align = cfg_txagg_pcie_align_88xx;
+		api->halmac_tx_allowed_sdio = tx_allowed_pcie_88xx;
+		api->halmac_set_bulkout_num = set_pcie_bulkout_num_88xx;
+		api->halmac_get_sdio_tx_addr = get_pcie_tx_addr_88xx;
+		api->halmac_get_usb_bulkout_id = get_pcie_bulkout_id_88xx;
+		api->halmac_reg_read_8 = reg_r8_pcie_88xx;
+		api->halmac_reg_write_8 = reg_w8_pcie_88xx;
+		api->halmac_reg_read_16 = reg_r16_pcie_88xx;
+		api->halmac_reg_write_16 = reg_w16_pcie_88xx;
+		api->halmac_reg_read_32 = reg_r32_pcie_88xx;
+		api->halmac_reg_write_32 = reg_w32_pcie_88xx;
+		api->halmac_reg_read_indirect_32 = pcie_indirect_reg_r32_88xx;
+		api->halmac_reg_sdio_cmd53_read_n = pcie_reg_rn_88xx;
+	} else {
+		pr_err("Set halmac io function Error!!\n");
+	}
+
+	if (adapter->chip_id == HALMAC_CHIP_ID_8822B) {
+		mount_api_8822b(adapter);
+	} else if (adapter->chip_id == HALMAC_CHIP_ID_8821C) {
+	} else if (adapter->chip_id == HALMAC_CHIP_ID_8822C) {
+	} else {
+		pr_err("Chip ID undefine!!\n");
+		return HALMAC_RET_CHIP_NOT_SUPPORT;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+init_state_machine_88xx(struct halmac_adapter *adapter)
+{
+	struct halmac_state *state = &adapter->halmac_state;
+
+	init_ofld_feature_state_machine_88xx(adapter);
+
+	state->api_state = HALMAC_API_STATE_INIT;
+
+	state->dlfw_state = HALMAC_DLFW_NONE;
+	state->mac_pwr = HALMAC_MAC_POWER_OFF;
+	state->gpio_cfg_state = HALMAC_GPIO_CFG_STATE_IDLE;
+	state->rsvd_pg_state = HALMAC_RSVD_PG_STATE_IDLE;
+}
+
+void
+init_ofld_feature_state_machine_88xx(struct halmac_adapter *adapter)
+{
+	struct halmac_state *state = &adapter->halmac_state;
+
+	state->efuse_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+	state->efuse_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+	state->efuse_state.seq_num = adapter->h2c_info.seq_num;
+
+	state->cfg_param_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+	state->cfg_param_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+	state->cfg_param_state.seq_num = adapter->h2c_info.seq_num;
+
+	state->scan_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+	state->scan_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+	state->scan_state.seq_num = adapter->h2c_info.seq_num;
+
+	state->update_pkt_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+	state->update_pkt_state.seq_num = adapter->h2c_info.seq_num;
+
+	state->iqk_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+	state->iqk_state.seq_num = adapter->h2c_info.seq_num;
+
+	state->pwr_trk_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+	state->pwr_trk_state.seq_num = adapter->h2c_info.seq_num;
+
+	state->psd_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+	state->psd_state.seq_num = adapter->h2c_info.seq_num;
+	state->psd_state.data_size = 0;
+	state->psd_state.seg_size = 0;
+	state->psd_state.data = NULL;
+
+	state->fw_snding_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+	state->fw_snding_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+	state->fw_snding_state.seq_num = adapter->h2c_info.seq_num;
+
+	state->wlcpu_mode = HALMAC_WLCPU_ACTIVE;
+}
+
+/**
+ * register_api_88xx() - register feature list
+ * @adapter
+ * @registry : feature list, 1->enable 0->disable
+ * Author : Ivan Lin
+ *
+ * Default is enable all api registry
+ *
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+register_api_88xx(struct halmac_adapter *adapter,
+		  struct halmac_api_registry *registry)
+{
+	if (!registry)
+		return HALMAC_RET_NULL_POINTER;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	memcpy(&adapter->api_registry, registry, sizeof(*registry));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * pre_init_system_cfg_88xx() - pre-init system config
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pre_init_system_cfg_88xx(struct halmac_adapter *adapter)
+{
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u8 enable_bb;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	HALMAC_REG_W8(REG_RSV_CTRL, 0);
+
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		if (leave_sdio_suspend_88xx(adapter) != HALMAC_RET_SUCCESS)
+			return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
+	} else if (adapter->intf == HALMAC_INTERFACE_USB) {
+		if (HALMAC_REG_R8(REG_SYS_CFG2 + 3) == 0x20)
+			HALMAC_REG_W8(0xFE5B, HALMAC_REG_R8(0xFE5B) | BIT(4));
+	} else if (adapter->intf == HALMAC_INTERFACE_PCIE) {
+		/* For PCIE power on fail issue */
+		HALMAC_REG_W8(REG_HCI_OPT_CTRL + 1,
+			      HALMAC_REG_R8(REG_HCI_OPT_CTRL + 1) | BIT(0));
+	}
+
+	/* Config PIN Mux */
+	value32 = HALMAC_REG_R32(REG_PAD_CTRL1);
+	value32 = value32 & (~(BIT(28) | BIT(29)));
+	value32 = value32 | BIT(28) | BIT(29);
+	HALMAC_REG_W32(REG_PAD_CTRL1, value32);
+
+	value32 = HALMAC_REG_R32(REG_LED_CFG);
+	value32 = value32 & (~(BIT(25) | BIT(26)));
+	HALMAC_REG_W32(REG_LED_CFG, value32);
+
+	value32 = HALMAC_REG_R32(REG_GPIO_MUXCFG);
+	value32 = value32 & (~(BIT(2)));
+	value32 = value32 | BIT(2);
+	HALMAC_REG_W32(REG_GPIO_MUXCFG, value32);
+
+	enable_bb = 0;
+	set_hw_value_88xx(adapter, HALMAC_HW_EN_BB_RF, &enable_bb);
+
+	if (HALMAC_REG_R8(REG_SYS_CFG1 + 2) & BIT(4)) {
+		pr_err("test mode!!\n");
+		return HALMAC_RET_WLAN_MODE_FAIL;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * init_system_cfg_88xx() -  init system config
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_system_cfg_88xx(struct halmac_adapter *adapter)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u32 tmp = 0;
+	u32 value32;
+	enum halmac_ret_status status;
+	u8 hwval;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (adapter->intf == HALMAC_INTERFACE_PCIE) {
+		hwval = 1;
+		status = api->halmac_set_hw_value(adapter,
+						  HALMAC_HW_PCIE_REF_AUTOK,
+						  &hwval);
+		if (status != HALMAC_RET_SUCCESS)
+			return status;
+	}
+
+	value32 = HALMAC_REG_R32(REG_SYS_SDIO_CTRL) | BIT_LTE_MUX_CTRL_PATH;
+	HALMAC_REG_W32(REG_SYS_SDIO_CTRL, value32);
+
+	value32 = HALMAC_REG_R32(REG_CPU_DMEM_CON) | BIT_WL_PLATFORM_RST;
+	HALMAC_REG_W32(REG_CPU_DMEM_CON, value32);
+
+	HALMAC_REG_W8(REG_SYS_FUNC_EN + 1, SYS_FUNC_EN);
+
+	/*disable boot-from-flash for driver's DL FW*/
+	tmp = HALMAC_REG_R32(REG_MCUFW_CTRL);
+	if (tmp & BIT_BOOT_FSPI_EN) {
+		HALMAC_REG_W32(REG_MCUFW_CTRL, tmp & (~BIT_BOOT_FSPI_EN));
+		value32 = HALMAC_REG_R32(REG_GPIO_MUXCFG) & (~BIT_FSPI_EN);
+		HALMAC_REG_W32(REG_GPIO_MUXCFG, value32);
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * init_edca_cfg_88xx() - init EDCA config
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_edca_cfg_88xx(struct halmac_adapter *adapter)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	/* Clear TX pause */
+	HALMAC_REG_W16(REG_TXPAUSE, 0x0000);
+
+	HALMAC_REG_W8(REG_SLOT, WLAN_SLOT_TIME);
+	HALMAC_REG_W8(REG_PIFS, WLAN_PIFS_TIME);
+	HALMAC_REG_W32(REG_SIFS, WLAN_SIFS_CFG);
+
+	HALMAC_REG_W16(REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT);
+	HALMAC_REG_W16(REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT);
+
+	HALMAC_REG_W32(REG_RD_NAV_NXT, WLAN_NAV_CFG);
+	HALMAC_REG_W16(REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG);
+
+	/* Set beacon cotnrol - enable TSF and other related functions */
+	HALMAC_REG_W8(REG_BCN_CTRL, (u8)(HALMAC_REG_R8(REG_BCN_CTRL) |
+					  BIT_EN_BCN_FUNCTION));
+
+	/* Set send beacon related registers */
+	HALMAC_REG_W32(REG_TBTT_PROHIBIT, WLAN_TBTT_TIME);
+	HALMAC_REG_W8(REG_DRVERLYINT, WLAN_DRV_EARLY_INT);
+	HALMAC_REG_W8(REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
+
+	HALMAC_REG_W8_CLR(REG_TX_PTCL_CTRL + 1, BIT(4));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * init_wmac_cfg_88xx() - init wmac config
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_wmac_cfg_88xx(struct halmac_adapter *adapter)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	HALMAC_REG_W32(REG_RXFLTMAP0, WLAN_RX_FILTER0);
+	HALMAC_REG_W16(REG_RXFLTMAP2, WLAN_RX_FILTER2);
+
+	HALMAC_REG_W32(REG_RCR, WLAN_RCR_CFG);
+
+	HALMAC_REG_W8(REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512);
+
+	HALMAC_REG_W8(REG_TCR + 2, WLAN_TX_FUNC_CFG2);
+	HALMAC_REG_W8(REG_TCR + 1, WLAN_TX_FUNC_CFG1);
+
+	HALMAC_REG_W32(REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
+
+	if (adapter->hw_cfg_info.trx_mode == HALMAC_TRNSFER_NORMAL)
+		value8 = WLAN_MAC_OPT_NORM_FUNC1;
+	else
+		value8 = WLAN_MAC_OPT_LB_FUNC1;
+
+	HALMAC_REG_W8(REG_WMAC_OPTION_FUNCTION + 4, value8);
+
+	status = api->halmac_init_low_pwr(adapter);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * init_mac_cfg_88xx() - config page1~page7 register
+ * @adapter : the adapter of halmac
+ * @mode : trx mode
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_mac_cfg_88xx(struct halmac_adapter *adapter, enum halmac_trx_mode mode)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = api->halmac_init_trx_cfg(adapter, mode);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("init trx %x\n", status);
+		return status;
+	}
+
+	status = api->halmac_init_protocol_cfg(adapter);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("init ptcl %x\n", status);
+		return status;
+	}
+
+	status = init_edca_cfg_88xx(adapter);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("init edca %x\n", status);
+		return status;
+	}
+
+	status = init_wmac_cfg_88xx(adapter);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("init wmac %x\n", status);
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return status;
+}
+
+/**
+ * reset_ofld_feature_88xx() -reset async api cmd status
+ * @adapter : the adapter of halmac
+ * @feature_id : feature_id
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status.
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reset_ofld_feature_88xx(struct halmac_adapter *adapter,
+			enum halmac_feature_id feature_id)
+{
+	struct halmac_state *state = &adapter->halmac_state;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	switch (feature_id) {
+	case HALMAC_FEATURE_CFG_PARA:
+		state->cfg_param_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->cfg_param_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+		break;
+	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
+	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
+		state->efuse_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->efuse_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+		break;
+	case HALMAC_FEATURE_CHANNEL_SWITCH:
+		state->scan_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->scan_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+		break;
+	case HALMAC_FEATURE_UPDATE_PACKET:
+		state->update_pkt_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		break;
+	case HALMAC_FEATURE_IQK:
+		state->iqk_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		break;
+	case HALMAC_FEATURE_POWER_TRACKING:
+		state->pwr_trk_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		break;
+	case HALMAC_FEATURE_PSD:
+		state->psd_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		break;
+	case HALMAC_FEATURE_FW_SNDING:
+		state->fw_snding_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->fw_snding_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+		break;
+	case HALMAC_FEATURE_ALL:
+		state->cfg_param_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->cfg_param_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+		state->efuse_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->efuse_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+		state->scan_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->scan_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+		state->update_pkt_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->iqk_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->pwr_trk_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->psd_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->fw_snding_state.proc_status = HALMAC_CMD_PROCESS_IDLE;
+		state->fw_snding_state.cmd_cnstr_state = HALMAC_CMD_CNSTR_IDLE;
+		break;
+	default:
+		pr_err("invalid feature id\n");
+		return HALMAC_RET_INVALID_FEATURE_ID;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * (debug API)verify_platform_api_88xx() - verify platform api
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+verify_platform_api_88xx(struct halmac_adapter *adapter)
+{
+	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	ret_status = verify_io_88xx(adapter);
+
+	if (ret_status != HALMAC_RET_SUCCESS)
+		return ret_status;
+
+	if (adapter->txff_alloc.la_mode != HALMAC_LA_MODE_FULL)
+		ret_status = verify_send_rsvd_page_88xx(adapter);
+
+	if (ret_status != HALMAC_RET_SUCCESS)
+		return ret_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return ret_status;
+}
+
+void
+tx_desc_chksum_88xx(struct halmac_adapter *adapter, u8 enable)
+{
+	u16 value16;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	adapter->tx_desc_checksum = enable;
+
+	value16 = HALMAC_REG_R16(REG_TXDMA_OFFSET_CHK);
+	if (enable == 1)
+		HALMAC_REG_W16(REG_TXDMA_OFFSET_CHK, value16 | BIT(13));
+	else
+		HALMAC_REG_W16(REG_TXDMA_OFFSET_CHK, value16 & ~BIT(13));
+}
+
+static enum halmac_ret_status
+verify_io_88xx(struct halmac_adapter *adapter)
+{
+	u8 value8;
+	u8 wvalue8;
+	u32 value32;
+	u32 value32_2;
+	u32 wvalue32;
+	u32 offset;
+	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		offset = REG_PAGE5_DUMMY;
+		if (0 == (offset & 0xFFFF0000))
+			offset |= WLAN_IOREG_OFFSET;
+
+		ret_status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+
+		/* Verify CMD52 R/W */
+		wvalue8 = 0xab;
+		PLTFM_SDIO_CMD52_W(offset, wvalue8);
+
+		value8 = PLTFM_SDIO_CMD52_R(offset);
+
+		if (value8 != wvalue8) {
+			pr_err("cmd52 r/w\n");
+			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+		}
+
+		/* Verify CMD53 R/W */
+		PLTFM_SDIO_CMD52_W(offset, 0xaa);
+		PLTFM_SDIO_CMD52_W(offset + 1, 0xbb);
+		PLTFM_SDIO_CMD52_W(offset + 2, 0xcc);
+		PLTFM_SDIO_CMD52_W(offset + 3, 0xdd);
+
+		value32 = PLTFM_SDIO_CMD53_R32(offset);
+
+		if (value32 != 0xddccbbaa) {
+			pr_err("cmd53 r\n");
+			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+		}
+
+		wvalue32 = 0x11223344;
+		PLTFM_SDIO_CMD53_W32(offset, wvalue32);
+
+		value32 = PLTFM_SDIO_CMD53_R32(offset);
+
+		if (value32 != wvalue32) {
+			pr_err("cmd53 w\n");
+			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+		}
+
+		/* value32 should be 0x33441122 */
+		value32 = PLTFM_SDIO_CMD53_R32(offset + 2);
+
+		wvalue32 = 0x11225566;
+		PLTFM_SDIO_CMD53_W32(offset, wvalue32);
+
+		/* value32 should be 0x55661122 */
+		value32_2 = PLTFM_SDIO_CMD53_R32(offset + 2);
+		if (value32_2 == value32) {
+			pr_err("cmd52 is used\n");
+			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+		}
+	} else {
+		wvalue32 = 0x77665511;
+		PLTFM_REG_W32(REG_PAGE5_DUMMY, wvalue32);
+
+		value32 = PLTFM_REG_R32(REG_PAGE5_DUMMY);
+		if (value32 != wvalue32) {
+			pr_err("reg rw\n");
+			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+		}
+	}
+
+	return ret_status;
+}
+
+static enum halmac_ret_status
+verify_send_rsvd_page_88xx(struct halmac_adapter *adapter)
+{
+	u8 txdesc_size = adapter->hw_cfg_info.txdesc_size;
+	u8 *rsvd_buf = NULL;
+	u8 *rsvd_page = NULL;
+	u32 i;
+	u32 pkt_size = 64;
+	u32 payload = 0xab;
+	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
+
+	rsvd_buf = kzalloc(pkt_size, GFP_KERNEL);
+
+	if (!rsvd_buf)
+		return HALMAC_RET_MALLOC_FAIL;
+
+	memset(rsvd_buf, (u8)payload, pkt_size);
+
+	ret_status = dl_rsvd_page_88xx(adapter,
+				       adapter->txff_alloc.rsvd_boundary,
+				       rsvd_buf, pkt_size);
+	if (ret_status != HALMAC_RET_SUCCESS) {
+		kfree(rsvd_buf);
+		return ret_status;
+	}
+
+	rsvd_page = kzalloc(pkt_size + txdesc_size, GFP_KERNEL);
+
+	if (!rsvd_page) {
+		kfree(rsvd_buf);
+		return HALMAC_RET_MALLOC_FAIL;
+	}
+
+	memset(rsvd_page, 0x00, pkt_size + txdesc_size);
+
+	ret_status = dump_fifo_88xx(adapter, HAL_FIFO_SEL_RSVD_PAGE, 0,
+				    pkt_size + txdesc_size, rsvd_page);
+
+	if (ret_status != HALMAC_RET_SUCCESS) {
+		kfree(rsvd_buf);
+		kfree(rsvd_page);
+		return ret_status;
+	}
+
+	for (i = 0; i < pkt_size; i++) {
+		if (*(rsvd_buf + i) != *(rsvd_page + (i + txdesc_size))) {
+			pr_err("Compare RSVD page Fail\n");
+			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
+		}
+	}
+
+	kfree(rsvd_buf);
+	kfree(rsvd_page);
+
+	return ret_status;
+}
+
+enum halmac_ret_status
+pg_num_parser_88xx(struct halmac_adapter *adapter, enum halmac_trx_mode mode,
+		   struct halmac_pg_num *tbl)
+{
+	u8 flag;
+	u16 hpq_num = 0;
+	u16 lpq_num = 0;
+	u16 npq_num = 0;
+	u16 gapq_num = 0;
+	u16 expq_num = 0;
+	u16 pubq_num = 0;
+	u32 i = 0;
+
+	flag = 0;
+	for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
+		if (mode == tbl[i].mode) {
+			hpq_num = tbl[i].hq_num;
+			lpq_num = tbl[i].lq_num;
+			npq_num = tbl[i].nq_num;
+			expq_num = tbl[i].exq_num;
+			gapq_num = tbl[i].gap_num;
+			pubq_num = adapter->txff_alloc.acq_pg_num - hpq_num -
+					lpq_num - npq_num - expq_num - gapq_num;
+			flag = 1;
+			RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+				 "%s done\n", __func__);
+			break;
+		}
+	}
+
+	if (flag == 0) {
+		pr_err("trx mode!!\n");
+		return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
+	}
+
+	if (adapter->txff_alloc.acq_pg_num <
+	    hpq_num + lpq_num + npq_num + expq_num + gapq_num) {
+		pr_err("acqnum = %d\n", adapter->txff_alloc.acq_pg_num);
+		pr_err("hpq_num = %d\n", hpq_num);
+		pr_err("LPQ_num = %d\n", lpq_num);
+		pr_err("npq_num = %d\n", npq_num);
+		pr_err("EPQ_num = %d\n", expq_num);
+		pr_err("gapq_num = %d\n", gapq_num);
+		return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
+	}
+
+	adapter->txff_alloc.high_queue_pg_num = hpq_num;
+	adapter->txff_alloc.low_queue_pg_num = lpq_num;
+	adapter->txff_alloc.normal_queue_pg_num = npq_num;
+	adapter->txff_alloc.extra_queue_pg_num = expq_num;
+	adapter->txff_alloc.pub_queue_pg_num = pubq_num;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+rqpn_parser_88xx(struct halmac_adapter *adapter, enum halmac_trx_mode mode,
+		 struct halmac_rqpn *tbl)
+{
+	u8 flag;
+	u32 i;
+
+	flag = 0;
+	for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
+		if (mode == tbl[i].mode) {
+			adapter->pq_map[HALMAC_PQ_MAP_VO] = tbl[i].dma_map_vo;
+			adapter->pq_map[HALMAC_PQ_MAP_VI] = tbl[i].dma_map_vi;
+			adapter->pq_map[HALMAC_PQ_MAP_BE] = tbl[i].dma_map_be;
+			adapter->pq_map[HALMAC_PQ_MAP_BK] = tbl[i].dma_map_bk;
+			adapter->pq_map[HALMAC_PQ_MAP_MG] = tbl[i].dma_map_mg;
+			adapter->pq_map[HALMAC_PQ_MAP_HI] = tbl[i].dma_map_hi;
+			flag = 1;
+			RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+				 "%s done\n", __func__);
+			break;
+		}
+	}
+
+	if (flag == 0) {
+		pr_err("trx mdoe!!\n");
+		return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.h
new file mode 100644
index 000000000000..469988484b8e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_init_88xx.h
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_INIT_88XX_H_
+#define _HALMAC_INIT_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+register_api_88xx(struct halmac_adapter *adapter,
+		  struct halmac_api_registry *registry);
+
+void
+init_adapter_param_88xx(struct halmac_adapter *adapter);
+
+void
+init_adapter_dynamic_param_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+mount_api_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+pre_init_system_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+init_system_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+init_edca_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+init_wmac_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+init_mac_cfg_88xx(struct halmac_adapter *adapter, enum halmac_trx_mode mode);
+
+enum halmac_ret_status
+reset_ofld_feature_88xx(struct halmac_adapter *adapter,
+			enum halmac_feature_id feature_id);
+
+enum halmac_ret_status
+verify_platform_api_88xx(struct halmac_adapter *adapter);
+
+void
+tx_desc_chksum_88xx(struct halmac_adapter *adapter, u8 enable);
+
+enum halmac_ret_status
+pg_num_parser_88xx(struct halmac_adapter *adapter, enum halmac_trx_mode mode,
+		   struct halmac_pg_num *tbl);
+
+enum halmac_ret_status
+rqpn_parser_88xx(struct halmac_adapter *adapter, enum halmac_trx_mode mode,
+		 struct halmac_rqpn *tbl);
+
+void
+init_ofld_feature_state_machine_88xx(struct halmac_adapter *adapter);
+
+#endif/* _HALMAC_INIT_88XX_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.c
new file mode 100644
index 000000000000..cd9de2baab8b
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.c
@@ -0,0 +1,438 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_type.h"
+#include "halmac_api.h"
+
+#include "halmac_88xx/halmac_init_88xx.h"
+
+enum chip_id_hw_def {
+	CHIP_ID_HW_DEF_8723A = 0x01,
+	CHIP_ID_HW_DEF_8188E = 0x02,
+	CHIP_ID_HW_DEF_8881A = 0x03,
+	CHIP_ID_HW_DEF_8812A = 0x04,
+	CHIP_ID_HW_DEF_8821A = 0x05,
+	CHIP_ID_HW_DEF_8723B = 0x06,
+	CHIP_ID_HW_DEF_8192E = 0x07,
+	CHIP_ID_HW_DEF_8814A = 0x08,
+	CHIP_ID_HW_DEF_8821C = 0x09,
+	CHIP_ID_HW_DEF_8822B = 0x0A,
+	CHIP_ID_HW_DEF_8703B = 0x0B,
+	CHIP_ID_HW_DEF_8188F = 0x0C,
+	CHIP_ID_HW_DEF_8192F = 0x0D,
+	CHIP_ID_HW_DEF_8197F = 0x0E,
+	CHIP_ID_HW_DEF_8723D = 0x0F,
+	CHIP_ID_HW_DEF_8814B = 0x11,
+	CHIP_ID_HW_DEF_8822C = 0x13,
+	CHIP_ID_HW_DEF_UNDEFINE = 0x7F,
+	CHIP_ID_HW_DEF_PS = 0xEA,
+};
+
+static enum halmac_ret_status
+chk_pltfm_api(void *drv_adapter, enum halmac_interface intf,
+	      struct halmac_platform_api *pltfm_api);
+
+static enum halmac_ret_status
+get_chip_info(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+	      enum halmac_interface intf, struct halmac_adapter *adapter);
+
+static u8
+pltfm_reg_r8_sdio(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+		  u32 offset);
+
+static enum halmac_ret_status
+pltfm_reg_w8_sdio(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+		  u32 offset, u8 data);
+
+static u8
+pltfm_reg_r_indir_sdio(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+		       u32 offset);
+
+static enum halmac_ret_status
+cnv_to_sdio_bus_offset(u32 *offset);
+
+/**
+ * halmac_init_adapter() - init halmac_adapter
+ * @drv_adapter : the adapter of caller
+ * @pltfm_api : the platform APIs which is used in halmac
+ * @intf : bus interface
+ * @halmac_adapter : the adapter of halmac
+ * @halmac_api : the function pointer of APIs
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_init_adapter(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+		    enum halmac_interface intf,
+		    struct halmac_adapter **halmac_adapter,
+		    struct halmac_api **halmac_api)
+{
+	struct halmac_adapter *adapter = NULL;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	u8 *buf = NULL;
+
+	status = chk_pltfm_api(drv_adapter, intf, pltfm_api);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	RT_TRACE(drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 HALMAC_SVN_VER "\n"
+		 "HALMAC_MAJOR_VER = %x\n"
+		 "HALMAC_PROTOTYPE_VER = %x\n"
+		 "HALMAC_MINOR_VER = %x\n"
+		 "HALMAC_PATCH_VER = %x\n", HALMAC_MAJOR_VER,
+		 HALMAC_PROTOTYPE_VER, HALMAC_MINOR_VER, HALMAC_PATCH_VER);
+
+	buf = kzalloc(sizeof(*adapter), GFP_KERNEL);
+
+	if (!buf)
+		return HALMAC_RET_MALLOC_FAIL;
+	memset(buf, 0x00, sizeof(*adapter));
+	adapter = (struct halmac_adapter *)buf;
+
+	*halmac_adapter = adapter;
+
+	adapter->pltfm_api = pltfm_api;
+	adapter->drv_adapter = drv_adapter;
+	intf = (intf == HALMAC_INTERFACE_AXI) ? HALMAC_INTERFACE_PCIE : intf;
+	adapter->intf = intf;
+
+	if (get_chip_info(drv_adapter, pltfm_api, intf, adapter)
+	    != HALMAC_RET_SUCCESS) {
+		kfree(*halmac_adapter);
+		*halmac_adapter = NULL;
+		return HALMAC_RET_CHIP_NOT_SUPPORT;
+	}
+
+	mutex_init(&adapter->efuse_mutex);
+	mutex_init(&adapter->h2c_seq_mutex);
+	mutex_init(&adapter->sdio_indir_mutex);
+
+	if (adapter->chip_id == HALMAC_CHIP_ID_8822B ||
+	    adapter->chip_id == HALMAC_CHIP_ID_8821C ||
+	    adapter->chip_id == HALMAC_CHIP_ID_8822C) {
+		init_adapter_param_88xx(adapter);
+		status = mount_api_88xx(adapter);
+	}
+
+	*halmac_api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return status;
+}
+
+/**
+ * halmac_halt_api() - stop halmac_api action
+ * @adapter : the adapter of halmac
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_halt_api(struct halmac_adapter *adapter)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	adapter->halmac_state.api_state = HALMAC_API_STATE_HALT;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_deinit_adapter() - deinit halmac adapter
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_deinit_adapter(struct halmac_adapter *adapter)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	mutex_destroy(&adapter->efuse_mutex);
+	mutex_destroy(&adapter->h2c_seq_mutex);
+	mutex_destroy(&adapter->sdio_indir_mutex);
+
+	kfree(adapter->efuse_map);
+	adapter->efuse_map = (u8 *)NULL;
+	kfree(adapter->sdio_fs.macid_map);
+	adapter->sdio_fs.macid_map = (u8 *)NULL;
+	kfree(adapter->halmac_state.psd_state.data);
+	adapter->halmac_state.psd_state.data = (u8 *)NULL;
+	kfree(adapter->halmac_api);
+	adapter->halmac_api = NULL;
+
+	kfree(adapter);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+chk_pltfm_api(void *drv_adapter, enum halmac_interface intf,
+	      struct halmac_platform_api *pltfm_api)
+{
+	if (!pltfm_api)
+		return HALMAC_RET_PLATFORM_API_NULL;
+
+	if (intf == HALMAC_INTERFACE_SDIO) {
+		if (!pltfm_api->SDIO_CMD52_READ) {
+			pr_err("sdio-r\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD53_READ_8) {
+			pr_err("sdio-r8\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD53_READ_16) {
+			pr_err("sdio-r16\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD53_READ_32) {
+			pr_err("sdio-r32\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD53_READ_N) {
+			pr_err("sdio-rn\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD52_WRITE) {
+			pr_err("sdio-w\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD53_WRITE_8) {
+			pr_err("sdio-w8\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD53_WRITE_16) {
+			pr_err("sdio-w16\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD53_WRITE_32) {
+			pr_err("sdio-w32\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->SDIO_CMD52_CIA_READ) {
+			pr_err("sdio-cia\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+	}
+
+	if (intf == HALMAC_INTERFACE_USB || intf == HALMAC_INTERFACE_PCIE) {
+		if (!pltfm_api->REG_READ_8) {
+			pr_err("reg-r8\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->REG_READ_16) {
+			pr_err("reg-r16\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->REG_READ_32) {
+			pr_err("reg-r32\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->REG_WRITE_8) {
+			pr_err("reg-w8\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->REG_WRITE_16) {
+			pr_err("reg-w16\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+		if (!pltfm_api->REG_WRITE_32) {
+			pr_err("reg-w32\n");
+			return HALMAC_RET_PLATFORM_API_NULL;
+		}
+	}
+
+	if (!pltfm_api->EVENT_INDICATION) {
+		pr_err("event-indication\n");
+		return HALMAC_RET_PLATFORM_API_NULL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_version() - get HALMAC version
+ * @version : return version of major, prototype and minor information
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+halmac_get_version(struct halmac_ver *version)
+{
+	version->major_ver = (u8)HALMAC_MAJOR_VER;
+	version->prototype_ver = (u8)HALMAC_PROTOTYPE_VER;
+	version->minor_ver = (u8)HALMAC_MINOR_VER;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+get_chip_info(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+	      enum halmac_interface intf, struct halmac_adapter *adapter)
+{
+	u8 chip_id;
+	u8 chip_ver;
+	u32 cnt;
+
+	if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+		pltfm_reg_w8_sdio(drv_adapter, pltfm_api, REG_SDIO_HSUS_CTRL,
+				  pltfm_reg_r8_sdio(drv_adapter, pltfm_api,
+						    REG_SDIO_HSUS_CTRL) &
+						    ~(BIT(0)));
+
+		cnt = 10000;
+		while (!(pltfm_reg_r8_sdio(drv_adapter, pltfm_api,
+					   REG_SDIO_HSUS_CTRL) & BIT(1))) {
+			cnt--;
+			if (cnt == 0)
+				return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
+		}
+
+		chip_id = pltfm_reg_r_indir_sdio(drv_adapter, pltfm_api,
+						 REG_SYS_CFG2);
+		chip_ver = pltfm_reg_r_indir_sdio(drv_adapter, pltfm_api,
+						  REG_SYS_CFG1 + 1) >> 4;
+	} else {
+		chip_id = pltfm_api->REG_READ_8(drv_adapter, REG_SYS_CFG2);
+		chip_ver = pltfm_api->REG_READ_8(drv_adapter,
+						 REG_SYS_CFG1 + 1) >> 4;
+	}
+
+	adapter->chip_ver = (enum halmac_chip_ver)chip_ver;
+
+	if (chip_id == CHIP_ID_HW_DEF_8822B) {
+		adapter->chip_id = HALMAC_CHIP_ID_8822B;
+	} else if (chip_id == CHIP_ID_HW_DEF_8821C) {
+		adapter->chip_id = HALMAC_CHIP_ID_8821C;
+	} else if (chip_id == CHIP_ID_HW_DEF_8814B) {
+		adapter->chip_id = HALMAC_CHIP_ID_8814B;
+	} else if (chip_id == CHIP_ID_HW_DEF_8197F) {
+		adapter->chip_id = HALMAC_CHIP_ID_8197F;
+	} else if (chip_id == CHIP_ID_HW_DEF_8822C) {
+		adapter->chip_id = HALMAC_CHIP_ID_8822C;
+	} else {
+		adapter->chip_id = HALMAC_CHIP_ID_UNDEFINE;
+		pr_err("Chip id is undefined\n");
+		return HALMAC_RET_CHIP_NOT_SUPPORT;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static u8
+pltfm_reg_r8_sdio(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+		  u32 offset)
+{
+	u8 value8;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (0 == (offset & 0xFFFF0000))
+		offset |= WLAN_IOREG_OFFSET;
+
+	status = cnv_to_sdio_bus_offset(&offset);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	value8 = pltfm_api->SDIO_CMD52_READ(drv_adapter, offset);
+
+	return value8;
+}
+
+static enum halmac_ret_status
+pltfm_reg_w8_sdio(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+		  u32 offset, u8 data)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (0 == (offset & 0xFFFF0000))
+		offset |= WLAN_IOREG_OFFSET;
+
+	status = cnv_to_sdio_bus_offset(&offset);
+
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	pltfm_api->SDIO_CMD52_WRITE(drv_adapter, offset, data);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static u8
+pltfm_reg_r_indir_sdio(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+		       u32 offset)
+{
+	u8 value8, tmp, cnt = 50;
+	u32 reg_cfg = REG_SDIO_INDIRECT_REG_CFG;
+	u32 reg_data = REG_SDIO_INDIRECT_REG_DATA;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	status = cnv_to_sdio_bus_offset(&reg_cfg);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+	status = cnv_to_sdio_bus_offset(&reg_data);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	pltfm_api->SDIO_CMD52_WRITE(drv_adapter, reg_cfg, (u8)offset);
+	pltfm_api->SDIO_CMD52_WRITE(drv_adapter, reg_cfg + 1,
+				    (u8)(offset >> 8));
+	pltfm_api->SDIO_CMD52_WRITE(drv_adapter, reg_cfg + 2,
+				    (u8)(BIT(3) | BIT(4)));
+
+	do {
+		tmp = pltfm_api->SDIO_CMD52_READ(drv_adapter, reg_cfg + 2);
+		cnt--;
+	} while (((tmp & BIT(4)) == 0) && (cnt > 0));
+
+	if (((cnt & BIT(4)) == 0) && cnt == 0)
+		pr_err("sdio indir read\n");
+
+	value8 = pltfm_api->SDIO_CMD52_READ(drv_adapter, reg_data);
+
+	return value8;
+}
+
+/*Note: copy from cnv_to_sdio_bus_offset_88xx*/
+static enum halmac_ret_status
+cnv_to_sdio_bus_offset(u32 *offset)
+{
+	switch ((*offset) & 0xFFFF0000) {
+	case WLAN_IOREG_OFFSET:
+		*offset &= HALMAC_WLAN_MAC_REG_MSK;
+		*offset |= HALMAC_SDIO_CMD_ADDR_MAC_REG << 13;
+		break;
+	case SDIO_LOCAL_OFFSET:
+		*offset &= HALMAC_SDIO_LOCAL_MSK;
+		*offset |= HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13;
+		break;
+	default:
+		*offset = 0xFFFFFFFF;
+		return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.h
new file mode 100644
index 000000000000..5bbd6b374ce0
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_api.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_API_H_
+#define _HALMAC_API_H_
+
+#define HALMAC_SVN_VER  "11692M"
+
+#define HALMAC_MAJOR_VER        0x0002
+#define HALMAC_PROTOTYPE_VER    0x0004
+#define HALMAC_MINOR_VER        0x0010
+#define HALMAC_PATCH_VER        0x0000
+
+#include "../wifi.h"
+#include "halmac_type.h"
+#include "halmac_usb_reg.h"
+#include "halmac_sdio_reg.h"
+#include "halmac_pcie_reg.h"
+#include "halmac_bit2.h"
+#include "halmac_reg2.h"
+
+#include "halmac_reg_8822b.h"
+#include "halmac_bit_8822b.h"
+
+#include "halmac_tx_desc_nic.h"
+#include "halmac_rx_desc_nic.h"
+#include "halmac_tx_bd_nic.h"
+#include "halmac_rx_bd_nic.h"
+#include "halmac_fw_offload_c2h_nic.h"
+#include "halmac_fw_offload_h2c_nic.h"
+#include "halmac_h2c_extra_info_nic.h"
+#include "halmac_original_c2h_nic.h"
+#include "halmac_original_h2c_nic.h"
+
+#include "halmac_tx_desc_chip.h"
+#include "halmac_rx_desc_chip.h"
+
+enum halmac_ret_status
+halmac_init_adapter(void *drv_adapter, struct halmac_platform_api *pltfm_api,
+		    enum halmac_interface intf,
+		    struct halmac_adapter **halmac_adapter,
+		    struct halmac_api **halmac_api);
+
+enum halmac_ret_status
+halmac_deinit_adapter(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+halmac_halt_api(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+halmac_get_version(struct halmac_ver *version);
+
+#endif
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 13/17] rtlwifi: halmac: add firmware related functions and definitions
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (10 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 12/17] rtlwifi: halmac: add halmac init/deinit functions pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 14/17] rtlwifi: halmac: add bus interface commands pkshih
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

Add H2C, C2H, fw header format, download firmware, etc.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.c |  316 ++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.h |   35 +
 .../rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.c    | 1149 ++++++++++++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.h    |   57 +
 .../realtek/rtlwifi/halmac/halmac_fw_info.h        |  119 ++
 .../rtlwifi/halmac/halmac_fw_offload_c2h_nic.h     |  371 +++++++
 .../rtlwifi/halmac/halmac_fw_offload_h2c_nic.h     |  694 ++++++++++++
 .../rtlwifi/halmac/halmac_h2c_extra_info_nic.h     |  171 +++
 .../rtlwifi/halmac/halmac_original_c2h_nic.h       |  408 +++++++
 .../rtlwifi/halmac/halmac_original_h2c_nic.h       | 1143 +++++++++++++++++++
 10 files changed, 4463 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_info.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_h2c_extra_info_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_c2h_nic.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_h2c_nic.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.c
new file mode 100644
index 000000000000..aabedfd84cc6
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.c
@@ -0,0 +1,316 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2017 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_flash_88xx.h"
+#include "halmac_88xx_cfg.h"
+#include "halmac_common_88xx.h"
+
+/**
+ * download_flash_88xx() -download firmware to flash
+ * @adapter : the adapter of halmac
+ * @fw_bin : pointer to fw
+ * @size : fw size
+ * @rom_addr : flash start address where fw should be download
+ * Author : Pablo Chiu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+download_flash_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size,
+		    u32 rom_addr)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status rc;
+	struct halmac_h2c_header_info hdr_info;
+	u8 value8;
+	u8 restore[3];
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = {0};
+	u16 seq_num = 0;
+	u16 h2c_info_offset;
+	u32 pkt_size;
+	u32 mem_offset;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	value8 = HALMAC_REG_R8(REG_CR + 1);
+	restore[0] = value8;
+	value8 = (u8)(value8 | BIT(0));
+	HALMAC_REG_W8(REG_CR + 1, value8);
+
+	value8 = HALMAC_REG_R8(REG_BCN_CTRL);
+	restore[1] = value8;
+	value8 = (u8)((value8 & ~(BIT(3))) | BIT(4));
+	HALMAC_REG_W8(REG_BCN_CTRL, value8);
+
+	value8 = HALMAC_REG_R8(REG_FWHW_TXQ_CTRL + 2);
+	restore[2] = value8;
+	value8 = (u8)(value8 & ~(BIT(6)));
+	HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, value8);
+
+	/* Download FW to Flash flow */
+	h2c_info_offset = adapter->txff_alloc.rsvd_h2c_info_addr -
+					adapter->txff_alloc.rsvd_boundary;
+	mem_offset = 0;
+
+	while (size != 0) {
+		if (size >= (DL_FLASH_RSVDPG_SIZE - 48))
+			pkt_size = DL_FLASH_RSVDPG_SIZE - 48;
+		else
+			pkt_size = size;
+
+		rc = dl_rsvd_page_88xx(adapter,
+				       adapter->txff_alloc.rsvd_h2c_info_addr,
+				       fw_bin + mem_offset, pkt_size);
+		if (rc != HALMAC_RET_SUCCESS) {
+			pr_err("dl rsvd pg!!\n");
+			return rc;
+		}
+
+		DOWNLOAD_FLASH_SET_SPI_CMD(h2c_buf, 0x02);
+		DOWNLOAD_FLASH_SET_LOCATION(h2c_buf, h2c_info_offset);
+		DOWNLOAD_FLASH_SET_SIZE(h2c_buf, pkt_size);
+		DOWNLOAD_FLASH_SET_START_ADDR(h2c_buf, rom_addr);
+
+		hdr_info.sub_cmd_id = SUB_CMD_ID_DOWNLOAD_FLASH;
+		hdr_info.content_size = 20;
+		hdr_info.ack = 1;
+		set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+		rc = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+		if (rc != HALMAC_RET_SUCCESS) {
+			pr_err("send h2c!!\n");
+			return rc;
+		}
+
+		value8 = HALMAC_REG_R8(REG_MCUTST_I);
+		value8 |= BIT(0);
+		HALMAC_REG_W8(REG_MCUTST_I, value8);
+
+		rom_addr += pkt_size;
+		mem_offset += pkt_size;
+		size -= pkt_size;
+
+		while (((HALMAC_REG_R8(REG_MCUTST_I)) & BIT(0)) != 0)
+			usleep_range(1000, 1100);
+
+		if (((HALMAC_REG_R8(REG_MCUTST_I)) & BIT(0)) != 0) {
+			pr_err("dl flash!!\n");
+			return  HALMAC_RET_DLFW_FAIL;
+		}
+	}
+
+	HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, restore[2]);
+	HALMAC_REG_W8(REG_BCN_CTRL, restore[1]);
+	HALMAC_REG_W8(REG_CR + 1, restore[0]);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * read_flash_88xx() -read data from flash
+ * @adapter : the adapter of halmac
+ * @addr : flash start address where fw should be read
+ * Author : Pablo Chiu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+read_flash_88xx(struct halmac_adapter *adapter, u32 addr, u32 length)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status;
+	struct halmac_h2c_header_info hdr_info;
+	u8 value8;
+	u8 restore[3];
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = {0};
+	u16 seq_num = 0;
+	u16 h2c_info_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
+	u16 rsvd_pg_addr = adapter->txff_alloc.rsvd_boundary;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	value8 = HALMAC_REG_R8(REG_CR + 1);
+	restore[0] = value8;
+	value8 = (u8)(value8 | BIT(0));
+	HALMAC_REG_W8(REG_CR + 1, value8);
+
+	value8 = HALMAC_REG_R8(REG_BCN_CTRL);
+	restore[1] = value8;
+	value8 = (u8)((value8 & ~(BIT(3))) | BIT(4));
+	HALMAC_REG_W8(REG_BCN_CTRL, value8);
+
+	value8 = HALMAC_REG_R8(REG_FWHW_TXQ_CTRL + 2);
+	restore[2] = value8;
+	value8 = (u8)(value8 & ~(BIT(6)));
+	HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, value8);
+
+	HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, h2c_info_addr);
+	value8 = HALMAC_REG_R8(REG_MCUTST_I);
+	value8 |= BIT(0);
+	HALMAC_REG_W8(REG_MCUTST_I, value8);
+
+	/* Construct H2C Content */
+	DOWNLOAD_FLASH_SET_SPI_CMD(h2c_buf, 0x03);
+	DOWNLOAD_FLASH_SET_LOCATION(h2c_buf, h2c_info_addr - rsvd_pg_addr);
+	DOWNLOAD_FLASH_SET_SIZE(h2c_buf, length);
+	DOWNLOAD_FLASH_SET_START_ADDR(h2c_buf, addr);
+
+	/* Fill in H2C Header */
+	hdr_info.sub_cmd_id = SUB_CMD_ID_DOWNLOAD_FLASH;
+	hdr_info.content_size = 16;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	/* Send H2C Cmd Packet */
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c!!\n");
+		return status;
+	}
+
+	while (((HALMAC_REG_R8(REG_MCUTST_I)) & BIT(0)) != 0)
+		usleep_range(1000, 1100);
+
+	HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, rsvd_pg_addr);
+	HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, restore[2]);
+	HALMAC_REG_W8(REG_BCN_CTRL, restore[1]);
+	HALMAC_REG_W8(REG_CR + 1, restore[0]);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * erase_flash_88xx() -erase flash data
+ * @adapter : the adapter of halmac
+ * @erase_cmd : erase command
+ * @addr : flash start address where fw should be erased
+ * Author : Pablo Chiu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+erase_flash_88xx(struct halmac_adapter *adapter, u8 erase_cmd, u32 addr)
+{
+	enum halmac_ret_status status;
+	struct halmac_h2c_header_info hdr_info;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u8 value8;
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = {0};
+	u16 seq_num = 0;
+	u32 cnt;
+
+	/* Construct H2C Content */
+	DOWNLOAD_FLASH_SET_SPI_CMD(h2c_buf, erase_cmd);
+	DOWNLOAD_FLASH_SET_LOCATION(h2c_buf, 0);
+	DOWNLOAD_FLASH_SET_START_ADDR(h2c_buf, addr);
+	DOWNLOAD_FLASH_SET_SIZE(h2c_buf, 0);
+
+	value8 = HALMAC_REG_R8(REG_MCUTST_I);
+	value8 |= BIT(0);
+	HALMAC_REG_W8(REG_MCUTST_I, value8);
+
+	/* Fill in H2C Header */
+	hdr_info.sub_cmd_id = SUB_CMD_ID_DOWNLOAD_FLASH;
+	hdr_info.content_size = 16;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	/* Send H2C Cmd Packet */
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS)
+		pr_err("send h2c!!\n");
+
+	cnt = 5000;
+	while (((HALMAC_REG_R8(REG_MCUTST_I)) & BIT(0)) != 0 && cnt != 0) {
+		usleep_range(1000, 1100);
+		cnt--;
+	}
+
+	if (cnt == 0)
+		return HALMAC_RET_FAIL;
+	else
+		return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * check_flash_88xx() -check flash data
+ * @adapter : the adapter of halmac
+ * @fw_bin : pointer to fw
+ * @size : fw size
+ * @addr : flash start address where fw should be checked
+ * Author : Pablo Chiu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+check_flash_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size,
+		 u32 addr)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u8 value8;
+	u16 i;
+	u16 residue;
+	u16 pg_addr;
+	u32 pkt_size;
+	u32 start_page;
+	u32 cnt;
+
+	pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
+
+	while (size != 0) {
+		start_page = ((pg_addr << 7) >> 12) + 0x780;
+		residue = (pg_addr << 7) & (4096 - 1);
+
+		if (size >= DL_FLASH_RSVDPG_SIZE)
+			pkt_size = DL_FLASH_RSVDPG_SIZE;
+		else
+			pkt_size = size;
+
+		read_flash_88xx(adapter, addr, 4096);
+
+		cnt = 0;
+		while (cnt < pkt_size) {
+			HALMAC_REG_W16(REG_PKTBUF_DBG_CTRL, (u16)(start_page));
+			for (i = 0x8000 + residue; i <= 0x8FFF; i++) {
+				value8 = HALMAC_REG_R8(i);
+				if (*fw_bin != value8) {
+					pr_err("check flash!!\n");
+					return HALMAC_RET_FAIL;
+				}
+
+				fw_bin++;
+				cnt++;
+				if (cnt == pkt_size)
+					break;
+			}
+			residue = 0;
+			start_page++;
+		}
+		addr += pkt_size;
+		size -= pkt_size;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.h
new file mode 100644
index 000000000000..72564eca531b
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_flash_88xx.h
@@ -0,0 +1,35 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2017 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_FLASH_88XX_H_
+#define _HALMAC_FLASH_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+download_flash_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size,
+		    u32 rom_addr);
+
+enum halmac_ret_status
+read_flash_88xx(struct halmac_adapter *adapter, u32 addr, u32 length);
+
+enum halmac_ret_status
+erase_flash_88xx(struct halmac_adapter *adapter, u8 erase_cmd, u32 addr);
+
+enum halmac_ret_status
+check_flash_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size,
+		 u32 addr);
+
+#endif/* _HALMAC_FLASH_88XX_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.c
new file mode 100644
index 000000000000..7268cf12d707
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.c
@@ -0,0 +1,1149 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_fw_88xx.h"
+#include "halmac_88xx_cfg.h"
+#include "halmac_common_88xx.h"
+#include "halmac_init_88xx.h"
+
+#define DLFW_RESTORE_REG_NUM		6
+#define ILLEGAL_KEY_GROUP		0xFAAAAA00
+
+/* Max dlfw size can not over 31K, due to SDIO HW limitation */
+#define DLFW_PKT_SIZE_LIMIT		31744
+
+#define ID_INFORM_DLEMEM_RDY		0x80
+#define ID_INFORM_ENETR_CPU_SLEEP	0x20
+#define ID_CHECK_DLEMEM_RDY		0x80
+#define ID_CHECK_ENETR_CPU_SLEEP	0x05
+
+#define FW_STATUS_CHK_FATAL	(BIT(1) | BIT(20))
+#define FW_STATUS_CHK_ERR	(BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | \
+				 BIT(9) | BIT(12) | BIT(14) | BIT(15) | \
+				 BIT(16) | BIT(17) | BIT(18) | BIT(19) | \
+				 BIT(21) | BIT(22) | BIT(25))
+#define FW_STATUS_CHK_WARN	~(FW_STATUS_CHK_FATAL | FW_STATUS_CHK_ERR)
+
+struct halmac_backup_info {
+	u32 mac_register;
+	u32 value;
+	u8 length;
+};
+
+static enum halmac_ret_status
+update_fw_info_88xx(struct halmac_adapter *adapter, u8 *fw_bin);
+
+static void
+restore_mac_reg_88xx(struct halmac_adapter *adapter,
+		     struct halmac_backup_info *info, u32 num);
+
+static enum halmac_ret_status
+dlfw_to_mem_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 src, u32 dest,
+		 u32 size);
+
+static enum halmac_ret_status
+dlfw_end_flow_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+free_dl_fw_end_flow_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+send_fwpkt_88xx(struct halmac_adapter *adapter, u16 pg_addr, u8 *fw_bin,
+		u32 size);
+
+static enum halmac_ret_status
+iddma_dlfw_88xx(struct halmac_adapter *adapter, u32 src, u32 dest, u32 len,
+		u8 first);
+
+static enum halmac_ret_status
+iddma_en_88xx(struct halmac_adapter *adapter, u32 src, u32 dest, u32 ctrl);
+
+static enum halmac_ret_status
+check_fw_chksum_88xx(struct halmac_adapter *adapter, u32 mem_addr);
+
+static void
+fw_fatal_status_debug_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+start_dlfw_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size,
+		u32 dl_addr, u8 emem_only);
+
+static enum halmac_ret_status
+chk_fw_size_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size);
+
+static void
+chk_h2c_ver_88xx(struct halmac_adapter *adapter, u8 *fw_bin);
+
+static void
+wlan_cpu_en_88xx(struct halmac_adapter *adapter, u8 enable);
+
+static void
+pltfm_reset_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+proc_send_general_info_88xx(struct halmac_adapter *adapter,
+			    struct halmac_general_info *info);
+
+static enum halmac_ret_status
+proc_send_phydm_info_88xx(struct halmac_adapter *adapter,
+			  struct halmac_general_info *info);
+
+/**
+ * download_firmware_88xx() - download Firmware
+ * @adapter : the adapter of halmac
+ * @fw_bin : firmware bin
+ * @size : firmware size
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+download_firmware_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size)
+{
+	u8 value8;
+	u32 bckp_idx = 0;
+	u32 lte_coex_backup = 0;
+	struct halmac_backup_info bckp[DLFW_RESTORE_REG_NUM];
+	enum halmac_ret_status status;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
+		return HALMAC_RET_POWER_STATE_INVALID;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = chk_fw_size_88xx(adapter, fw_bin, size);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	chk_h2c_ver_88xx(adapter, fw_bin);
+
+	if (adapter->halmac_state.wlcpu_mode == HALMAC_WLCPU_ENTER_SLEEP)
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Enter Sleep..zZZ\n");
+
+	adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
+
+	status = ltecoex_reg_read_88xx(adapter, 0x38, &lte_coex_backup);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	wlan_cpu_en_88xx(adapter, 0);
+
+	/* set HIQ to hi priority */
+	bckp[bckp_idx].length = 1;
+	bckp[bckp_idx].mac_register = REG_TXDMA_PQ_MAP + 1;
+	bckp[bckp_idx].value = HALMAC_REG_R8(REG_TXDMA_PQ_MAP + 1);
+	bckp_idx++;
+	value8 = HALMAC_DMA_MAPPING_HIGH << 6;
+	HALMAC_REG_W8(REG_TXDMA_PQ_MAP + 1, value8);
+
+	/* DLFW only use HIQ, map HIQ to hi priority */
+	adapter->pq_map[HALMAC_PQ_MAP_HI] = HALMAC_DMA_MAPPING_HIGH;
+	bckp[bckp_idx].length = 1;
+	bckp[bckp_idx].mac_register = REG_CR;
+	bckp[bckp_idx].value = HALMAC_REG_R8(REG_CR);
+	bckp_idx++;
+	bckp[bckp_idx].length = 4;
+	bckp[bckp_idx].mac_register = REG_H2CQ_CSR;
+	bckp[bckp_idx].value = BIT(31);
+	bckp_idx++;
+	value8 = BIT_HCI_TXDMA_EN | BIT_TXDMA_EN;
+	HALMAC_REG_W8(REG_CR, value8);
+	HALMAC_REG_W32(REG_H2CQ_CSR, BIT(31));
+
+	/* Config hi priority queue and public priority queue page number */
+	bckp[bckp_idx].length = 2;
+	bckp[bckp_idx].mac_register = REG_FIFOPAGE_INFO_1;
+	bckp[bckp_idx].value = HALMAC_REG_R16(REG_FIFOPAGE_INFO_1);
+	bckp_idx++;
+	bckp[bckp_idx].length = 4;
+	bckp[bckp_idx].mac_register = REG_RQPN_CTRL_2;
+	bckp[bckp_idx].value = HALMAC_REG_R32(REG_RQPN_CTRL_2) | BIT(31);
+	bckp_idx++;
+	HALMAC_REG_W16(REG_FIFOPAGE_INFO_1, 0x200);
+	HALMAC_REG_W32(REG_RQPN_CTRL_2, bckp[bckp_idx - 1].value);
+
+	/* Disable beacon related functions */
+	value8 = HALMAC_REG_R8(REG_BCN_CTRL);
+	bckp[bckp_idx].length = 1;
+	bckp[bckp_idx].mac_register = REG_BCN_CTRL;
+	bckp[bckp_idx].value = value8;
+	bckp_idx++;
+	value8 = (u8)((value8 & (~BIT(3))) | BIT(4));
+	HALMAC_REG_W8(REG_BCN_CTRL, value8);
+
+	if (adapter->intf == HALMAC_INTERFACE_SDIO)
+		HALMAC_REG_R32(REG_SDIO_FREE_TXPG);
+
+	pltfm_reset_88xx(adapter);
+
+	status = start_dlfw_88xx(adapter, fw_bin, size, 0, 0);
+
+	restore_mac_reg_88xx(adapter, bckp, DLFW_RESTORE_REG_NUM);
+
+	if (status != HALMAC_RET_SUCCESS)
+		goto DLFW_FAIL;
+
+	status = dlfw_end_flow_88xx(adapter);
+	if (status != HALMAC_RET_SUCCESS)
+		goto DLFW_FAIL;
+
+	status = ltecoex_reg_write_88xx(adapter, 0x38, lte_coex_backup);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	adapter->halmac_state.dlfw_state = HALMAC_DLFW_DONE;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+
+DLFW_FAIL:
+
+	/* Disable FWDL_EN */
+	value8 = HALMAC_REG_R8(REG_MCUFW_CTRL);
+	value8 &= ~BIT(0);
+	HALMAC_REG_W8(REG_MCUFW_CTRL, value8);
+
+	value8 = HALMAC_REG_R8(REG_SYS_FUNC_EN + 1);
+	value8 |= BIT(2);
+	HALMAC_REG_W8(REG_SYS_FUNC_EN + 1, value8);
+
+	if (ltecoex_reg_write_88xx(adapter, 0x38, lte_coex_backup) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_LTECOEX_READY_FAIL;
+
+	return status;
+}
+
+static enum halmac_ret_status
+start_dlfw_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size,
+		u32 dl_addr, u8 emem_only)
+{
+	u8 *cur_fw;
+	u16 value16;
+	u32 imem_size;
+	u32 dmem_size;
+	u32 emem_size = 0;
+	u32 addr;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status;
+
+	dmem_size =
+		le32_to_cpu(*((__le32 *)(fw_bin + WLAN_FW_HDR_DMEM_SIZE)));
+	imem_size =
+		le32_to_cpu(*((__le32 *)(fw_bin + WLAN_FW_HDR_IMEM_SIZE)));
+	if (0 != ((*(fw_bin + WLAN_FW_HDR_MEM_USAGE)) & BIT(4)))
+		emem_size =
+		le32_to_cpu(*((__le32 *)(fw_bin + WLAN_FW_HDR_EMEM_SIZE)));
+
+	dmem_size += WLAN_FW_HDR_CHKSUM_SIZE;
+	imem_size += WLAN_FW_HDR_CHKSUM_SIZE;
+	if (emem_size != 0)
+		emem_size += WLAN_FW_HDR_CHKSUM_SIZE;
+
+	if (emem_only == 1) {
+		if (!emem_size)
+			return HALMAC_RET_SUCCESS;
+		goto DLFW_EMEM;
+	}
+
+	value16 = (u16)(HALMAC_REG_R16(REG_MCUFW_CTRL) & 0x3800);
+	value16 |= BIT(0);
+	HALMAC_REG_W16(REG_MCUFW_CTRL, value16);
+
+	cur_fw = fw_bin + WLAN_FW_HDR_SIZE;
+	addr = le32_to_cpu(*((__le32 *)(fw_bin + WLAN_FW_HDR_DMEM_ADDR)));
+	addr &= ~BIT(31);
+	status = dlfw_to_mem_88xx(adapter, cur_fw, 0, addr, dmem_size);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	cur_fw = fw_bin + WLAN_FW_HDR_SIZE + dmem_size;
+	addr = le32_to_cpu(*((__le32 *)(fw_bin + WLAN_FW_HDR_IMEM_ADDR)));
+	addr &= ~BIT(31);
+	status = dlfw_to_mem_88xx(adapter, cur_fw, 0, addr, imem_size);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+DLFW_EMEM:
+	if (emem_size) {
+		cur_fw = fw_bin + WLAN_FW_HDR_SIZE +
+				dmem_size + imem_size;
+		addr = le32_to_cpu(*((__le32 *)(fw_bin +
+				       WLAN_FW_HDR_EMEM_ADDR)));
+		addr &= ~BIT(31);
+		status = dlfw_to_mem_88xx(adapter, cur_fw, dl_addr << 7, addr,
+					  emem_size);
+		if (status != HALMAC_RET_SUCCESS)
+			return status;
+
+		if (emem_only == 1)
+			return HALMAC_RET_SUCCESS;
+	}
+
+	update_fw_info_88xx(adapter, fw_bin);
+	init_ofld_feature_state_machine_88xx(adapter);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+chk_h2c_ver_88xx(struct halmac_adapter *adapter, u8 *fw_bin)
+{
+	u16 halmac_h2c_ver;
+	u16 fw_h2c_ver;
+
+	fw_h2c_ver = le16_to_cpu(*((__le16 *)(fw_bin +
+						  WLAN_FW_HDR_H2C_FMT_VER)));
+	halmac_h2c_ver = H2C_FORMAT_VERSION;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "halmac h2c ver = %x, fw h2c ver = %x!!\n", halmac_h2c_ver,
+		 fw_h2c_ver);
+
+	if (fw_h2c_ver != halmac_h2c_ver)
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "H2C/C2H ver is compatible!!\n");
+}
+
+static enum halmac_ret_status
+chk_fw_size_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size)
+{
+	u32 imem_size;
+	u32 dmem_size;
+	u32 emem_size = 0;
+	u32 real_size;
+
+	if (size < WLAN_FW_HDR_SIZE) {
+		pr_err("FW size error!\n");
+		return HALMAC_RET_FW_SIZE_ERR;
+	}
+
+	dmem_size =
+		le32_to_cpu(*((__le32 *)(fw_bin + WLAN_FW_HDR_DMEM_SIZE)));
+	imem_size =
+		le32_to_cpu(*((__le32 *)(fw_bin + WLAN_FW_HDR_IMEM_SIZE)));
+	if (0 != ((*(fw_bin + WLAN_FW_HDR_MEM_USAGE)) & BIT(4)))
+		emem_size =
+		le32_to_cpu(*((__le32 *)(fw_bin + WLAN_FW_HDR_EMEM_SIZE)));
+
+	dmem_size += WLAN_FW_HDR_CHKSUM_SIZE;
+	imem_size += WLAN_FW_HDR_CHKSUM_SIZE;
+	if (emem_size != 0)
+		emem_size += WLAN_FW_HDR_CHKSUM_SIZE;
+
+	real_size = WLAN_FW_HDR_SIZE + dmem_size + imem_size + emem_size;
+	if (size != real_size) {
+		pr_err("size != real size!\n");
+		return HALMAC_RET_FW_SIZE_ERR;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+wlan_cpu_en_88xx(struct halmac_adapter *adapter, u8 enable)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (enable == 1) {
+		/* cpu io interface enable or disable */
+		value8 = HALMAC_REG_R8(REG_RSV_CTRL + 1);
+		value8 |= BIT(0);
+		HALMAC_REG_W8(REG_RSV_CTRL + 1, value8);
+
+		/* cpu enable or disable */
+		value8 = HALMAC_REG_R8(REG_SYS_FUNC_EN + 1);
+		value8 |= BIT(2);
+		HALMAC_REG_W8(REG_SYS_FUNC_EN + 1, value8);
+
+	} else {
+		/* cpu enable or disable */
+		value8 = HALMAC_REG_R8(REG_SYS_FUNC_EN + 1);
+		value8 &= ~BIT(2);
+		HALMAC_REG_W8(REG_SYS_FUNC_EN + 1, value8);
+
+		/* cpu io interface enable or disable */
+		value8 = HALMAC_REG_R8(REG_RSV_CTRL + 1);
+		value8 &= ~BIT(0);
+		HALMAC_REG_W8(REG_RSV_CTRL + 1, value8);
+	}
+}
+
+static void
+pltfm_reset_88xx(struct halmac_adapter *adapter)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	value8 = HALMAC_REG_R8(REG_CPU_DMEM_CON + 2) & ~BIT(0);
+	HALMAC_REG_W8(REG_CPU_DMEM_CON + 2, value8);
+
+	/* For 8822B & 8821C clock sync issue */
+	if (adapter->chip_id == HALMAC_CHIP_ID_8821C ||
+	    adapter->chip_id == HALMAC_CHIP_ID_8822B) {
+		value8 = HALMAC_REG_R8(REG_SYS_CLK_CTRL + 1) & ~BIT(6);
+		HALMAC_REG_W8(REG_SYS_CLK_CTRL + 1, value8);
+	}
+
+	value8 = HALMAC_REG_R8(REG_CPU_DMEM_CON + 2) | BIT(0);
+	HALMAC_REG_W8(REG_CPU_DMEM_CON + 2, value8);
+
+	if (adapter->chip_id == HALMAC_CHIP_ID_8821C ||
+	    adapter->chip_id == HALMAC_CHIP_ID_8822B) {
+		value8 = HALMAC_REG_R8(REG_SYS_CLK_CTRL + 1) | BIT(6);
+		HALMAC_REG_W8(REG_SYS_CLK_CTRL + 1, value8);
+	}
+}
+
+/**
+ * free_download_firmware_88xx() - download specific memory firmware
+ * @adapter
+ * @mem_sel : memory selection
+ * @fw_bin : firmware bin
+ * @size : firmware size
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+free_download_firmware_88xx(struct halmac_adapter *adapter,
+			    enum halmac_dlfw_mem mem_sel, u8 *fw_bin, u32 size)
+{
+	u8 tx_pause_bckp;
+	u32 dl_addr;
+	u32 dlfw_size_bckp;
+	enum halmac_ret_status status;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = chk_fw_size_88xx(adapter, fw_bin, size);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	if (((*(fw_bin + WLAN_FW_HDR_MEM_USAGE)) & BIT(4)) == 0)
+		return HALMAC_RET_SUCCESS;
+
+	dlfw_size_bckp = adapter->dlfw_pkt_size;
+	if (mem_sel == HALMAC_DLFW_MEM_EMEM) {
+		dl_addr = 0;
+	} else {
+		dl_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
+		adapter->dlfw_pkt_size = (dlfw_size_bckp > DLFW_RSVDPG_SIZE) ?
+					DLFW_RSVDPG_SIZE : dlfw_size_bckp;
+	}
+
+	tx_pause_bckp = HALMAC_REG_R8(REG_TXPAUSE);
+	HALMAC_REG_W8(REG_TXPAUSE, tx_pause_bckp | BIT(7));
+
+	status = start_dlfw_88xx(adapter, fw_bin, size, dl_addr, 1);
+	if (status != HALMAC_RET_SUCCESS)
+		goto DL_FREE_FW_END;
+
+	status = free_dl_fw_end_flow_88xx(adapter);
+
+DL_FREE_FW_END:
+	HALMAC_REG_W8(REG_TXPAUSE, tx_pause_bckp);
+	adapter->dlfw_pkt_size = dlfw_size_bckp;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return status;
+}
+
+/**
+ * get_fw_version_88xx() - get FW version
+ * @adapter : the adapter of halmac
+ * @ver : fw version info
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_fw_version_88xx(struct halmac_adapter *adapter,
+		    struct halmac_fw_version *ver)
+{
+	struct halmac_fw_version *info = &adapter->fw_ver;
+
+	if (!ver)
+		return HALMAC_RET_NULL_POINTER;
+
+	if (adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE)
+		return HALMAC_RET_NO_DLFW;
+
+	ver->version = info->version;
+	ver->sub_version = info->sub_version;
+	ver->sub_index = info->sub_index;
+	ver->h2c_version = info->h2c_version;
+	ver->build_time.month = info->build_time.month;
+	ver->build_time.date = info->build_time.date;
+	ver->build_time.hour = info->build_time.hour;
+	ver->build_time.min = info->build_time.min;
+	ver->build_time.year = info->build_time.year;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+update_fw_info_88xx(struct halmac_adapter *adapter, u8 *fw_bin)
+{
+	struct halmac_fw_version *info = &adapter->fw_ver;
+
+	info->version =
+		le16_to_cpu(*((__le16 *)(fw_bin + WLAN_FW_HDR_VERSION)));
+	info->sub_version = *(fw_bin + WLAN_FW_HDR_SUBVERSION);
+	info->sub_index = *(fw_bin + WLAN_FW_HDR_SUBINDEX);
+	info->h2c_version = le16_to_cpu(*((__le16 *)(fw_bin +
+					    WLAN_FW_HDR_H2C_FMT_VER)));
+	info->build_time.month = *(fw_bin + WLAN_FW_HDR_MONTH);
+	info->build_time.date = *(fw_bin + WLAN_FW_HDR_DATE);
+	info->build_time.hour = *(fw_bin + WLAN_FW_HDR_HOUR);
+	info->build_time.min = *(fw_bin + WLAN_FW_HDR_MIN);
+	info->build_time.year =
+		le16_to_cpu(*((__le16 *)(fw_bin + WLAN_FW_HDR_YEAR)));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "=== FW info ===\n");
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "ver : %X\n",
+		 info->version);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "sub-ver : %X\n",
+		 info->sub_version);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "sub-idx : %X\n",
+		 info->sub_index);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "build : %d/%d/%d %d:%d\n", info->build_time.year,
+		 info->build_time.month, info->build_time.date,
+		 info->build_time.hour, info->build_time.min);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+dlfw_to_mem_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 src, u32 dest,
+		 u32 size)
+{
+	u8 first_part;
+	u32 mem_offset;
+	u32 residue_size;
+	u32 pkt_size;
+	enum halmac_ret_status status;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	mem_offset = 0;
+	first_part = 1;
+	residue_size = size;
+
+	HALMAC_REG_W32_SET(REG_DDMA_CH0CTRL, BIT_DDMACH0_RESET_CHKSUM_STS);
+
+	while (residue_size != 0) {
+		if (residue_size >= adapter->dlfw_pkt_size)
+			pkt_size = adapter->dlfw_pkt_size;
+		else
+			pkt_size = residue_size;
+
+		status = send_fwpkt_88xx(adapter, (u16)(src >> 7),
+					 fw_bin + mem_offset, pkt_size);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("send fw pkt!!\n");
+			return status;
+		}
+
+		status = iddma_dlfw_88xx(adapter,
+					 OCPBASE_TXBUF_88XX +
+					 src + adapter->hw_cfg_info.txdesc_size,
+					 dest + mem_offset, pkt_size,
+					 first_part);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("iddma dlfw!!\n");
+			return status;
+		}
+
+		first_part = 0;
+		mem_offset += pkt_size;
+		residue_size -= pkt_size;
+	}
+
+	status = check_fw_chksum_88xx(adapter, dest);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("chk fw chksum!!\n");
+		return status;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+restore_mac_reg_88xx(struct halmac_adapter *adapter,
+		     struct halmac_backup_info *info, u32 num)
+{
+	u8 len;
+	u32 i;
+	u32 reg;
+	u32 value;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	struct halmac_backup_info *curr_info = info;
+
+	for (i = 0; i < num; i++) {
+		reg = curr_info->mac_register;
+		value = curr_info->value;
+		len = curr_info->length;
+
+		if (len == 1)
+			HALMAC_REG_W8(reg, (u8)value);
+		else if (len == 2)
+			HALMAC_REG_W16(reg, (u16)value);
+		else if (len == 4)
+			HALMAC_REG_W32(reg, value);
+
+		curr_info++;
+	}
+}
+
+static enum halmac_ret_status
+dlfw_end_flow_88xx(struct halmac_adapter *adapter)
+{
+	u16 fw_ctrl;
+	u32 cnt;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	HALMAC_REG_W32(REG_TXDMA_STATUS, BIT(2));
+
+	/* Check IMEM & DMEM checksum is OK or not */
+	fw_ctrl = HALMAC_REG_R16(REG_MCUFW_CTRL);
+	if ((fw_ctrl & 0x50) != 0x50)
+		return HALMAC_RET_IDMEM_CHKSUM_FAIL;
+
+	HALMAC_REG_W16(REG_MCUFW_CTRL, (fw_ctrl | BIT_FW_DW_RDY) & ~BIT(0));
+
+	wlan_cpu_en_88xx(adapter, 1);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Dlfw OK, enable CPU\n");
+
+	cnt = 5000;
+	while (HALMAC_REG_R16(REG_MCUFW_CTRL) != 0xC078) {
+		if (cnt == 0) {
+			pr_err("Check 0x80 = 0xC078 fail\n");
+			if ((HALMAC_REG_R32(REG_FW_DBG7) & 0xFFFFFF00) ==
+			    ILLEGAL_KEY_GROUP) {
+				pr_err("Key!!\n");
+				return HALMAC_RET_ILLEGAL_KEY_FAIL;
+			}
+			return HALMAC_RET_FW_READY_CHK_FAIL;
+		}
+		cnt--;
+		usleep_range(50, 60);
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "0x80=0xC078, cnt=%d\n", cnt);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+free_dl_fw_end_flow_88xx(struct halmac_adapter *adapter)
+{
+	u32 cnt;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	cnt = 100;
+	while (HALMAC_REG_R8(REG_HMETFR + 3) != 0) {
+		cnt--;
+		if (cnt == 0) {
+			pr_err("0x1CF != 0\n");
+			return HALMAC_RET_DLFW_FAIL;
+		}
+		usleep_range(50, 60);
+	}
+
+	HALMAC_REG_W8(REG_HMETFR + 3, ID_INFORM_DLEMEM_RDY);
+
+	cnt = 10000;
+	while (HALMAC_REG_R8(REG_MCU_TST_CFG) != ID_CHECK_DLEMEM_RDY) {
+		cnt--;
+		if (cnt == 0) {
+			pr_err("0x84 != 0x80\n");
+			return HALMAC_RET_DLFW_FAIL;
+		}
+		usleep_range(50, 60);
+	}
+
+	HALMAC_REG_W8(REG_MCU_TST_CFG, 0);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+send_fwpkt_88xx(struct halmac_adapter *adapter, u16 pg_addr, u8 *fw_bin,
+		u32 size)
+{
+	enum halmac_ret_status status;
+
+	status = dl_rsvd_page_88xx(adapter, pg_addr, fw_bin, size);
+	if (status != HALMAC_RET_SUCCESS)
+		pr_err("dl rsvd page!!\n");
+
+	return status;
+}
+
+static enum halmac_ret_status
+iddma_dlfw_88xx(struct halmac_adapter *adapter, u32 src, u32 dest, u32 len,
+		u8 first)
+{
+	u32 cnt;
+	u32 ch0_ctrl = (u32)(BIT_DDMACH0_CHKSUM_EN | BIT_DDMACH0_OWN);
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	cnt = HALMC_DDMA_POLLING_COUNT;
+	while (HALMAC_REG_R32(REG_DDMA_CH0CTRL) & BIT_DDMACH0_OWN) {
+		cnt--;
+		if (cnt == 0) {
+			pr_err("ch0 ready!!\n");
+			return HALMAC_RET_DDMA_FAIL;
+		}
+	}
+
+	ch0_ctrl |= (len & BIT_MASK_DDMACH0_DLEN);
+	if (first == 0)
+		ch0_ctrl |= BIT_DDMACH0_CHKSUM_CONT;
+
+	if (iddma_en_88xx(adapter, src, dest, ch0_ctrl) !=
+	    HALMAC_RET_SUCCESS) {
+		pr_err("iddma en!!\n");
+		return HALMAC_RET_DDMA_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+iddma_en_88xx(struct halmac_adapter *adapter, u32 src, u32 dest, u32 ctrl)
+{
+	u32 cnt = HALMC_DDMA_POLLING_COUNT;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	HALMAC_REG_W32(REG_DDMA_CH0SA, src);
+	HALMAC_REG_W32(REG_DDMA_CH0DA, dest);
+	HALMAC_REG_W32(REG_DDMA_CH0CTRL, ctrl);
+
+	while (HALMAC_REG_R32(REG_DDMA_CH0CTRL) & BIT_DDMACH0_OWN) {
+		cnt--;
+		if (cnt == 0)
+			return HALMAC_RET_DDMA_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+check_fw_chksum_88xx(struct halmac_adapter *adapter, u32 mem_addr)
+{
+	u8 fw_ctrl;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	fw_ctrl = HALMAC_REG_R8(REG_MCUFW_CTRL);
+
+	if (HALMAC_REG_R32(REG_DDMA_CH0CTRL) & BIT_DDMACH0_CHKSUM_STS) {
+		if (mem_addr < OCPBASE_DMEM_88XX) {
+			fw_ctrl |= BIT_IMEM_DW_OK;
+			fw_ctrl &= ~BIT_IMEM_CHKSUM_OK;
+			HALMAC_REG_W8(REG_MCUFW_CTRL, fw_ctrl);
+		} else {
+			fw_ctrl |= BIT_DMEM_DW_OK;
+			fw_ctrl &= ~BIT_DMEM_CHKSUM_OK;
+			HALMAC_REG_W8(REG_MCUFW_CTRL, fw_ctrl);
+		}
+
+		pr_err("fw chksum!!\n");
+
+		return HALMAC_RET_FW_CHECKSUM_FAIL;
+	}
+
+	if (mem_addr < OCPBASE_DMEM_88XX) {
+		fw_ctrl |= (BIT_IMEM_DW_OK | BIT_IMEM_CHKSUM_OK);
+		HALMAC_REG_W8(REG_MCUFW_CTRL, fw_ctrl);
+	} else {
+		fw_ctrl |= (BIT_DMEM_DW_OK | BIT_DMEM_CHKSUM_OK);
+		HALMAC_REG_W8(REG_MCUFW_CTRL, fw_ctrl);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * check_fw_status_88xx() -check fw status
+ * @adapter : the adapter of halmac
+ * @status : fw status
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+check_fw_status_88xx(struct halmac_adapter *adapter, u8 *fw_status)
+{
+	u32 cnt;
+	u32 fw_dbg6;
+	u32 fw_pc;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	*fw_status = 1;
+
+	fw_dbg6 = HALMAC_REG_R32(REG_FW_DBG6);
+
+	if (fw_dbg6 != 0) {
+		pr_err("REG_FW_DBG6 !=0\n");
+		if ((fw_dbg6 & FW_STATUS_CHK_WARN) != 0)
+			RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+				 "fw status(warn):%X\n", fw_dbg6);
+
+		if ((fw_dbg6 & FW_STATUS_CHK_ERR) != 0)
+			pr_err("fw status(err):%X\n", fw_dbg6);
+
+		if ((fw_dbg6 & FW_STATUS_CHK_FATAL) != 0) {
+			pr_err("fw status(fatal):%X\n", fw_dbg6);
+			fw_fatal_status_debug_88xx(adapter);
+			*fw_status = 0;
+			return status;
+		}
+	}
+
+	fw_pc = HALMAC_REG_R32(REG_FW_DBG7);
+	cnt = 10;
+	while (HALMAC_REG_R32(REG_FW_DBG7) == fw_pc) {
+		cnt--;
+		if (cnt == 0)
+			break;
+	}
+
+	if (cnt == 0) {
+		cnt = 200;
+		while (HALMAC_REG_R32(REG_FW_DBG7) == fw_pc) {
+			cnt--;
+			if (cnt == 0) {
+				pr_err("fw pc\n");
+				*fw_status = 0;
+				return status;
+			}
+			usleep_range(50, 60);
+		}
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return status;
+}
+
+static void
+fw_fatal_status_debug_88xx(struct halmac_adapter *adapter)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	pr_err("0x%X = %X\n", REG_FW_DBG6, HALMAC_REG_R32(REG_FW_DBG6));
+
+	pr_err("0x%X = %X\n", REG_ARFR5, HALMAC_REG_R32(REG_ARFR5));
+
+	pr_err("0x%X = %X\n", REG_MCUTST_I, HALMAC_REG_R32(REG_MCUTST_I));
+}
+
+enum halmac_ret_status
+dump_fw_dmem_88xx(struct halmac_adapter *adapter, u8 *dmem, u32 *size)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_max_dl_size_88xx() - config max download FW size
+ * @adapter : the adapter of halmac
+ * @size : max download fw size
+ *
+ * Halmac uses this setting to set max packet size for
+ * download FW.
+ * If user has not called this API, halmac use default
+ * setting for download FW
+ * Note1 : size need multiple of 2
+ * Note2 : max size is 31K
+ *
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_max_dl_size_88xx(struct halmac_adapter *adapter, u32 size)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (size > DLFW_PKT_SIZE_LIMIT) {
+		pr_err("size > max dl size!\n");
+		return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
+	}
+
+	if ((size & (2 - 1)) != 0) {
+		pr_err("not multiple of 2!\n");
+		return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
+	}
+
+	adapter->dlfw_pkt_size = size;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Cfg max size:%X\n", size);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * enter_cpu_sleep_mode_88xx() -wlan cpu enter sleep mode
+ * @adapter : the adapter of halmac
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+enter_cpu_sleep_mode_88xx(struct halmac_adapter *adapter)
+{
+	u32 cnt;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_wlcpu_mode *cur_mode = &adapter->halmac_state.wlcpu_mode;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	if (*cur_mode != HALMAC_WLCPU_ACTIVE)
+		return HALMAC_RET_ERROR_STATE;
+
+	cnt = 100;
+	while (HALMAC_REG_R8(REG_HMETFR + 3) != 0) {
+		cnt--;
+		if (cnt == 0) {
+			pr_err("0x1CF != 0\n");
+			return HALMAC_RET_STATE_INCORRECT;
+		}
+		usleep_range(50, 60);
+	}
+
+	HALMAC_REG_W8(REG_HMETFR + 3, ID_INFORM_ENETR_CPU_SLEEP);
+
+	*cur_mode = HALMAC_WLCPU_ENTER_SLEEP;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * get_cpu_mode_88xx() -get wlcpu mode
+ * @adapter : the adapter of halmac
+ * @mode : cpu mode
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_cpu_mode_88xx(struct halmac_adapter *adapter,
+		  enum halmac_wlcpu_mode *mode)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_wlcpu_mode *cur_mode = &adapter->halmac_state.wlcpu_mode;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	if (*cur_mode == HALMAC_WLCPU_ACTIVE) {
+		*mode = HALMAC_WLCPU_ACTIVE;
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (*cur_mode == HALMAC_WLCPU_SLEEP) {
+		*mode = HALMAC_WLCPU_SLEEP;
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (HALMAC_REG_R8(REG_MCU_TST_CFG) == ID_CHECK_ENETR_CPU_SLEEP)
+		*mode = HALMAC_WLCPU_SLEEP;
+	else
+		*mode = HALMAC_WLCPU_ENTER_SLEEP;
+
+	HALMAC_REG_W8(REG_MCU_TST_CFG, 0);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * send_general_info_88xx() -send general information to FW
+ * @adapter : the adapter of halmac
+ * @info : general information
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+send_general_info_88xx(struct halmac_adapter *adapter,
+		       struct halmac_general_info *info)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	if (adapter->fw_ver.h2c_version < 4)
+		return HALMAC_RET_FW_NO_SUPPORT;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
+		pr_err("no dl fw!!\n");
+		return HALMAC_RET_NO_DLFW;
+	}
+
+	status = proc_send_general_info_88xx(adapter, info);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send gen info!!\n");
+		return status;
+	}
+
+	status = proc_send_phydm_info_88xx(adapter, info);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send phydm info\n");
+		return status;
+	}
+
+	if (adapter->halmac_state.dlfw_state == HALMAC_DLFW_DONE)
+		adapter->halmac_state.dlfw_state = HALMAC_GEN_INFO_SENT;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+proc_send_general_info_88xx(struct halmac_adapter *adapter,
+			    struct halmac_general_info *info)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s\n",
+		 __func__);
+
+	GENERAL_INFO_SET_FW_TX_BOUNDARY(h2c_buf,
+					adapter->txff_alloc.rsvd_fw_txbuf_addr -
+					adapter->txff_alloc.rsvd_boundary);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_GENERAL_INFO;
+	hdr_info.content_size = 4;
+	hdr_info.ack = 0;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS)
+		pr_err("send h2c!!\n");
+
+	return status;
+}
+
+static enum halmac_ret_status
+proc_send_phydm_info_88xx(struct halmac_adapter *adapter,
+			  struct halmac_general_info *info)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s\n",
+		 __func__);
+
+	PHYDM_INFO_SET_REF_TYPE(h2c_buf, info->rfe_type);
+	PHYDM_INFO_SET_RF_TYPE(h2c_buf, info->rf_type);
+	PHYDM_INFO_SET_CUT_VER(h2c_buf, adapter->chip_ver);
+	PHYDM_INFO_SET_RX_ANT_STATUS(h2c_buf, info->rx_ant_status);
+	PHYDM_INFO_SET_TX_ANT_STATUS(h2c_buf, info->tx_ant_status);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_PHYDM_INFO;
+	hdr_info.content_size = 8;
+	hdr_info.ack = 0;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS)
+		pr_err("send h2c!!\n");
+
+	return status;
+}
+
+/**
+ * drv_fwctrl_88xx() - send drv-defined h2c pkt
+ * @adapter : the adapter of halmac
+ * @payload : no include offload pkt h2c header
+ * @size : no include offload pkt h2c header
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+drv_fwctrl_88xx(struct halmac_adapter *adapter, u8 *payload, u32 size, u8 ack)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (!payload)
+		return HALMAC_RET_DATA_BUF_NULL;
+
+	if (size > H2C_PKT_SIZE_88XX - H2C_PKT_HDR_SIZE_88XX)
+		return HALMAC_RET_DATA_SIZE_INCORRECT;
+
+	memcpy(h2c_buf + H2C_PKT_HDR_SIZE_88XX, payload, size);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_FW_FWCTRL;
+	hdr_info.content_size = (u16)size;
+	hdr_info.ack = ack;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS)
+		pr_err("send h2c!!\n");
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return status;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.h
new file mode 100644
index 000000000000..bf8ba8b58f2d
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_fw_88xx.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_FW_88XX_H_
+#define _HALMAC_FW_88XX_H_
+
+#include "../halmac_api.h"
+
+#define HALMC_DDMA_POLLING_COUNT		1000
+
+enum halmac_ret_status
+download_firmware_88xx(struct halmac_adapter *adapter, u8 *fw_bin, u32 size);
+
+enum halmac_ret_status
+free_download_firmware_88xx(struct halmac_adapter *adapter,
+			    enum halmac_dlfw_mem mem_sel, u8 *fw_bin, u32 size);
+
+enum halmac_ret_status
+get_fw_version_88xx(struct halmac_adapter *adapter,
+		    struct halmac_fw_version *ver);
+
+enum halmac_ret_status
+check_fw_status_88xx(struct halmac_adapter *adapter, u8 *fw_status);
+
+enum halmac_ret_status
+dump_fw_dmem_88xx(struct halmac_adapter *adapter, u8 *dmem, u32 *size);
+
+enum halmac_ret_status
+cfg_max_dl_size_88xx(struct halmac_adapter *adapter, u32 size);
+
+enum halmac_ret_status
+enter_cpu_sleep_mode_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+get_cpu_mode_88xx(struct halmac_adapter *adapter,
+		  enum halmac_wlcpu_mode *mode);
+
+enum halmac_ret_status
+send_general_info_88xx(struct halmac_adapter *adapter,
+		       struct halmac_general_info *info);
+
+enum halmac_ret_status
+drv_fwctrl_88xx(struct halmac_adapter *adapter, u8 *payload, u32 size, u8 ack);
+
+#endif/* _HALMAC_FW_88XX_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_info.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_info.h
new file mode 100644
index 000000000000..1da64fba231a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_info.h
@@ -0,0 +1,119 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_FW_INFO_H_
+#define _HALMAC_FW_INFO_H_
+
+#define H2C_FORMAT_VERSION		11
+
+/* FW bin information */
+#define WLAN_FW_HDR_SIZE		64
+#define WLAN_FW_HDR_CHKSUM_SIZE		8
+
+#define WLAN_FW_HDR_VERSION		4
+#define WLAN_FW_HDR_SUBVERSION		6
+#define WLAN_FW_HDR_SUBINDEX		7
+#define WLAN_FW_HDR_MONTH		16
+#define WLAN_FW_HDR_DATE		17
+#define WLAN_FW_HDR_HOUR		18
+#define WLAN_FW_HDR_MIN			19
+#define WLAN_FW_HDR_YEAR		20
+#define WLAN_FW_HDR_MEM_USAGE		24
+#define WLAN_FW_HDR_H2C_FMT_VER		28
+#define WLAN_FW_HDR_DMEM_ADDR		32
+#define WLAN_FW_HDR_DMEM_SIZE		36
+#define WLAN_FW_HDR_IMEM_SIZE		48
+#define WLAN_FW_HDR_EMEM_SIZE		52
+#define WLAN_FW_HDR_EMEM_ADDR		56
+#define WLAN_FW_HDR_IMEM_ADDR		60
+
+#define H2C_ACK_HDR_CONTENT_LENGTH		8
+#define CFG_PARAMETER_ACK_CONTENT_LENGTH	16
+#define SCAN_STATUS_RPT_CONTENT_LENGTH		4
+#define C2H_DBG_HDR_LEN				4
+#define C2H_DBG_CONTENT_MAX_LENGTH		228
+#define C2H_DBG_CONTENT_SEQ_OFFSET		1
+
+/* Rename from FW SysHalCom_Debug_RAM.h */
+#define FW_REG_H2CPKT_DONE_SEQ		0x1C8
+#define FW_REG_WOW_REASON		0x1C7
+
+enum halmac_data_type {
+	HALMAC_DATA_TYPE_MAC_REG = 0x00,
+	HALMAC_DATA_TYPE_BB_REG = 0x01,
+	HALMAC_DATA_TYPE_RADIO_A = 0x02,
+	HALMAC_DATA_TYPE_RADIO_B = 0x03,
+	HALMAC_DATA_TYPE_RADIO_C = 0x04,
+	HALMAC_DATA_TYPE_RADIO_D = 0x05,
+
+	HALMAC_DATA_TYPE_DRV_DEFINE_0 = 0x80,
+	HALMAC_DATA_TYPE_DRV_DEFINE_1 = 0x81,
+	HALMAC_DATA_TYPE_DRV_DEFINE_2 = 0x82,
+	HALMAC_DATA_TYPE_DRV_DEFINE_3 = 0x83,
+	HALMAC_DATA_TYPE_UNDEFINE = 0x7FFFFFFF,
+};
+
+enum halmac_packet_id {
+	HALMAC_PACKET_PROBE_REQ = 0x00,
+	HALMAC_PACKET_SYNC_BCN = 0x01,
+	HALMAC_PACKET_DISCOVERY_BCN = 0x02,
+	HALMAC_PACKET_UNDEFINE = 0x7FFFFFFF,
+};
+
+enum halmac_cs_action_id {
+	HALMAC_CS_ACTION_NONE = 0x00,
+	HALMAC_CS_ACTIVE_SCAN = 0x01,
+	HALMAC_CS_NAN_NONMASTER_DW = 0x02,
+	HALMAC_CS_NAN_NONMASTER_NONDW = 0x03,
+	HALMAC_CS_NAN_MASTER_NONDW = 0x04,
+	HALMAC_CS_NAN_MASTER_DW = 0x05,
+	HALMAC_CS_ACTION_UNDEFINE = 0x7FFFFFFF,
+};
+
+enum halmac_cs_extra_action_id {
+	HALMAC_CS_EXTRA_ACTION_NONE = 0x00,
+	HALMAC_CS_EXTRA_UPDATE_PROBE = 0x01,
+	HALMAC_CS_EXTRA_UPDATE_BEACON = 0x02,
+	HALMAC_CS_EXTRA_ACTION_UNDEFINE = 0x7FFFFFFF,
+};
+
+enum halmac_h2c_return_code {
+	HALMAC_H2C_RETURN_SUCCESS = 0x00,
+	HALMAC_H2C_RETURN_CFG_ERR_LEN = 0x01,
+	HALMAC_H2C_RETURN_CFG_ERR_CMD = 0x02,
+	HALMAC_H2C_RETURN_EFUSE_ERR_DUMP = 0x03,
+	HALMAC_H2C_RETURN_DATAPACK_ERR_FULL = 0x04,
+	HALMAC_H2C_RETURN_DATAPACK_ERR_ID = 0x05,
+	HALMAC_H2C_RETURN_RUN_ERR_EMPTY = 0x06,
+	HALMAC_H2C_RETURN_RUN_ERR_LEN = 0x07,
+	HALMAC_H2C_RETURN_RUN_ERR_CMD = 0x08,
+	HALMAC_H2C_RETURN_RUN_ERR_ID = 0x09,
+	HALMAC_H2C_RETURN_PACKET_ERR_FULL = 0x0A,
+	HALMAC_H2C_RETURN_PACKET_ERR_ID = 0x0B,
+	HALMAC_H2C_RETURN_SCAN_ERR_FULL = 0x0C,
+	HALMAC_H2C_RETURN_SCAN_ERR_PHYDM = 0x0D,
+	HALMAC_H2C_RETURN_ORIG_ERR_ID = 0x0E,
+	HALMAC_H2C_RETURN_UNDEFINE = 0x7FFFFFFF,
+};
+
+enum halmac_scan_report_code {
+	HALMAC_SCAN_REPORT_DONE	= 0x00,
+	HALMAC_SCAN_REPORT_ERR_PHYDM = 0x01,
+	HALMAC_SCAN_REPORT_ERR_ID = 0x02,
+	HALMAC_SCAN_REPORT_ERR_TX = 0x03,
+	HALMAC_SCAN_REPORT_UNDEFINE = 0x7FFFFFFF,
+};
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h
new file mode 100644
index 000000000000..b87e34187283
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_c2h_nic.h
@@ -0,0 +1,371 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HAL_FWOFFLOADC2HFORMAT_H2C_C2H_NIC_H_
+#define _HAL_FWOFFLOADC2HFORMAT_H2C_C2H_NIC_H_
+#define C2H_SUB_CMD_ID_C2H_DBG 0X00
+#define C2H_SUB_CMD_ID_BT_COEX_INFO 0X02
+#define C2H_SUB_CMD_ID_SCAN_STATUS_RPT 0X03
+#define C2H_SUB_CMD_ID_H2C_ACK_HDR 0X01
+#define C2H_SUB_CMD_ID_CFG_PARAM_ACK 0X01
+#define C2H_SUB_CMD_ID_BT_COEX_ACK 0X01
+#define C2H_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK 0X01
+#define C2H_SUB_CMD_ID_UPDATE_PKT_ACK 0X01
+#define C2H_SUB_CMD_ID_UPDATE_DATAPACK_ACK 0X01
+#define C2H_SUB_CMD_ID_RUN_DATAPACK_ACK 0X01
+#define C2H_SUB_CMD_ID_CH_SWITCH_ACK 0X01
+#define C2H_SUB_CMD_ID_IQK_ACK 0X01
+#define C2H_SUB_CMD_ID_PWR_TRK_ACK 0X01
+#define C2H_SUB_CMD_ID_PSD_ACK 0X01
+#define C2H_SUB_CMD_ID_PSD_DATA 0X04
+#define C2H_SUB_CMD_ID_EFUSE_DATA 0X05
+#define C2H_SUB_CMD_ID_IQK_DATA 0X06
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_DBG 0X07
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_2_DBG 0X08
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_3_DBG 0X09
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_4_DBG 0X0A
+#define C2H_SUB_CMD_ID_FTMACKRPT_HDL_DBG 0X0B
+#define C2H_SUB_CMD_ID_FTMC2H_RPT 0X0C
+#define C2H_SUB_CMD_ID_DRVFTMC2H_RPT 0X0D
+#define C2H_SUB_CMD_ID_C2H_PKT_FTM_5_DBG 0X0E
+#define C2H_SUB_CMD_ID_CCX_RPT 0X0F
+#define C2H_SUB_CMD_ID_C2H_PKT_NAN_RPT 0X10
+#define C2H_SUB_CMD_ID_C2H_PKT_ATM_RPT 0X11
+#define C2H_SUB_CMD_ID_C2H_PKT_FTMSESSION_END 0X1C
+#define C2H_SUB_CMD_ID_C2H_PKT_DETECT_THERMAL 0X1D
+#define C2H_SUB_CMD_ID_FW_DBG_MSG 0XFF
+#define C2H_SUB_CMD_ID_FW_SNDING_ACK 0X01
+#define C2H_SUB_CMD_ID_FW_FWCTRL_RPT 0X1F
+#define C2H_SUB_CMD_ID_H2C_LOOPBACK_ACK 0X20
+#define C2H_SUB_CMD_ID_FWCMD_LOOPBACK_ACK 0X21
+#define H2C_SUB_CMD_ID_CFG_PARAM_ACK SUB_CMD_ID_CFG_PARAM
+#define H2C_SUB_CMD_ID_BT_COEX_ACK SUB_CMD_ID_BT_COEX
+#define H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK SUB_CMD_ID_DUMP_PHYSICAL_EFUSE
+#define H2C_SUB_CMD_ID_UPDATE_PKT_ACK SUB_CMD_ID_UPDATE_PKT
+#define H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK SUB_CMD_ID_UPDATE_DATAPACK
+#define H2C_SUB_CMD_ID_RUN_DATAPACK_ACK SUB_CMD_ID_RUN_DATAPACK
+#define H2C_SUB_CMD_ID_CH_SWITCH_ACK SUB_CMD_ID_CH_SWITCH
+#define H2C_SUB_CMD_ID_IQK_ACK SUB_CMD_ID_IQK
+#define H2C_SUB_CMD_ID_PWR_TRK_ACK SUB_CMD_ID_PWR_TRK
+#define H2C_SUB_CMD_ID_PSD_ACK SUB_CMD_ID_PSD
+#define H2C_SUB_CMD_ID_CCX_RPT SUB_CMD_ID_CCX_RPT
+#define H2C_SUB_CMD_ID_FW_DBG_MSG SUB_CMD_ID_FW_DBG_MSG
+#define H2C_SUB_CMD_ID_FW_SNDING_ACK SUB_CMD_ID_FW_SNDING
+#define H2C_SUB_CMD_ID_FW_FWCTRL_RPT SUB_CMD_ID_FW_FWCTRL_RPT
+#define H2C_SUB_CMD_ID_H2C_LOOPBACK_ACK SUB_CMD_ID_H2C_LOOPBACK
+#define H2C_SUB_CMD_ID_FWCMD_LOOPBACK_ACK SUB_CMD_ID_FWCMD_LOOPBACK
+#define H2C_CMD_ID_CFG_PARAM_ACK 0XFF
+#define H2C_CMD_ID_BT_COEX_ACK 0XFF
+#define H2C_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK 0XFF
+#define H2C_CMD_ID_UPDATE_PKT_ACK 0XFF
+#define H2C_CMD_ID_UPDATE_DATAPACK_ACK 0XFF
+#define H2C_CMD_ID_RUN_DATAPACK_ACK 0XFF
+#define H2C_CMD_ID_CH_SWITCH_ACK 0XFF
+#define H2C_CMD_ID_IQK_ACK 0XFF
+#define H2C_CMD_ID_PWR_TRK_ACK 0XFF
+#define H2C_CMD_ID_PSD_ACK 0XFF
+#define H2C_CMD_ID_CCX_RPT 0XFF
+#define H2C_CMD_ID_FW_DBG_MSG 0XFF
+#define H2C_CMD_ID_FW_SNDING_ACK 0XFF
+#define H2C_CMD_ID_FW_FWCTRL_RPT 0XFF
+#define H2C_CMD_ID_H2C_LOOPBACK_ACK 0XFF
+#define H2C_CMD_ID_FWCMD_LOOPBACK_ACK 0XFF
+#define C2H_HDR_GET_CMD_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_HDR_SET_CMD_ID(c2h_pkt, value)                                     \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_HDR_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_HDR_SET_SEQ(c2h_pkt, value)                                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 8)
+#define C2H_HDR_SET_C2H_SUB_CMD_ID(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 8, value)
+#define C2H_HDR_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 8)
+#define C2H_HDR_SET_LEN(c2h_pkt, value)                                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 8, value)
+#define C2H_DBG_GET_DBG_MSG(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define C2H_DBG_SET_DBG_MSG(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define BT_COEX_INFO_GET_DATA_START(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define BT_COEX_INFO_SET_DATA_START(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(c2h_pkt)                           \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define SCAN_STATUS_RPT_SET_H2C_RETURN_CODE(c2h_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define SCAN_STATUS_RPT_GET_H2C_SEQ(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 16)
+#define SCAN_STATUS_RPT_SET_H2C_SEQ(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 16, value)
+#define H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define H2C_ACK_HDR_SET_H2C_RETURN_CODE(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define H2C_ACK_HDR_GET_H2C_CMD_ID(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define H2C_ACK_HDR_SET_H2C_CMD_ID(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(c2h_pkt)                                \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 16)
+#define H2C_ACK_HDR_SET_H2C_SUB_CMD_ID(c2h_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 16, value)
+#define H2C_ACK_HDR_GET_H2C_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 0, 16)
+#define H2C_ACK_HDR_SET_H2C_SEQ(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 0, 16, value)
+#define CFG_PARAM_ACK_GET_OFFSET_ACCUMULATION(c2h_pkt)                         \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0XC, 0, 32)
+#define CFG_PARAM_ACK_SET_OFFSET_ACCUMULATION(c2h_pkt, value)                  \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0XC, 0, 32, value)
+#define CFG_PARAM_ACK_GET_VALUE_ACCUMULATION(c2h_pkt)                          \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X10, 0, 32)
+#define CFG_PARAM_ACK_SET_VALUE_ACCUMULATION(c2h_pkt, value)                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X10, 0, 32, value)
+#define BT_COEX_ACK_GET_DATA_START(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0XC, 0, 8)
+#define BT_COEX_ACK_SET_DATA_START(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0XC, 0, 8, value)
+#define PSD_DATA_GET_SEGMENT_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 7)
+#define PSD_DATA_SET_SEGMENT_ID(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 7, value)
+#define PSD_DATA_GET_END_SEGMENT(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 7, 1)
+#define PSD_DATA_SET_END_SEGMENT(c2h_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 7, 1, value)
+#define PSD_DATA_GET_SEGMENT_SIZE(c2h_pkt)                                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define PSD_DATA_SET_SEGMENT_SIZE(c2h_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define PSD_DATA_GET_TOTAL_SIZE(c2h_pkt)                                       \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 16)
+#define PSD_DATA_SET_TOTAL_SIZE(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 16, value)
+#define PSD_DATA_GET_H2C_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 0, 16)
+#define PSD_DATA_SET_H2C_SEQ(c2h_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 0, 16, value)
+#define PSD_DATA_GET_DATA_START(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 16, 8)
+#define PSD_DATA_SET_DATA_START(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 16, 8, value)
+#define EFUSE_DATA_GET_SEGMENT_ID(c2h_pkt)                                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 7)
+#define EFUSE_DATA_SET_SEGMENT_ID(c2h_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 7, value)
+#define EFUSE_DATA_GET_END_SEGMENT(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 7, 1)
+#define EFUSE_DATA_SET_END_SEGMENT(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 7, 1, value)
+#define EFUSE_DATA_GET_SEGMENT_SIZE(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define EFUSE_DATA_SET_SEGMENT_SIZE(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define EFUSE_DATA_GET_TOTAL_SIZE(c2h_pkt)                                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 16)
+#define EFUSE_DATA_SET_TOTAL_SIZE(c2h_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 16, value)
+#define EFUSE_DATA_GET_H2C_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 0, 16)
+#define EFUSE_DATA_SET_H2C_SEQ(c2h_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 0, 16, value)
+#define EFUSE_DATA_GET_DATA_START(c2h_pkt)                                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 16, 8)
+#define EFUSE_DATA_SET_DATA_START(c2h_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 16, 8, value)
+#define IQK_DATA_GET_SEGMENT_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 7)
+#define IQK_DATA_SET_SEGMENT_ID(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 7, value)
+#define IQK_DATA_GET_END_SEGMENT(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 7, 1)
+#define IQK_DATA_SET_END_SEGMENT(c2h_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 7, 1, value)
+#define IQK_DATA_GET_SEGMENT_SIZE(c2h_pkt)                                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define IQK_DATA_SET_SEGMENT_SIZE(c2h_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define IQK_DATA_GET_TOTAL_SIZE(c2h_pkt)                                       \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 16)
+#define IQK_DATA_SET_TOTAL_SIZE(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 16, value)
+#define IQK_DATA_GET_H2C_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 0, 16)
+#define IQK_DATA_SET_H2C_SEQ(c2h_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 0, 16, value)
+#define IQK_DATA_GET_DATA_START(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 16, 8)
+#define IQK_DATA_SET_DATA_START(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 16, 8, value)
+#define CCX_RPT_GET_POLLUTED(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X4, 0, 1)
+#define CCX_RPT_SET_POLLUTED(c2h_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X4, 0, 1, value)
+#define CCX_RPT_GET_RPT_SEL(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X4, 5, 3)
+#define CCX_RPT_SET_RPT_SEL(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X4, 5, 3, value)
+#define CCX_RPT_GET_QSEL(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X4, 8, 5)
+#define CCX_RPT_SET_QSEL(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X4, 8, 5, value)
+#define CCX_RPT_GET_MISSED_RPT_NUM(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X4, 13, 3)
+#define CCX_RPT_SET_MISSED_RPT_NUM(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X4, 13, 3, value)
+#define CCX_RPT_GET_MACID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X4, 16, 7)
+#define CCX_RPT_SET_MACID(c2h_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X4, 16, 7, value)
+#define CCX_RPT_GET_INITIAL_DATA_RATE(c2h_pkt)                                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X4, 24, 7)
+#define CCX_RPT_SET_INITIAL_DATA_RATE(c2h_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X4, 24, 7, value)
+#define CCX_RPT_GET_INITIAL_SGI(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X4, 31, 1)
+#define CCX_RPT_SET_INITIAL_SGI(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X4, 31, 1, value)
+#define CCX_RPT_GET_QUEUE_TIME(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 0, 16)
+#define CCX_RPT_SET_QUEUE_TIME(c2h_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 0, 16, value)
+#define CCX_RPT_GET_SW_DEFINE_BYTE0(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 16, 8)
+#define CCX_RPT_SET_SW_DEFINE_BYTE0(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 16, 8, value)
+#define CCX_RPT_GET_RTS_RETRY_COUNT(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 24, 4)
+#define CCX_RPT_SET_RTS_RETRY_COUNT(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 24, 4, value)
+#define CCX_RPT_GET_BMC(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 29, 1)
+#define CCX_RPT_SET_BMC(c2h_pkt, value)                                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 29, 1, value)
+#define CCX_RPT_GET_TX_STATE(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 30, 2)
+#define CCX_RPT_SET_TX_STATE(c2h_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 30, 2, value)
+#define CCX_RPT_GET_DATA_RETRY_COUNT(c2h_pkt)                                  \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0XC, 0, 6)
+#define CCX_RPT_SET_DATA_RETRY_COUNT(c2h_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0XC, 0, 6, value)
+#define CCX_RPT_GET_FINAL_DATA_RATE(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0XC, 8, 7)
+#define CCX_RPT_SET_FINAL_DATA_RATE(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0XC, 8, 7, value)
+#define CCX_RPT_GET_FINAL_SGI(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0XC, 15, 1)
+#define CCX_RPT_SET_FINAL_SGI(c2h_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0XC, 15, 1, value)
+#define CCX_RPT_GET_RF_CH_NUM(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0XC, 16, 10)
+#define CCX_RPT_SET_RF_CH_NUM(c2h_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0XC, 16, 10, value)
+#define CCX_RPT_GET_SC(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0XC, 26, 4)
+#define CCX_RPT_SET_SC(c2h_pkt, value)                                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0XC, 26, 4, value)
+#define CCX_RPT_GET_BW(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0XC, 30, 2)
+#define CCX_RPT_SET_BW(c2h_pkt, value)                                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0XC, 30, 2, value)
+#define FW_DBG_MSG_GET_CMD_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define FW_DBG_MSG_SET_CMD_ID(c2h_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define FW_DBG_MSG_GET_C2H_SUB_CMD_ID(c2h_pkt)                                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 8)
+#define FW_DBG_MSG_SET_C2H_SUB_CMD_ID(c2h_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 8, value)
+#define FW_DBG_MSG_GET_FULL(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 1)
+#define FW_DBG_MSG_SET_FULL(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 1, value)
+#define FW_DBG_MSG_GET_OWN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 31, 1)
+#define FW_DBG_MSG_SET_OWN(c2h_pkt, value)                                     \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 31, 1, value)
+#define FW_FWCTRL_RPT_GET_EVT_TYPE(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define FW_FWCTRL_RPT_SET_EVT_TYPE(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define FW_FWCTRL_RPT_GET_LENGTH(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define FW_FWCTRL_RPT_SET_LENGTH(c2h_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define FW_FWCTRL_RPT_GET_SEQ_NUM(c2h_pkt)                                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 8)
+#define FW_FWCTRL_RPT_SET_SEQ_NUM(c2h_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 8, value)
+#define FW_FWCTRL_RPT_GET_IS_ACK(c2h_pkt)                                      \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 1)
+#define FW_FWCTRL_RPT_SET_IS_ACK(c2h_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 1, value)
+#define FW_FWCTRL_RPT_GET_MORE_CONTENT(c2h_pkt)                                \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 25, 1)
+#define FW_FWCTRL_RPT_SET_MORE_CONTENT(c2h_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 25, 1, value)
+#define FW_FWCTRL_RPT_GET_CONTENT_IDX(c2h_pkt)                                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 26, 6)
+#define FW_FWCTRL_RPT_SET_CONTENT_IDX(c2h_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 26, 6, value)
+#define FW_FWCTRL_RPT_GET_CLASS_ID(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define FW_FWCTRL_RPT_SET_CLASS_ID(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define FW_FWCTRL_RPT_GET_CONTENT(c2h_pkt)                                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 16)
+#define FW_FWCTRL_RPT_SET_CONTENT(c2h_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 16, value)
+#define H2C_LOOPBACK_ACK_GET_H2C_BYTE_0(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define H2C_LOOPBACK_ACK_SET_H2C_BYTE_0(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define H2C_LOOPBACK_ACK_GET_H2C_BYTE_1(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define H2C_LOOPBACK_ACK_SET_H2C_BYTE_1(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define H2C_LOOPBACK_ACK_GET_H2C_BYTE_2(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 8)
+#define H2C_LOOPBACK_ACK_SET_H2C_BYTE_2(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 8, value)
+#define H2C_LOOPBACK_ACK_GET_H2C_BYTE_3(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 24, 8)
+#define H2C_LOOPBACK_ACK_SET_H2C_BYTE_3(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 24, 8, value)
+#define H2C_LOOPBACK_ACK_GET_H2C_BYTE_4(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 0, 8)
+#define H2C_LOOPBACK_ACK_SET_H2C_BYTE_4(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 0, 8, value)
+#define H2C_LOOPBACK_ACK_GET_H2C_BYTE_5(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 8, 8)
+#define H2C_LOOPBACK_ACK_SET_H2C_BYTE_5(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 8, 8, value)
+#define H2C_LOOPBACK_ACK_GET_H2C_BYTE_6(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 16, 8)
+#define H2C_LOOPBACK_ACK_SET_H2C_BYTE_6(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 16, 8, value)
+#define H2C_LOOPBACK_ACK_GET_H2C_BYTE_7(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 24, 8)
+#define H2C_LOOPBACK_ACK_SET_H2C_BYTE_7(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 24, 8, value)
+#define FWCMD_LOOPBACK_ACK_GET_H2C_BYTE_0(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define FWCMD_LOOPBACK_ACK_SET_H2C_BYTE_0(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define FWCMD_LOOPBACK_ACK_GET_H2C_BYTE_1(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define FWCMD_LOOPBACK_ACK_SET_H2C_BYTE_1(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define FWCMD_LOOPBACK_ACK_GET_H2C_BYTE_2(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 8)
+#define FWCMD_LOOPBACK_ACK_SET_H2C_BYTE_2(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 8, value)
+#define FWCMD_LOOPBACK_ACK_GET_H2C_BYTE_3(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 24, 8)
+#define FWCMD_LOOPBACK_ACK_SET_H2C_BYTE_3(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 24, 8, value)
+#define FWCMD_LOOPBACK_ACK_GET_H2C_BYTE_4(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 0, 8)
+#define FWCMD_LOOPBACK_ACK_SET_H2C_BYTE_4(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 0, 8, value)
+#define FWCMD_LOOPBACK_ACK_GET_H2C_BYTE_5(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 8, 8)
+#define FWCMD_LOOPBACK_ACK_SET_H2C_BYTE_5(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 8, 8, value)
+#define FWCMD_LOOPBACK_ACK_GET_H2C_BYTE_6(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 16, 8)
+#define FWCMD_LOOPBACK_ACK_SET_H2C_BYTE_6(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 16, 8, value)
+#define FWCMD_LOOPBACK_ACK_GET_H2C_BYTE_7(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X8, 24, 8)
+#define FWCMD_LOOPBACK_ACK_SET_H2C_BYTE_7(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X8, 24, 8, value)
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h
new file mode 100644
index 000000000000..525be7e9d72f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_fw_offload_h2c_nic.h
@@ -0,0 +1,694 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HAL_FWOFFLOADH2CFORMAT_H2C_C2H_NIC_H_
+#define _HAL_FWOFFLOADH2CFORMAT_H2C_C2H_NIC_H_
+#define CMD_ID_FW_OFFLOAD_H2C 0XFF
+#define CMD_ID_CH_SWITCH 0XFF
+#define CMD_ID_DUMP_PHYSICAL_EFUSE 0XFF
+#define CMD_ID_UPDATE_BEACON_PARSING_INFO 0XFF
+#define CMD_ID_CFG_PARAM 0XFF
+#define CMD_ID_UPDATE_DATAPACK 0XFF
+#define CMD_ID_RUN_DATAPACK 0XFF
+#define CMD_ID_DOWNLOAD_FLASH 0XFF
+#define CMD_ID_UPDATE_PKT 0XFF
+#define CMD_ID_GENERAL_INFO 0XFF
+#define CMD_ID_IQK 0XFF
+#define CMD_ID_PWR_TRK 0XFF
+#define CMD_ID_PSD 0XFF
+#define CMD_ID_P2PPS 0XFF
+#define CMD_ID_BT_COEX 0XFF
+#define CMD_ID_NAN_CTRL 0XFF
+#define CMD_ID_NAN_CHANNEL_PLAN_0 0XFF
+#define CMD_ID_NAN_CHANNEL_PLAN_1 0XFF
+#define CMD_ID_FW_ACCESS_TEST 0XFF
+#define CMD_ID_PHYDM_INFO 0XFF
+#define CMD_ID_FW_SNDING 0XFF
+#define CMD_ID_H2C_LOOPBACK 0XFF
+#define CMD_ID_FWCMD_LOOPBACK 0XFF
+#define CMD_ID_FW_FWCTRL 0XFF
+#define CATEGORY_H2C_CMD_HEADER 0X00
+#define CATEGORY_FW_OFFLOAD_H2C 0X01
+#define CATEGORY_CH_SWITCH 0X01
+#define CATEGORY_DUMP_PHYSICAL_EFUSE 0X01
+#define CATEGORY_UPDATE_BEACON_PARSING_INFO 0X01
+#define CATEGORY_CFG_PARAM 0X01
+#define CATEGORY_UPDATE_DATAPACK 0X01
+#define CATEGORY_RUN_DATAPACK 0X01
+#define CATEGORY_DOWNLOAD_FLASH 0X01
+#define CATEGORY_UPDATE_PKT 0X01
+#define CATEGORY_GENERAL_INFO 0X01
+#define CATEGORY_IQK 0X01
+#define CATEGORY_PWR_TRK 0X01
+#define CATEGORY_PSD 0X01
+#define CATEGORY_P2PPS 0X01
+#define CATEGORY_BT_COEX 0X01
+#define CATEGORY_NAN_CTRL 0X01
+#define CATEGORY_NAN_CHANNEL_PLAN_0 0X01
+#define CATEGORY_NAN_CHANNEL_PLAN_1 0X01
+#define CATEGORY_FW_ACCESS_TEST 0X01
+#define CATEGORY_PHYDM_INFO 0X01
+#define CATEGORY_FW_SNDING 0X01
+#define CATEGORY_H2C_LOOPBACK 0X01
+#define CATEGORY_FWCMD_LOOPBACK 0X01
+#define CATEGORY_FW_FWCTRL 0X01
+#define SUB_CMD_ID_CH_SWITCH 0X02
+#define SUB_CMD_ID_DUMP_PHYSICAL_EFUSE 0X03
+#define SUB_CMD_ID_UPDATE_BEACON_PARSING_INFO 0X05
+#define SUB_CMD_ID_CFG_PARAM 0X08
+#define SUB_CMD_ID_UPDATE_DATAPACK 0X09
+#define SUB_CMD_ID_RUN_DATAPACK 0X0A
+#define SUB_CMD_ID_DOWNLOAD_FLASH 0X0B
+#define SUB_CMD_ID_UPDATE_PKT 0X0C
+#define SUB_CMD_ID_GENERAL_INFO 0X0D
+#define SUB_CMD_ID_IQK 0X0E
+#define SUB_CMD_ID_PWR_TRK 0X0F
+#define SUB_CMD_ID_PSD 0X10
+#define SUB_CMD_ID_P2PPS 0X24
+#define SUB_CMD_ID_BT_COEX 0X60
+#define SUB_CMD_ID_NAN_CTRL 0XB2
+#define SUB_CMD_ID_NAN_CHANNEL_PLAN_0 0XB4
+#define SUB_CMD_ID_NAN_CHANNEL_PLAN_1 0XB5
+#define SUB_CMD_ID_FW_ACCESS_TEST 0X00
+#define SUB_CMD_ID_PHYDM_INFO 0X11
+#define SUB_CMD_ID_FW_SNDING 0X12
+#define SUB_CMD_ID_FW_FWCTRL 0X13
+#define SUB_CMD_ID_H2C_LOOPBACK 0X14
+#define SUB_CMD_ID_FWCMD_LOOPBACK 0X15
+#define H2C_CMD_HEADER_GET_CATEGORY(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 7)
+#define H2C_CMD_HEADER_SET_CATEGORY(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 7, value)
+#define H2C_CMD_HEADER_GET_ACK(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 7, 1)
+#define H2C_CMD_HEADER_SET_ACK(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 7, 1, value)
+#define H2C_CMD_HEADER_GET_TOTAL_LEN(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 16)
+#define H2C_CMD_HEADER_SET_TOTAL_LEN(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 16, value)
+#define H2C_CMD_HEADER_GET_SEQ_NUM(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 16)
+#define H2C_CMD_HEADER_SET_SEQ_NUM(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 16, value)
+#define FW_OFFLOAD_H2C_GET_CATEGORY(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 7)
+#define FW_OFFLOAD_H2C_SET_CATEGORY(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 7, value)
+#define FW_OFFLOAD_H2C_GET_ACK(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 7, 1)
+#define FW_OFFLOAD_H2C_SET_ACK(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 7, 1, value)
+#define FW_OFFLOAD_H2C_GET_CMD_ID(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define FW_OFFLOAD_H2C_SET_CMD_ID(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define FW_OFFLOAD_H2C_GET_SUB_CMD_ID(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 16)
+#define FW_OFFLOAD_H2C_SET_SUB_CMD_ID(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 16, value)
+#define FW_OFFLOAD_H2C_GET_TOTAL_LEN(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 16)
+#define FW_OFFLOAD_H2C_SET_TOTAL_LEN(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 16, value)
+#define FW_OFFLOAD_H2C_GET_SEQ_NUM(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 16)
+#define FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 16, value)
+#define CH_SWITCH_GET_START(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 1)
+#define CH_SWITCH_SET_START(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 1, value)
+#define CH_SWITCH_GET_DEST_CH_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 1, 1)
+#define CH_SWITCH_SET_DEST_CH_EN(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 1, 1, value)
+#define CH_SWITCH_GET_ABSOLUTE_TIME(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 2, 1)
+#define CH_SWITCH_SET_ABSOLUTE_TIME(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 2, 1, value)
+#define CH_SWITCH_GET_PERIODIC_OPT(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 3, 2)
+#define CH_SWITCH_SET_PERIODIC_OPT(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 3, 2, value)
+#define CH_SWITCH_GET_INFO_LOC(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 8)
+#define CH_SWITCH_SET_INFO_LOC(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 8, value)
+#define CH_SWITCH_GET_CH_NUM(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define CH_SWITCH_SET_CH_NUM(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define CH_SWITCH_GET_PRI_CH_IDX(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 4)
+#define CH_SWITCH_SET_PRI_CH_IDX(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 4, value)
+#define CH_SWITCH_GET_DEST_BW(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 28, 4)
+#define CH_SWITCH_SET_DEST_BW(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 28, 4, value)
+#define CH_SWITCH_GET_DEST_CH(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 8)
+#define CH_SWITCH_SET_DEST_CH(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 8, value)
+#define CH_SWITCH_GET_NORMAL_PERIOD(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 8, 6)
+#define CH_SWITCH_SET_NORMAL_PERIOD(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 8, 6, value)
+#define CH_SWITCH_GET_NORMAL_PERIOD_SEL(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 14, 2)
+#define CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 14, 2, value)
+#define CH_SWITCH_GET_SLOW_PERIOD(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 16, 6)
+#define CH_SWITCH_SET_SLOW_PERIOD(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 16, 6, value)
+#define CH_SWITCH_GET_SLOW_PERIOD_SEL(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 22, 2)
+#define CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 22, 2, value)
+#define CH_SWITCH_GET_NORMAL_CYCLE(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 24, 8)
+#define CH_SWITCH_SET_NORMAL_CYCLE(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 24, 8, value)
+#define CH_SWITCH_GET_TSF_HIGH(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 0, 32)
+#define CH_SWITCH_SET_TSF_HIGH(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 0, 32, value)
+#define CH_SWITCH_GET_TSF_LOW(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 0, 32)
+#define CH_SWITCH_SET_TSF_LOW(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 0, 32, value)
+#define CH_SWITCH_GET_INFO_SIZE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 0, 16)
+#define CH_SWITCH_SET_INFO_SIZE(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 0, 16, value)
+#define UPDATE_BEACON_PARSING_INFO_GET_FUNC_EN(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 1)
+#define UPDATE_BEACON_PARSING_INFO_SET_FUNC_EN(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 1, value)
+#define UPDATE_BEACON_PARSING_INFO_GET_SIZE_TH(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 4)
+#define UPDATE_BEACON_PARSING_INFO_SET_SIZE_TH(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 4, value)
+#define UPDATE_BEACON_PARSING_INFO_GET_TIMEOUT(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 12, 4)
+#define UPDATE_BEACON_PARSING_INFO_SET_TIMEOUT(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 12, 4, value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_0(h2c_pkt)                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_0(h2c_pkt, value)             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 32, value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_1(h2c_pkt)                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_1(h2c_pkt, value)             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 0, 32, value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_2(h2c_pkt)                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_2(h2c_pkt, value)             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 0, 32, value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_3(h2c_pkt)                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_3(h2c_pkt, value)             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 0, 32, value)
+#define UPDATE_BEACON_PARSING_INFO_GET_IE_ID_BMP_4(h2c_pkt)                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X1C, 0, 32)
+#define UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_4(h2c_pkt, value)             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X1C, 0, 32, value)
+#define CFG_PARAM_GET_NUM(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 16)
+#define CFG_PARAM_SET_NUM(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 16, value)
+#define CFG_PARAM_GET_INIT_CASE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 1)
+#define CFG_PARAM_SET_INIT_CASE(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 1, value)
+#define CFG_PARAM_GET_LOC(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 8)
+#define CFG_PARAM_SET_LOC(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 8, value)
+#define UPDATE_DATAPACK_GET_SIZE(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 16)
+#define UPDATE_DATAPACK_SET_SIZE(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 16, value)
+#define UPDATE_DATAPACK_GET_DATAPACK_ID(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define UPDATE_DATAPACK_SET_DATAPACK_ID(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define UPDATE_DATAPACK_GET_DATAPACK_LOC(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 8)
+#define UPDATE_DATAPACK_SET_DATAPACK_LOC(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 8, value)
+#define UPDATE_DATAPACK_GET_DATAPACK_SEGMENT(h2c_pkt)                          \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 8)
+#define UPDATE_DATAPACK_SET_DATAPACK_SEGMENT(h2c_pkt, value)                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 8, value)
+#define UPDATE_DATAPACK_GET_END_SEGMENT(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 8, 1)
+#define UPDATE_DATAPACK_SET_END_SEGMENT(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 8, 1, value)
+#define RUN_DATAPACK_GET_DATAPACK_ID(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 8)
+#define RUN_DATAPACK_SET_DATAPACK_ID(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 8, value)
+#define DOWNLOAD_FLASH_GET_SPI_CMD(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 8)
+#define DOWNLOAD_FLASH_SET_SPI_CMD(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 8, value)
+#define DOWNLOAD_FLASH_GET_LOCATION(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 16)
+#define DOWNLOAD_FLASH_SET_LOCATION(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 16, value)
+#define DOWNLOAD_FLASH_GET_SIZE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 32)
+#define DOWNLOAD_FLASH_SET_SIZE(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 32, value)
+#define DOWNLOAD_FLASH_GET_START_ADDR(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 0, 32)
+#define DOWNLOAD_FLASH_SET_START_ADDR(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 0, 32, value)
+#define UPDATE_PKT_GET_SIZE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 16)
+#define UPDATE_PKT_SET_SIZE(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 16, value)
+#define UPDATE_PKT_GET_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define UPDATE_PKT_SET_ID(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define UPDATE_PKT_GET_LOC(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 8)
+#define UPDATE_PKT_SET_LOC(h2c_pkt, value)                                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 8, value)
+#define GENERAL_INFO_GET_FW_TX_BOUNDARY(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define GENERAL_INFO_SET_FW_TX_BOUNDARY(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define IQK_GET_CLEAR(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 1)
+#define IQK_SET_CLEAR(h2c_pkt, value)                                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 1, value)
+#define IQK_GET_SEGMENT_IQK(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 1, 1)
+#define IQK_SET_SEGMENT_IQK(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 1, 1, value)
+#define PWR_TRK_GET_ENABLE_A(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 1)
+#define PWR_TRK_SET_ENABLE_A(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 1, value)
+#define PWR_TRK_GET_ENABLE_B(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 1, 1)
+#define PWR_TRK_SET_ENABLE_B(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 1, 1, value)
+#define PWR_TRK_GET_ENABLE_C(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 2, 1)
+#define PWR_TRK_SET_ENABLE_C(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 2, 1, value)
+#define PWR_TRK_GET_ENABLE_D(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 3, 1)
+#define PWR_TRK_SET_ENABLE_D(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 3, 1, value)
+#define PWR_TRK_GET_TYPE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 4, 3)
+#define PWR_TRK_SET_TYPE(h2c_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 4, 3, value)
+#define PWR_TRK_GET_BBSWING_INDEX(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 8)
+#define PWR_TRK_SET_BBSWING_INDEX(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 8, value)
+#define PWR_TRK_GET_TX_PWR_INDEX_A(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 8)
+#define PWR_TRK_SET_TX_PWR_INDEX_A(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 8, value)
+#define PWR_TRK_GET_OFFSET_VALUE_A(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 8, 8)
+#define PWR_TRK_SET_OFFSET_VALUE_A(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 8, 8, value)
+#define PWR_TRK_GET_TSSI_VALUE_A(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 16, 8)
+#define PWR_TRK_SET_TSSI_VALUE_A(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 16, 8, value)
+#define PWR_TRK_GET_TX_PWR_INDEX_B(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 0, 8)
+#define PWR_TRK_SET_TX_PWR_INDEX_B(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 0, 8, value)
+#define PWR_TRK_GET_OFFSET_VALUE_B(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 8, 8)
+#define PWR_TRK_SET_OFFSET_VALUE_B(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 8, 8, value)
+#define PWR_TRK_GET_TSSI_VALUE_B(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 16, 8)
+#define PWR_TRK_SET_TSSI_VALUE_B(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 16, 8, value)
+#define PWR_TRK_GET_TX_PWR_INDEX_C(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 0, 8)
+#define PWR_TRK_SET_TX_PWR_INDEX_C(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 0, 8, value)
+#define PWR_TRK_GET_OFFSET_VALUE_C(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 8, 8)
+#define PWR_TRK_SET_OFFSET_VALUE_C(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 8, 8, value)
+#define PWR_TRK_GET_TSSI_VALUE_C(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 16, 8)
+#define PWR_TRK_SET_TSSI_VALUE_C(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 16, 8, value)
+#define PWR_TRK_GET_TX_PWR_INDEX_D(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 0, 8)
+#define PWR_TRK_SET_TX_PWR_INDEX_D(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 0, 8, value)
+#define PWR_TRK_GET_OFFSET_VALUE_D(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 8, 8)
+#define PWR_TRK_SET_OFFSET_VALUE_D(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 8, 8, value)
+#define PWR_TRK_GET_TSSI_VALUE_D(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 16, 8)
+#define PWR_TRK_SET_TSSI_VALUE_D(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 16, 8, value)
+#define PSD_GET_START_PSD(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 16)
+#define PSD_SET_START_PSD(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 16, value)
+#define PSD_GET_END_PSD(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 16)
+#define PSD_SET_END_PSD(h2c_pkt, value)                                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 16, value)
+#define P2PPS_GET_OFFLOAD_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 1)
+#define P2PPS_SET_OFFLOAD_EN(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 1, value)
+#define P2PPS_GET_ROLE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 1, 1)
+#define P2PPS_SET_ROLE(h2c_pkt, value)                                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 1, 1, value)
+#define P2PPS_GET_CTWINDOW_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 2, 1)
+#define P2PPS_SET_CTWINDOW_EN(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 2, 1, value)
+#define P2PPS_GET_NOA_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 3, 1)
+#define P2PPS_SET_NOA_EN(h2c_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 3, 1, value)
+#define P2PPS_GET_NOA_SEL(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 4, 1)
+#define P2PPS_SET_NOA_SEL(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 4, 1, value)
+#define P2PPS_GET_ALLSTASLEEP(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 5, 1)
+#define P2PPS_SET_ALLSTASLEEP(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 5, 1, value)
+#define P2PPS_GET_DISCOVERY(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 6, 1)
+#define P2PPS_SET_DISCOVERY(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 6, 1, value)
+#define P2PPS_GET_DISABLE_CLOSERF(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 7, 1)
+#define P2PPS_SET_DISABLE_CLOSERF(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 7, 1, value)
+#define P2PPS_GET_P2P_PORT_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 8)
+#define P2PPS_SET_P2P_PORT_ID(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 8, value)
+#define P2PPS_GET_P2P_GROUP(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define P2PPS_SET_P2P_GROUP(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define P2PPS_GET_P2P_MACID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 8)
+#define P2PPS_SET_P2P_MACID(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 8, value)
+#define P2PPS_GET_CTWINDOW_LENGTH(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 8)
+#define P2PPS_SET_CTWINDOW_LENGTH(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 8, value)
+#define P2PPS_GET_NOA_DURATION_PARA(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 0, 32)
+#define P2PPS_SET_NOA_DURATION_PARA(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 0, 32, value)
+#define P2PPS_GET_NOA_INTERVAL_PARA(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 0, 32)
+#define P2PPS_SET_NOA_INTERVAL_PARA(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 0, 32, value)
+#define P2PPS_GET_NOA_START_TIME_PARA(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 0, 32)
+#define P2PPS_SET_NOA_START_TIME_PARA(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 0, 32, value)
+#define P2PPS_GET_NOA_COUNT_PARA(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X1C, 0, 32)
+#define P2PPS_SET_NOA_COUNT_PARA(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X1C, 0, 32, value)
+#define BT_COEX_GET_DATA_START(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 8)
+#define BT_COEX_SET_DATA_START(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 8, value)
+#define NAN_CTRL_GET_NAN_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 2)
+#define NAN_CTRL_SET_NAN_EN(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 2, value)
+#define NAN_CTRL_GET_WARMUP_TIMER_FLAG(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 2, 1)
+#define NAN_CTRL_SET_WARMUP_TIMER_FLAG(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 2, 1, value)
+#define NAN_CTRL_GET_SUPPORT_BAND(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 2)
+#define NAN_CTRL_SET_SUPPORT_BAND(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 2, value)
+#define NAN_CTRL_GET_DISABLE_2G_DISC_BCN(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 10, 1)
+#define NAN_CTRL_SET_DISABLE_2G_DISC_BCN(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 10, 1, value)
+#define NAN_CTRL_GET_DISABLE_5G_DISC_BCN(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 11, 1)
+#define NAN_CTRL_SET_DISABLE_5G_DISC_BCN(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 11, 1, value)
+#define NAN_CTRL_GET_BCN_RSVD_PAGE_OFFSET(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define NAN_CTRL_SET_BCN_RSVD_PAGE_OFFSET(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define NAN_CTRL_GET_CHANNEL_2G(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 8)
+#define NAN_CTRL_SET_CHANNEL_2G(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 8, value)
+#define NAN_CTRL_GET_CHANNEL_5G(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 8)
+#define NAN_CTRL_SET_CHANNEL_5G(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 8, value)
+#define NAN_CTRL_GET_MASTERPREFERENCE_VALUE(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 8, 8)
+#define NAN_CTRL_SET_MASTERPREFERENCE_VALUE(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 8, 8, value)
+#define NAN_CTRL_GET_RANDOMFACTOR_VALUE(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 16, 8)
+#define NAN_CTRL_SET_RANDOMFACTOR_VALUE(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 16, 8, value)
+#define NAN_CHANNEL_PLAN_0_GET_CHANNEL_NUMBER_0(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 8)
+#define NAN_CHANNEL_PLAN_0_SET_CHANNEL_NUMBER_0(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 8, value)
+#define NAN_CHANNEL_PLAN_0_GET_UNPAUSE_MACID_0(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 8)
+#define NAN_CHANNEL_PLAN_0_SET_UNPAUSE_MACID_0(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 8, value)
+#define NAN_CHANNEL_PLAN_0_GET_START_TIME_SLOT_0(h2c_pkt)                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 16)
+#define NAN_CHANNEL_PLAN_0_SET_START_TIME_SLOT_0(h2c_pkt, value)               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 16, value)
+#define NAN_CHANNEL_PLAN_0_GET_DURATION_0(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 16, 16)
+#define NAN_CHANNEL_PLAN_0_SET_DURATION_0(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 16, 16, value)
+#define NAN_CHANNEL_PLAN_0_GET_CHANNEL_NUMBER_1(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 0, 8)
+#define NAN_CHANNEL_PLAN_0_SET_CHANNEL_NUMBER_1(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 0, 8, value)
+#define NAN_CHANNEL_PLAN_0_GET_UNPAUSE_MACID_1(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 8, 8)
+#define NAN_CHANNEL_PLAN_0_SET_UNPAUSE_MACID_1(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 8, 8, value)
+#define NAN_CHANNEL_PLAN_0_GET_START_TIME_SLOT_1(h2c_pkt)                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 0, 16)
+#define NAN_CHANNEL_PLAN_0_SET_START_TIME_SLOT_1(h2c_pkt, value)               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 0, 16, value)
+#define NAN_CHANNEL_PLAN_0_GET_DURATION_1(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 16, 16)
+#define NAN_CHANNEL_PLAN_0_SET_DURATION_1(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 16, 16, value)
+#define NAN_CHANNEL_PLAN_0_GET_CHANNEL_NUMBER_2(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 0, 8)
+#define NAN_CHANNEL_PLAN_0_SET_CHANNEL_NUMBER_2(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 0, 8, value)
+#define NAN_CHANNEL_PLAN_0_GET_UNPAUSE_MACID_2(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 8, 8)
+#define NAN_CHANNEL_PLAN_0_SET_UNPAUSE_MACID_2(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 8, 8, value)
+#define NAN_CHANNEL_PLAN_0_GET_START_TIME_SLOT_2(h2c_pkt)                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X1C, 0, 16)
+#define NAN_CHANNEL_PLAN_0_SET_START_TIME_SLOT_2(h2c_pkt, value)               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X1C, 0, 16, value)
+#define NAN_CHANNEL_PLAN_0_GET_DURATION_2(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X1C, 16, 16)
+#define NAN_CHANNEL_PLAN_0_SET_DURATION_2(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X1C, 16, 16, value)
+#define NAN_CHANNEL_PLAN_1_GET_CHANNEL_NUMBER_3(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 8)
+#define NAN_CHANNEL_PLAN_1_SET_CHANNEL_NUMBER_3(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 8, value)
+#define NAN_CHANNEL_PLAN_1_GET_UNPAUSE_MACID_3(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 8)
+#define NAN_CHANNEL_PLAN_1_SET_UNPAUSE_MACID_3(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 8, value)
+#define NAN_CHANNEL_PLAN_1_GET_START_TIME_SLOT_3(h2c_pkt)                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 16)
+#define NAN_CHANNEL_PLAN_1_SET_START_TIME_SLOT_3(h2c_pkt, value)               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 16, value)
+#define NAN_CHANNEL_PLAN_1_GET_DURATION_3(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 16, 16)
+#define NAN_CHANNEL_PLAN_1_SET_DURATION_3(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 16, 16, value)
+#define NAN_CHANNEL_PLAN_1_GET_CHANNEL_NUMBER_4(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 0, 8)
+#define NAN_CHANNEL_PLAN_1_SET_CHANNEL_NUMBER_4(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 0, 8, value)
+#define NAN_CHANNEL_PLAN_1_GET_UNPAUSE_MACID_4(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X10, 8, 8)
+#define NAN_CHANNEL_PLAN_1_SET_UNPAUSE_MACID_4(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X10, 8, 8, value)
+#define NAN_CHANNEL_PLAN_1_GET_START_TIME_SLOT_4(h2c_pkt)                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 0, 16)
+#define NAN_CHANNEL_PLAN_1_SET_START_TIME_SLOT_4(h2c_pkt, value)               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 0, 16, value)
+#define NAN_CHANNEL_PLAN_1_GET_DURATION_4(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X14, 16, 16)
+#define NAN_CHANNEL_PLAN_1_SET_DURATION_4(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X14, 16, 16, value)
+#define NAN_CHANNEL_PLAN_1_GET_CHANNEL_NUMBER_5(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 0, 8)
+#define NAN_CHANNEL_PLAN_1_SET_CHANNEL_NUMBER_5(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 0, 8, value)
+#define NAN_CHANNEL_PLAN_1_GET_UNPAUSE_MACID_5(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X18, 8, 8)
+#define NAN_CHANNEL_PLAN_1_SET_UNPAUSE_MACID_5(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X18, 8, 8, value)
+#define NAN_CHANNEL_PLAN_1_GET_START_TIME_SLOT_5(h2c_pkt)                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X1C, 0, 16)
+#define NAN_CHANNEL_PLAN_1_SET_START_TIME_SLOT_5(h2c_pkt, value)               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X1C, 0, 16, value)
+#define NAN_CHANNEL_PLAN_1_GET_DURATION_5(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X1C, 16, 16)
+#define NAN_CHANNEL_PLAN_1_SET_DURATION_5(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X1C, 16, 16, value)
+#define FW_ACCESS_TEST_GET_ACCESS_TXFF(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_TXFF(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_RXFF(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 1, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_RXFF(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 1, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_FWFF(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 2, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_FWFF(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 2, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PHYFF(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 3, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PHYFF(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 3, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_RPT_BUF(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 4, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_RPT_BUF(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 4, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_CAM(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 5, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_CAM(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 5, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_WOW_CAM(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 6, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_WOW_CAM(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 6, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_RX_CAM(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 7, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_RX_CAM(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 7, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_BA_CAM(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_BA_CAM(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_MBSSID_CAM(h2c_pkt)                          \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 9, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_MBSSID_CAM(h2c_pkt, value)                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 9, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PAGE0(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PAGE0(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PAGE1(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 17, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PAGE1(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 17, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PAGE2(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 18, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PAGE2(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 18, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PAGE3(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 19, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PAGE3(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 19, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PAGE4(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 20, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PAGE4(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 20, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PAGE5(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 21, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PAGE5(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 21, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PAGE6(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 22, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PAGE6(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 22, 1, value)
+#define FW_ACCESS_TEST_GET_ACCESS_PAGE7(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 23, 1)
+#define FW_ACCESS_TEST_SET_ACCESS_PAGE7(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 23, 1, value)
+#define PHYDM_INFO_GET_REF_TYPE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 8)
+#define PHYDM_INFO_SET_REF_TYPE(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 8, value)
+#define PHYDM_INFO_GET_RF_TYPE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 8)
+#define PHYDM_INFO_SET_RF_TYPE(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 8, value)
+#define PHYDM_INFO_GET_CUT_VER(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define PHYDM_INFO_SET_CUT_VER(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define PHYDM_INFO_GET_RX_ANT_STATUS(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 4)
+#define PHYDM_INFO_SET_RX_ANT_STATUS(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 4, value)
+#define PHYDM_INFO_GET_TX_ANT_STATUS(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 28, 4)
+#define PHYDM_INFO_SET_TX_ANT_STATUS(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 28, 4, value)
+#define FW_SNDING_GET_SU0(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 1)
+#define FW_SNDING_SET_SU0(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 1, value)
+#define FW_SNDING_GET_SU1(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 1, 1)
+#define FW_SNDING_SET_SU1(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 1, 1, value)
+#define FW_SNDING_GET_MU(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 2, 1)
+#define FW_SNDING_SET_MU(h2c_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 2, 1, value)
+#define FW_SNDING_GET_PERIOD(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 8)
+#define FW_SNDING_SET_PERIOD(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 8, value)
+#define FW_SNDING_GET_NDPA0_HEAD_PG(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define FW_SNDING_SET_NDPA0_HEAD_PG(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define FW_SNDING_GET_NDPA1_HEAD_PG(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 8)
+#define FW_SNDING_SET_NDPA1_HEAD_PG(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 8, value)
+#define FW_SNDING_GET_MU_NDPA_HEAD_PG(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0XC, 0, 8)
+#define FW_SNDING_SET_MU_NDPA_HEAD_PG(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0XC, 0, 8, value)
+#define FW_SNDING_GET_RPT0_HEAD_PG(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0XC, 8, 8)
+#define FW_SNDING_SET_RPT0_HEAD_PG(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0XC, 8, 8, value)
+#define FW_SNDING_GET_RPT1_HEAD_PG(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0XC, 16, 8)
+#define FW_SNDING_SET_RPT1_HEAD_PG(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0XC, 16, 8, value)
+#define FW_SNDING_GET_RPT2_HEAD_PG(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0XC, 24, 8)
+#define FW_SNDING_SET_RPT2_HEAD_PG(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0XC, 24, 8, value)
+#define FW_FWCTRL_GET_SEQ_NUM(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 0, 8)
+#define FW_FWCTRL_SET_SEQ_NUM(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 0, 8, value)
+#define FW_FWCTRL_GET_MORE_CONTENT(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 8, 1)
+#define FW_FWCTRL_SET_MORE_CONTENT(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 8, 1, value)
+#define FW_FWCTRL_GET_CONTENT_IDX(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 9, 7)
+#define FW_FWCTRL_SET_CONTENT_IDX(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 9, 7, value)
+#define FW_FWCTRL_GET_CLASS_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 16, 8)
+#define FW_FWCTRL_SET_CLASS_ID(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 16, 8, value)
+#define FW_FWCTRL_GET_LENGTH(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X08, 24, 8)
+#define FW_FWCTRL_SET_LENGTH(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X08, 24, 8, value)
+#define FW_FWCTRL_GET_CONTENT(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X0C, 0, 32)
+#define FW_FWCTRL_SET_CONTENT(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X0C, 0, 32, value)
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_h2c_extra_info_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_h2c_extra_info_nic.h
new file mode 100644
index 000000000000..d48a683485ea
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_h2c_extra_info_nic.h
@@ -0,0 +1,171 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HAL_H2CEXTRAINFO_H2C_C2H_NIC_H_
+#define _HAL_H2CEXTRAINFO_H2C_C2H_NIC_H_
+
+/* H2C extra info (rsvd page) usage, unit : page (128byte)*/
+/* dlfw : not include txdesc size*/
+/* update pkt : not include txdesc size*/
+/* cfg param : not include txdesc size*/
+/* scan info : not include txdesc size*/
+/* dl flash : not include txdesc size*/
+#define DLFW_RSVDPG_SIZE 2048
+#define UPDATE_PKT_RSVDPG_SIZE 2048
+#define CFG_PARAM_RSVDPG_SIZE 2048
+#define SCAN_INFO_RSVDPG_SIZE 256
+#define DL_FLASH_RSVDPG_SIZE 2048
+/* su0 snding pkt : include txdesc size */
+#define SU0_SNDING_PKT_OFFSET 0
+#define SU0_SNDING_PKT_RSVDPG_SIZE 128
+
+#define PARAM_INFO_GET_LEN(extra_info) LE_BITS_TO_4BYTE(extra_info + 0X00, 0, 8)
+#define PARAM_INFO_SET_LEN(extra_info, value)                                  \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 0, 8, value)
+#define PARAM_INFO_GET_IO_CMD(extra_info)                                      \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 8, 7)
+#define PARAM_INFO_SET_IO_CMD(extra_info, value)                               \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 8, 7, value)
+#define PARAM_INFO_GET_MSK_EN(extra_info)                                      \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 15, 1)
+#define PARAM_INFO_SET_MSK_EN(extra_info, value)                               \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 15, 1, value)
+#define PARAM_INFO_GET_LLT_PG_BNDY(extra_info)                                 \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 8)
+#define PARAM_INFO_SET_LLT_PG_BNDY(extra_info, value)                          \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 8, value)
+#define PARAM_INFO_GET_EFUSE_RSVDPAGE_LOC(extra_info)                          \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 8)
+#define PARAM_INFO_SET_EFUSE_RSVDPAGE_LOC(extra_info, value)                   \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 8, value)
+#define PARAM_INFO_GET_EFUSE_PATCH_EN(extra_info)                              \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 8)
+#define PARAM_INFO_SET_EFUSE_PATCH_EN(extra_info, value)                       \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 8, value)
+#define PARAM_INFO_GET_RF_ADDR(extra_info)                                     \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 8)
+#define PARAM_INFO_SET_RF_ADDR(extra_info, value)                              \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 8, value)
+#define PARAM_INFO_GET_IO_ADDR(extra_info)                                     \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 16)
+#define PARAM_INFO_SET_IO_ADDR(extra_info, value)                              \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 16, value)
+#define PARAM_INFO_GET_DELAY_VAL(extra_info)                                   \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 16)
+#define PARAM_INFO_SET_DELAY_VAL(extra_info, value)                            \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 16, value)
+#define PARAM_INFO_GET_RF_PATH(extra_info)                                     \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 24, 8)
+#define PARAM_INFO_SET_RF_PATH(extra_info, value)                              \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 24, 8, value)
+#define PARAM_INFO_GET_DATA(extra_info)                                        \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 0, 32)
+#define PARAM_INFO_SET_DATA(extra_info, value)                                 \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 0, 32, value)
+#define PARAM_INFO_GET_MASK(extra_info)                                        \
+	LE_BITS_TO_4BYTE(extra_info + 0X08, 0, 32)
+#define PARAM_INFO_SET_MASK(extra_info, value)                                 \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X08, 0, 32, value)
+#define CH_INFO_GET_CH(extra_info) LE_BITS_TO_4BYTE(extra_info + 0X00, 0, 8)
+#define CH_INFO_SET_CH(extra_info, value)                                      \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 0, 8, value)
+#define CH_INFO_GET_PRI_CH_IDX(extra_info)                                     \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 8, 4)
+#define CH_INFO_SET_PRI_CH_IDX(extra_info, value)                              \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 8, 4, value)
+#define CH_INFO_GET_BW(extra_info) LE_BITS_TO_4BYTE(extra_info + 0X00, 12, 4)
+#define CH_INFO_SET_BW(extra_info, value)                                      \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 12, 4, value)
+#define CH_INFO_GET_TIMEOUT(extra_info)                                        \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 8)
+#define CH_INFO_SET_TIMEOUT(extra_info, value)                                 \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 8, value)
+#define CH_INFO_GET_ACTION_ID(extra_info)                                      \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 24, 7)
+#define CH_INFO_SET_ACTION_ID(extra_info, value)                               \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 24, 7, value)
+#define CH_INFO_GET_EXTRA_INFO(extra_info)                                     \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 31, 1)
+#define CH_INFO_SET_EXTRA_INFO(extra_info, value)                              \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 31, 1, value)
+#define CH_EXTRA_INFO_GET_ID(extra_info)                                       \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 0, 7)
+#define CH_EXTRA_INFO_SET_ID(extra_info, value)                                \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 0, 7, value)
+#define CH_EXTRA_INFO_GET_INFO(extra_info)                                     \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 7, 1)
+#define CH_EXTRA_INFO_SET_INFO(extra_info, value)                              \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 7, 1, value)
+#define CH_EXTRA_INFO_GET_SIZE(extra_info)                                     \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 8, 8)
+#define CH_EXTRA_INFO_SET_SIZE(extra_info, value)                              \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 8, 8, value)
+#define CH_EXTRA_INFO_GET_DATA(extra_info)                                     \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 1)
+#define CH_EXTRA_INFO_SET_DATA(extra_info, value)                              \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 1, value)
+#define HIOE_INSTRUCTION_INFO_GET_BYTEDATA_L(extra_info)                       \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 0, 16)
+#define HIOE_INSTRUCTION_INFO_SET_BYTEDATA_L(extra_info, value)                \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 0, 16, value)
+#define HIOE_INSTRUCTION_INFO_GET_BITDATA(extra_info)                          \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 0, 16)
+#define HIOE_INSTRUCTION_INFO_SET_BITDATA(extra_info, value)                   \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 0, 16, value)
+#define HIOE_INSTRUCTION_INFO_GET_BYTEDATA_H(extra_info)                       \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 16)
+#define HIOE_INSTRUCTION_INFO_SET_BYTEDATA_H(extra_info, value)                \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 16, value)
+#define HIOE_INSTRUCTION_INFO_GET_BITMASK(extra_info)                          \
+	LE_BITS_TO_4BYTE(extra_info + 0X00, 16, 16)
+#define HIOE_INSTRUCTION_INFO_SET_BITMASK(extra_info, value)                   \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X00, 16, 16, value)
+#define HIOE_INSTRUCTION_INFO_GET_REG_ADDR(extra_info)                         \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 0, 22)
+#define HIOE_INSTRUCTION_INFO_SET_REG_ADDR(extra_info, value)                  \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 0, 22, value)
+#define HIOE_INSTRUCTION_INFO_GET_DELAY_VALUE(extra_info)                      \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 0, 22)
+#define HIOE_INSTRUCTION_INFO_SET_DELAY_VALUE(extra_info, value)               \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 0, 22, value)
+#define HIOE_INSTRUCTION_INFO_GET_MODE_SELECT(extra_info)                      \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 22, 1)
+#define HIOE_INSTRUCTION_INFO_SET_MODE_SELECT(extra_info, value)               \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 22, 1, value)
+#define HIOE_INSTRUCTION_INFO_GET_IO_DELAY(extra_info)                         \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 23, 1)
+#define HIOE_INSTRUCTION_INFO_SET_IO_DELAY(extra_info, value)                  \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 23, 1, value)
+#define HIOE_INSTRUCTION_INFO_GET_BYTEMASK(extra_info)                         \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 24, 4)
+#define HIOE_INSTRUCTION_INFO_SET_BYTEMASK(extra_info, value)                  \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 24, 4, value)
+#define HIOE_INSTRUCTION_INFO_GET_RD_EN(extra_info)                            \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 28, 1)
+#define HIOE_INSTRUCTION_INFO_SET_RD_EN(extra_info, value)                     \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 28, 1, value)
+#define HIOE_INSTRUCTION_INFO_GET_WR_EN(extra_info)                            \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 29, 1)
+#define HIOE_INSTRUCTION_INFO_SET_WR_EN(extra_info, value)                     \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 29, 1, value)
+#define HIOE_INSTRUCTION_INFO_GET_RAW_R(extra_info)                            \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 30, 1)
+#define HIOE_INSTRUCTION_INFO_SET_RAW_R(extra_info, value)                     \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 30, 1, value)
+#define HIOE_INSTRUCTION_INFO_GET_RAW(extra_info)                              \
+	LE_BITS_TO_4BYTE(extra_info + 0X04, 31, 1)
+#define HIOE_INSTRUCTION_INFO_SET_RAW(extra_info, value)                       \
+	SET_BITS_TO_LE_4BYTE(extra_info + 0X04, 31, 1, value)
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_c2h_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_c2h_nic.h
new file mode 100644
index 000000000000..18cc2c7a09ba
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_c2h_nic.h
@@ -0,0 +1,408 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HAL_ORIGINALC2HFORMAT_H2C_C2H_NIC_H_
+#define _HAL_ORIGINALC2HFORMAT_H2C_C2H_NIC_H_
+#define CMD_ID_C2H 0X00
+#define CMD_ID_DBG 0X00
+#define CMD_ID_C2H_LB 0X01
+#define CMD_ID_C2H_SND_TXBF 0X02
+#define CMD_ID_C2H_CCX_RPT 0X03
+#define CMD_ID_C2H_AP_REQ_TXRPT 0X04
+#define CMD_ID_C2H_INITIAL_RATE_COLLECTION 0X05
+#define CMD_ID_C2H_RA_RPT 0X0C
+#define CMD_ID_C2H_SPECIAL_STATISTICS 0X0D
+#define CMD_ID_C2H_RA_PARA_RPT 0X0E
+#define CMD_ID_C2H_CUR_CHANNEL 0X10
+#define CMD_ID_C2H_GPIO_WAKEUP 0X14
+#define C2H_GET_CMD_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_SET_CMD_ID(c2h_pkt, value)                                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_SET_SEQ(c2h_pkt, value)                                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define DBG_GET_CMD_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define DBG_SET_CMD_ID(c2h_pkt, value)                                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define DBG_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define DBG_SET_SEQ(c2h_pkt, value)                                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define DBG_GET_DBG_STR1(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 8)
+#define DBG_SET_DBG_STR1(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 8, value)
+#define DBG_GET_DBG_STR2(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 8)
+#define DBG_SET_DBG_STR2(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 8, value)
+#define DBG_GET_DBG_STR3(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define DBG_SET_DBG_STR3(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define DBG_GET_DBG_STR4(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define DBG_SET_DBG_STR4(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define DBG_GET_DBG_STR5(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 8)
+#define DBG_SET_DBG_STR5(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 8, value)
+#define DBG_GET_DBG_STR6(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 24, 8)
+#define DBG_SET_DBG_STR6(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 24, 8, value)
+#define DBG_GET_DBG_STR7(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 0, 8)
+#define DBG_SET_DBG_STR7(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 0, 8, value)
+#define DBG_GET_DBG_STR8(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 8, 8)
+#define DBG_SET_DBG_STR8(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 8, 8, value)
+#define DBG_GET_DBG_STR9(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 16, 8)
+#define DBG_SET_DBG_STR9(c2h_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 16, 8, value)
+#define DBG_GET_DBG_STR10(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 24, 8)
+#define DBG_SET_DBG_STR10(c2h_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 24, 8, value)
+#define DBG_GET_DBG_STR11(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 0, 8)
+#define DBG_SET_DBG_STR11(c2h_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 0, 8, value)
+#define DBG_GET_DBG_STR12(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 8, 8)
+#define DBG_SET_DBG_STR12(c2h_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 8, 8, value)
+#define DBG_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define DBG_SET_LEN(c2h_pkt, value)                                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define DBG_GET_TRIGGER(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define DBG_SET_TRIGGER(c2h_pkt, value)                                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_LB_GET_CMD_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_LB_SET_CMD_ID(c2h_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_LB_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_LB_SET_SEQ(c2h_pkt, value)                                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_LB_GET_PAYLOAD1(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 16)
+#define C2H_LB_SET_PAYLOAD1(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 16, value)
+#define C2H_LB_GET_PAYLOAD2(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 32)
+#define C2H_LB_SET_PAYLOAD2(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 32, value)
+#define C2H_LB_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_LB_SET_LEN(c2h_pkt, value)                                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_LB_GET_TRIGGER(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_LB_SET_TRIGGER(c2h_pkt, value)                                     \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_SND_TXBF_GET_CMD_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_SND_TXBF_SET_CMD_ID(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_SND_TXBF_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_SND_TXBF_SET_SEQ(c2h_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_SND_TXBF_GET_SND_RESULT(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 1)
+#define C2H_SND_TXBF_SET_SND_RESULT(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 1, value)
+#define C2H_SND_TXBF_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_SND_TXBF_SET_LEN(c2h_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_SND_TXBF_GET_TRIGGER(c2h_pkt)                                      \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_SND_TXBF_SET_TRIGGER(c2h_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_CCX_RPT_GET_CMD_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_CCX_RPT_SET_CMD_ID(c2h_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_CCX_RPT_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_CCX_RPT_SET_SEQ(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_CCX_RPT_GET_QSEL(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 5)
+#define C2H_CCX_RPT_SET_QSEL(c2h_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 5, value)
+#define C2H_CCX_RPT_GET_BMC(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 21, 1)
+#define C2H_CCX_RPT_SET_BMC(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 21, 1, value)
+#define C2H_CCX_RPT_GET_LIFE_TIME_OVER(c2h_pkt)                                \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 22, 1)
+#define C2H_CCX_RPT_SET_LIFE_TIME_OVER(c2h_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 22, 1, value)
+#define C2H_CCX_RPT_GET_RETRY_OVER(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 23, 1)
+#define C2H_CCX_RPT_SET_RETRY_OVER(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 23, 1, value)
+#define C2H_CCX_RPT_GET_MACID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 8)
+#define C2H_CCX_RPT_SET_MACID(c2h_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 8, value)
+#define C2H_CCX_RPT_GET_DATA_RETRY_CNT(c2h_pkt)                                \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 6)
+#define C2H_CCX_RPT_SET_DATA_RETRY_CNT(c2h_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 6, value)
+#define C2H_CCX_RPT_GET_QUEUE7_0(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define C2H_CCX_RPT_SET_QUEUE7_0(c2h_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define C2H_CCX_RPT_GET_QUEUE15_8(c2h_pkt)                                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 8)
+#define C2H_CCX_RPT_SET_QUEUE15_8(c2h_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 8, value)
+#define C2H_CCX_RPT_GET_FINAL_DATA_RATE(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 24, 8)
+#define C2H_CCX_RPT_SET_FINAL_DATA_RATE(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 24, 8, value)
+#define C2H_CCX_RPT_GET_SW_DEFINE_0(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 0, 8)
+#define C2H_CCX_RPT_SET_SW_DEFINE_0(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 0, 8, value)
+#define C2H_CCX_RPT_GET_SW_DEFINE_1(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 8, 4)
+#define C2H_CCX_RPT_SET_SW_DEFINE_1(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 8, 4, value)
+#define C2H_CCX_RPT_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_CCX_RPT_SET_LEN(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_CCX_RPT_GET_TRIGGER(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_CCX_RPT_SET_TRIGGER(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_CMD_ID(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_AP_REQ_TXRPT_SET_CMD_ID(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_AP_REQ_TXRPT_SET_SEQ(c2h_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_STA1_MACID(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 8)
+#define C2H_AP_REQ_TXRPT_SET_STA1_MACID(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TX_OK1_0(c2h_pkt)                                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_OK1_0(c2h_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TX_OK1_1(c2h_pkt)                                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_OK1_1(c2h_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TX_FAIL1_0(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_FAIL1_0(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TX_FAIL1_1(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_FAIL1_1(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_INITIAL_RATE1(c2h_pkt)                            \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 24, 8)
+#define C2H_AP_REQ_TXRPT_SET_INITIAL_RATE1(c2h_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 24, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_STA2_MACID(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 0, 8)
+#define C2H_AP_REQ_TXRPT_SET_STA2_MACID(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 0, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TX_OK2_0(c2h_pkt)                                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 8, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_OK2_0(c2h_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 8, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TX_OK2_1(c2h_pkt)                                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 16, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_OK2_1(c2h_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 16, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TX_FAIL2_0(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 24, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_FAIL2_0(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 24, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TX_FAIL2_1(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 0, 8)
+#define C2H_AP_REQ_TXRPT_SET_TX_FAIL2_1(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 0, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_INITIAL_RATE2(c2h_pkt)                            \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 8, 8)
+#define C2H_AP_REQ_TXRPT_SET_INITIAL_RATE2(c2h_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 8, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_LEN(c2h_pkt)                                      \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_AP_REQ_TXRPT_SET_LEN(c2h_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_AP_REQ_TXRPT_GET_TRIGGER(c2h_pkt)                                  \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_AP_REQ_TXRPT_SET_TRIGGER(c2h_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_CMD_ID(c2h_pkt)                        \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_CMD_ID(c2h_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_SEQ(c2h_pkt)                           \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_SEQ(c2h_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_TRYING_BITMAP(c2h_pkt)                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 7)
+#define C2H_INITIAL_RATE_COLLECTION_SET_TRYING_BITMAP(c2h_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 7, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE1(c2h_pkt)                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE1(c2h_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE2(c2h_pkt)                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE2(c2h_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE3(c2h_pkt)                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE3(c2h_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE4(c2h_pkt)                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE4(c2h_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE5(c2h_pkt)                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 24, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE5(c2h_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 24, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE6(c2h_pkt)                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 0, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE6(c2h_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 0, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_INITIAL_RATE7(c2h_pkt)                 \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 8, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_INITIAL_RATE7(c2h_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 8, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_LEN(c2h_pkt)                           \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_LEN(c2h_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_INITIAL_RATE_COLLECTION_GET_TRIGGER(c2h_pkt)                       \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_INITIAL_RATE_COLLECTION_SET_TRIGGER(c2h_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_RA_RPT_GET_CMD_ID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_RA_RPT_SET_CMD_ID(c2h_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_RA_RPT_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_RA_RPT_SET_SEQ(c2h_pkt, value)                                     \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_RA_RPT_GET_RATE(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 8)
+#define C2H_RA_RPT_SET_RATE(c2h_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 8, value)
+#define C2H_RA_RPT_GET_MACID(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 8)
+#define C2H_RA_RPT_SET_MACID(c2h_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 8, value)
+#define C2H_RA_RPT_GET_USE_LDPC(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 1)
+#define C2H_RA_RPT_SET_USE_LDPC(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 1, value)
+#define C2H_RA_RPT_GET_USE_TXBF(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 1, 1)
+#define C2H_RA_RPT_SET_USE_TXBF(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 1, 1, value)
+#define C2H_RA_RPT_GET_COLLISION_STATE(c2h_pkt)                                \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define C2H_RA_RPT_SET_COLLISION_STATE(c2h_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define C2H_RA_RPT_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_RA_RPT_SET_LEN(c2h_pkt, value)                                     \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_RA_RPT_GET_TRIGGER(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_RA_RPT_SET_TRIGGER(c2h_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_CMD_ID(c2h_pkt)                             \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_SPECIAL_STATISTICS_SET_CMD_ID(c2h_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_SEQ(c2h_pkt)                                \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_SPECIAL_STATISTICS_SET_SEQ(c2h_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_STATISTICS_IDX(c2h_pkt)                     \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 8)
+#define C2H_SPECIAL_STATISTICS_SET_STATISTICS_IDX(c2h_pkt, value)              \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA0(c2h_pkt)                              \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 24, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA0(c2h_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 24, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA1(c2h_pkt)                              \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 0, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA1(c2h_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 0, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA2(c2h_pkt)                              \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 8, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA2(c2h_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 8, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA3(c2h_pkt)                              \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 16, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA3(c2h_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 16, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA4(c2h_pkt)                              \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X04, 24, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA4(c2h_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X04, 24, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA5(c2h_pkt)                              \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 0, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA5(c2h_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 0, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA6(c2h_pkt)                              \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 8, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA6(c2h_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 8, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_DATA7(c2h_pkt)                              \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X08, 16, 8)
+#define C2H_SPECIAL_STATISTICS_SET_DATA7(c2h_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X08, 16, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_LEN(c2h_pkt)                                \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_SPECIAL_STATISTICS_SET_LEN(c2h_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_SPECIAL_STATISTICS_GET_TRIGGER(c2h_pkt)                            \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_SPECIAL_STATISTICS_SET_TRIGGER(c2h_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_RA_PARA_RPT_GET_CMD_ID(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_RA_PARA_RPT_SET_CMD_ID(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_RA_PARA_RPT_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_RA_PARA_RPT_SET_SEQ(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_RA_PARA_RPT_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_RA_PARA_RPT_SET_LEN(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_RA_PARA_RPT_GET_TRIGGER(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_RA_PARA_RPT_SET_TRIGGER(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_CUR_CHANNEL_GET_CMD_ID(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_CUR_CHANNEL_SET_CMD_ID(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_CUR_CHANNEL_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_CUR_CHANNEL_SET_SEQ(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_CUR_CHANNEL_GET_CHANNEL_NUM(c2h_pkt)                               \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 16, 8)
+#define C2H_CUR_CHANNEL_SET_CHANNEL_NUM(c2h_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 16, 8, value)
+#define C2H_CUR_CHANNEL_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_CUR_CHANNEL_SET_LEN(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_CUR_CHANNEL_GET_TRIGGER(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_CUR_CHANNEL_SET_TRIGGER(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#define C2H_GPIO_WAKEUP_GET_CMD_ID(c2h_pkt)                                    \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 0, 8)
+#define C2H_GPIO_WAKEUP_SET_CMD_ID(c2h_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 0, 8, value)
+#define C2H_GPIO_WAKEUP_GET_SEQ(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X00, 8, 8)
+#define C2H_GPIO_WAKEUP_SET_SEQ(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X00, 8, 8, value)
+#define C2H_GPIO_WAKEUP_GET_LEN(c2h_pkt) LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 16, 8)
+#define C2H_GPIO_WAKEUP_SET_LEN(c2h_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 16, 8, value)
+#define C2H_GPIO_WAKEUP_GET_TRIGGER(c2h_pkt)                                   \
+	LE_BITS_TO_4BYTE(c2h_pkt + 0X0C, 24, 8)
+#define C2H_GPIO_WAKEUP_SET_TRIGGER(c2h_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(c2h_pkt + 0X0C, 24, 8, value)
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_h2c_nic.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_h2c_nic.h
new file mode 100644
index 000000000000..3870ff4953c8
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_original_h2c_nic.h
@@ -0,0 +1,1143 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HAL_ORIGINALH2CFORMAT_H2C_C2H_NIC_H_
+#define _HAL_ORIGINALH2CFORMAT_H2C_C2H_NIC_H_
+#define CMD_ID_ORIGINAL_H2C 0X00
+#define CMD_ID_H2C2H_LB 0X0
+#define CMD_ID_D0_SCAN_OFFLOAD_CTRL 0X06
+#define CMD_ID_RSVD_PAGE 0X0
+#define CMD_ID_MEDIA_STATUS_RPT 0X01
+#define CMD_ID_KEEP_ALIVE 0X03
+#define CMD_ID_DISCONNECT_DECISION 0X04
+#define CMD_ID_AP_OFFLOAD 0X08
+#define CMD_ID_BCN_RSVDPAGE 0X09
+#define CMD_ID_PROBE_RSP_RSVDPAGE 0X0A
+#define CMD_ID_SINGLE_CHANNELSWITCH 0X1C
+#define CMD_ID_SINGLE_CHANNELSWITCH_V2 0X1D
+#define CMD_ID_SET_PWR_MODE 0X00
+#define CMD_ID_PS_TUNING_PARA 0X01
+#define CMD_ID_PS_TUNING_PARA_II 0X02
+#define CMD_ID_PS_LPS_PARA 0X03
+#define CMD_ID_P2P_PS_OFFLOAD 0X04
+#define CMD_ID_PS_SCAN_EN 0X05
+#define CMD_ID_SAP_PS 0X06
+#define CMD_ID_INACTIVE_PS 0X07
+#define CMD_ID_MACID_CFG 0X00
+#define CMD_ID_TXBF 0X01
+#define CMD_ID_RSSI_SETTING 0X02
+#define CMD_ID_AP_REQ_TXRPT 0X03
+#define CMD_ID_INIT_RATE_COLLECTION 0X04
+#define CMD_ID_IQK_OFFLOAD 0X05
+#define CMD_ID_MACID_CFG_3SS 0X06
+#define CMD_ID_RA_PARA_ADJUST 0X07
+#define CMD_ID_WWLAN 0X00
+#define CMD_ID_REMOTE_WAKE_CTRL 0X01
+#define CMD_ID_AOAC_GLOBAL_INFO 0X02
+#define CMD_ID_AOAC_RSVD_PAGE 0X03
+#define CMD_ID_AOAC_RSVD_PAGE2 0X04
+#define CMD_ID_D0_SCAN_OFFLOAD_INFO 0X05
+#define CMD_ID_CHANNEL_SWITCH_OFFLOAD 0X07
+#define CMD_ID_AOAC_RSVD_PAGE3 0X08
+#define CMD_ID_DBG_MSG_CTRL 0X1E
+#define CLASS_ORIGINAL_H2C 0X00
+#define CLASS_H2C2H_LB 0X07
+#define CLASS_D0_SCAN_OFFLOAD_CTRL 0X04
+#define CLASS_RSVD_PAGE 0X0
+#define CLASS_MEDIA_STATUS_RPT 0X0
+#define CLASS_KEEP_ALIVE 0X0
+#define CLASS_DISCONNECT_DECISION 0X0
+#define CLASS_AP_OFFLOAD 0X0
+#define CLASS_BCN_RSVDPAGE 0X0
+#define CLASS_PROBE_RSP_RSVDPAGE 0X0
+#define CLASS_SINGLE_CHANNELSWITCH 0X0
+#define CLASS_SINGLE_CHANNELSWITCH_V2 0X0
+#define CLASS_SET_PWR_MODE 0X01
+#define CLASS_PS_TUNING_PARA 0X01
+#define CLASS_PS_TUNING_PARA_II 0X01
+#define CLASS_PS_LPS_PARA 0X01
+#define CLASS_P2P_PS_OFFLOAD 0X01
+#define CLASS_PS_SCAN_EN 0X1
+#define CLASS_SAP_PS 0X1
+#define CLASS_INACTIVE_PS 0X1
+#define CLASS_MACID_CFG 0X2
+#define CLASS_TXBF 0X2
+#define CLASS_RSSI_SETTING 0X2
+#define CLASS_AP_REQ_TXRPT 0X2
+#define CLASS_INIT_RATE_COLLECTION 0X2
+#define CLASS_IQK_OFFLOAD 0X2
+#define CLASS_MACID_CFG_3SS 0X2
+#define CLASS_RA_PARA_ADJUST 0X02
+#define CLASS_WWLAN 0X4
+#define CLASS_REMOTE_WAKE_CTRL 0X4
+#define CLASS_AOAC_GLOBAL_INFO 0X04
+#define CLASS_AOAC_RSVD_PAGE 0X04
+#define CLASS_AOAC_RSVD_PAGE2 0X04
+#define CLASS_D0_SCAN_OFFLOAD_INFO 0X04
+#define CLASS_CHANNEL_SWITCH_OFFLOAD 0X04
+#define CLASS_AOAC_RSVD_PAGE3 0X04
+#define CLASS_DBG_MSG_CTRL 0X07
+#define ORIGINAL_H2C_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define ORIGINAL_H2C_SET_CMD_ID(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define ORIGINAL_H2C_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define ORIGINAL_H2C_SET_CLASS(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define H2C2H_LB_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define H2C2H_LB_SET_CMD_ID(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define H2C2H_LB_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define H2C2H_LB_SET_CLASS(h2c_pkt, value)                                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define H2C2H_LB_GET_SEQ(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define H2C2H_LB_SET_SEQ(h2c_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define H2C2H_LB_GET_PAYLOAD1(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 16)
+#define H2C2H_LB_SET_PAYLOAD1(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 16, value)
+#define H2C2H_LB_GET_PAYLOAD2(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 32)
+#define H2C2H_LB_SET_PAYLOAD2(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 32, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_CMD_ID(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define D0_SCAN_OFFLOAD_CTRL_SET_CMD_ID(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_CLASS(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define D0_SCAN_OFFLOAD_CTRL_SET_CLASS(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_D0_SCAN_FUN_EN(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_D0_SCAN_FUN_EN(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_RTD3FUN_EN(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_RTD3FUN_EN(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_U3_SCAN_FUN_EN(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 10, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_U3_SCAN_FUN_EN(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 10, 1, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_NLO_FUN_EN(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 11, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_NLO_FUN_EN(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 11, 1, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_IPS_DEPENDENT(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 12, 1)
+#define D0_SCAN_OFFLOAD_CTRL_SET_IPS_DEPENDENT(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 12, 1, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_LOC_PROBE_PACKET(h2c_pkt)                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 17)
+#define D0_SCAN_OFFLOAD_CTRL_SET_LOC_PROBE_PACKET(h2c_pkt, value)              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 17, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_LOC_SCAN_INFO(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define D0_SCAN_OFFLOAD_CTRL_SET_LOC_SCAN_INFO(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define D0_SCAN_OFFLOAD_CTRL_GET_LOC_SSID_INFO(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define D0_SCAN_OFFLOAD_CTRL_SET_LOC_SSID_INFO(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define RSVD_PAGE_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define RSVD_PAGE_SET_CMD_ID(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define RSVD_PAGE_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define RSVD_PAGE_SET_CLASS(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define RSVD_PAGE_GET_LOC_PROBE_RSP(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define RSVD_PAGE_SET_LOC_PROBE_RSP(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define RSVD_PAGE_GET_LOC_PS_POLL(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define RSVD_PAGE_SET_LOC_PS_POLL(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define RSVD_PAGE_GET_LOC_NULL_DATA(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define RSVD_PAGE_SET_LOC_NULL_DATA(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define RSVD_PAGE_GET_LOC_QOS_NULL(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define RSVD_PAGE_SET_LOC_QOS_NULL(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define RSVD_PAGE_GET_LOC_BT_QOS_NULL(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define RSVD_PAGE_SET_LOC_BT_QOS_NULL(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define RSVD_PAGE_GET_LOC_CTS2SELF(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 8)
+#define RSVD_PAGE_SET_LOC_CTS2SELF(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 8, value)
+#define RSVD_PAGE_GET_LOC_LTECOEX_QOSNULL(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 24, 8)
+#define RSVD_PAGE_SET_LOC_LTECOEX_QOSNULL(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 24, 8, value)
+#define MEDIA_STATUS_RPT_GET_CMD_ID(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define MEDIA_STATUS_RPT_SET_CMD_ID(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define MEDIA_STATUS_RPT_GET_CLASS(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define MEDIA_STATUS_RPT_SET_CLASS(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define MEDIA_STATUS_RPT_GET_OP_MODE(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define MEDIA_STATUS_RPT_SET_OP_MODE(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define MEDIA_STATUS_RPT_GET_MACID_IN(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define MEDIA_STATUS_RPT_SET_MACID_IN(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define MEDIA_STATUS_RPT_GET_MACID(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define MEDIA_STATUS_RPT_SET_MACID(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define MEDIA_STATUS_RPT_GET_MACID_END(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define MEDIA_STATUS_RPT_SET_MACID_END(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define KEEP_ALIVE_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define KEEP_ALIVE_SET_CMD_ID(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define KEEP_ALIVE_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define KEEP_ALIVE_SET_CLASS(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define KEEP_ALIVE_GET_ENABLE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define KEEP_ALIVE_SET_ENABLE(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define KEEP_ALIVE_GET_ADOPT_USER_SETTING(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define KEEP_ALIVE_SET_ADOPT_USER_SETTING(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define KEEP_ALIVE_GET_PKT_TYPE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 10, 1)
+#define KEEP_ALIVE_SET_PKT_TYPE(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 10, 1, value)
+#define KEEP_ALIVE_GET_KEEP_ALIVE_CHECK_PERIOD(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define KEEP_ALIVE_SET_KEEP_ALIVE_CHECK_PERIOD(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define DISCONNECT_DECISION_GET_CMD_ID(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define DISCONNECT_DECISION_SET_CMD_ID(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define DISCONNECT_DECISION_GET_CLASS(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define DISCONNECT_DECISION_SET_CLASS(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define DISCONNECT_DECISION_GET_ENABLE(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define DISCONNECT_DECISION_SET_ENABLE(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define DISCONNECT_DECISION_GET_ADOPT_USER_SETTING(h2c_pkt)                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define DISCONNECT_DECISION_SET_ADOPT_USER_SETTING(h2c_pkt, value)             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define DISCONNECT_DECISION_GET_TRY_OK_BCN_FAIL_COUNT_EN(h2c_pkt)              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 10, 1)
+#define DISCONNECT_DECISION_SET_TRY_OK_BCN_FAIL_COUNT_EN(h2c_pkt, value)       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 10, 1, value)
+#define DISCONNECT_DECISION_GET_DISCONNECT_EN(h2c_pkt)                         \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 11, 1)
+#define DISCONNECT_DECISION_SET_DISCONNECT_EN(h2c_pkt, value)                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 11, 1, value)
+#define DISCONNECT_DECISION_GET_DISCON_DECISION_CHECK_PERIOD(h2c_pkt)          \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define DISCONNECT_DECISION_SET_DISCON_DECISION_CHECK_PERIOD(h2c_pkt, value)   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define DISCONNECT_DECISION_GET_TRY_PKT_NUM(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define DISCONNECT_DECISION_SET_TRY_PKT_NUM(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define DISCONNECT_DECISION_GET_TRY_OK_BCN_FAIL_COUNT_LIMIT(h2c_pkt)           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define DISCONNECT_DECISION_SET_TRY_OK_BCN_FAIL_COUNT_LIMIT(h2c_pkt, value)    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define AP_OFFLOAD_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define AP_OFFLOAD_SET_CMD_ID(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define AP_OFFLOAD_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define AP_OFFLOAD_SET_CLASS(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define AP_OFFLOAD_GET_ON(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define AP_OFFLOAD_SET_ON(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define AP_OFFLOAD_GET_CFG_MIFI_PLATFORM(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define AP_OFFLOAD_SET_CFG_MIFI_PLATFORM(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define AP_OFFLOAD_GET_LINKED(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 10, 1)
+#define AP_OFFLOAD_SET_LINKED(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 10, 1, value)
+#define AP_OFFLOAD_GET_EN_AUTO_WAKE(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 11, 1)
+#define AP_OFFLOAD_SET_EN_AUTO_WAKE(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 11, 1, value)
+#define AP_OFFLOAD_GET_WAKE_FLAG(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 12, 1)
+#define AP_OFFLOAD_SET_WAKE_FLAG(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 12, 1, value)
+#define AP_OFFLOAD_GET_HIDDEN_ROOT(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 1)
+#define AP_OFFLOAD_SET_HIDDEN_ROOT(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 1, value)
+#define AP_OFFLOAD_GET_HIDDEN_VAP1(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 17, 1)
+#define AP_OFFLOAD_SET_HIDDEN_VAP1(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 17, 1, value)
+#define AP_OFFLOAD_GET_HIDDEN_VAP2(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 18, 1)
+#define AP_OFFLOAD_SET_HIDDEN_VAP2(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 18, 1, value)
+#define AP_OFFLOAD_GET_HIDDEN_VAP3(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 19, 1)
+#define AP_OFFLOAD_SET_HIDDEN_VAP3(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 19, 1, value)
+#define AP_OFFLOAD_GET_HIDDEN_VAP4(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 20, 1)
+#define AP_OFFLOAD_SET_HIDDEN_VAP4(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 20, 1, value)
+#define AP_OFFLOAD_GET_DENYANY_ROOT(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 1)
+#define AP_OFFLOAD_SET_DENYANY_ROOT(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 1, value)
+#define AP_OFFLOAD_GET_DENYANY_VAP1(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 25, 1)
+#define AP_OFFLOAD_SET_DENYANY_VAP1(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 25, 1, value)
+#define AP_OFFLOAD_GET_DENYANY_VAP2(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 26, 1)
+#define AP_OFFLOAD_SET_DENYANY_VAP2(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 26, 1, value)
+#define AP_OFFLOAD_GET_DENYANY_VAP3(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 27, 1)
+#define AP_OFFLOAD_SET_DENYANY_VAP3(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 27, 1, value)
+#define AP_OFFLOAD_GET_DENYANY_VAP4(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 28, 1)
+#define AP_OFFLOAD_SET_DENYANY_VAP4(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 28, 1, value)
+#define AP_OFFLOAD_GET_WAIT_TBTT_CNT(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define AP_OFFLOAD_SET_WAIT_TBTT_CNT(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define AP_OFFLOAD_GET_WAKE_TIMEOUT(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define AP_OFFLOAD_SET_WAKE_TIMEOUT(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define AP_OFFLOAD_GET_LEN_IV_PAIR(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 8)
+#define AP_OFFLOAD_SET_LEN_IV_PAIR(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 8, value)
+#define AP_OFFLOAD_GET_LEN_IV_GRP(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 24, 8)
+#define AP_OFFLOAD_SET_LEN_IV_GRP(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 24, 8, value)
+#define BCN_RSVDPAGE_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define BCN_RSVDPAGE_SET_CMD_ID(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define BCN_RSVDPAGE_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define BCN_RSVDPAGE_SET_CLASS(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define BCN_RSVDPAGE_GET_LOC_ROOT(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define BCN_RSVDPAGE_SET_LOC_ROOT(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define BCN_RSVDPAGE_GET_LOC_VAP1(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define BCN_RSVDPAGE_SET_LOC_VAP1(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define BCN_RSVDPAGE_GET_LOC_VAP2(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define BCN_RSVDPAGE_SET_LOC_VAP2(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define BCN_RSVDPAGE_GET_LOC_VAP3(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define BCN_RSVDPAGE_SET_LOC_VAP3(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define BCN_RSVDPAGE_GET_LOC_VAP4(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define BCN_RSVDPAGE_SET_LOC_VAP4(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define PROBE_RSP_RSVDPAGE_GET_CMD_ID(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define PROBE_RSP_RSVDPAGE_SET_CMD_ID(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define PROBE_RSP_RSVDPAGE_GET_CLASS(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define PROBE_RSP_RSVDPAGE_SET_CLASS(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_ROOT(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_ROOT(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_VAP1(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_VAP1(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_VAP2(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_VAP2(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_VAP3(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_VAP3(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define PROBE_RSP_RSVDPAGE_GET_LOC_VAP4(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define PROBE_RSP_RSVDPAGE_SET_LOC_VAP4(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define SINGLE_CHANNELSWITCH_GET_CMD_ID(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define SINGLE_CHANNELSWITCH_SET_CMD_ID(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define SINGLE_CHANNELSWITCH_GET_CLASS(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define SINGLE_CHANNELSWITCH_SET_CLASS(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define SINGLE_CHANNELSWITCH_GET_CHANNEL_NUM(h2c_pkt)                          \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define SINGLE_CHANNELSWITCH_SET_CHANNEL_NUM(h2c_pkt, value)                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define SINGLE_CHANNELSWITCH_GET_BW(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 2)
+#define SINGLE_CHANNELSWITCH_SET_BW(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 2, value)
+#define SINGLE_CHANNELSWITCH_GET_BW40SC(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 18, 3)
+#define SINGLE_CHANNELSWITCH_SET_BW40SC(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 18, 3, value)
+#define SINGLE_CHANNELSWITCH_GET_BW80SC(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 21, 3)
+#define SINGLE_CHANNELSWITCH_SET_BW80SC(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 21, 3, value)
+#define SINGLE_CHANNELSWITCH_GET_RFE_TYPE(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 4)
+#define SINGLE_CHANNELSWITCH_SET_RFE_TYPE(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 4, value)
+#define SINGLE_CHANNELSWITCH_V2_GET_CMD_ID(h2c_pkt)                            \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define SINGLE_CHANNELSWITCH_V2_SET_CMD_ID(h2c_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define SINGLE_CHANNELSWITCH_V2_GET_CLASS(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define SINGLE_CHANNELSWITCH_V2_SET_CLASS(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define SINGLE_CHANNELSWITCH_V2_GET_CENTRAL_CH(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define SINGLE_CHANNELSWITCH_V2_SET_CENTRAL_CH(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define SINGLE_CHANNELSWITCH_V2_GET_PRIMARY_CH_IDX(h2c_pkt)                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 4)
+#define SINGLE_CHANNELSWITCH_V2_SET_PRIMARY_CH_IDX(h2c_pkt, value)             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 4, value)
+#define SINGLE_CHANNELSWITCH_V2_GET_BW(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 20, 4)
+#define SINGLE_CHANNELSWITCH_V2_SET_BW(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 20, 4, value)
+#define SET_PWR_MODE_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define SET_PWR_MODE_SET_CMD_ID(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define SET_PWR_MODE_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define SET_PWR_MODE_SET_CLASS(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define SET_PWR_MODE_GET_MODE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 7)
+#define SET_PWR_MODE_SET_MODE(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 7, value)
+#define SET_PWR_MODE_GET_CLK_REQUEST(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 15, 1)
+#define SET_PWR_MODE_SET_CLK_REQUEST(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 15, 1, value)
+#define SET_PWR_MODE_GET_RLBM(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 4)
+#define SET_PWR_MODE_SET_RLBM(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 4, value)
+#define SET_PWR_MODE_GET_SMART_PS(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 20, 4)
+#define SET_PWR_MODE_SET_SMART_PS(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 20, 4, value)
+#define SET_PWR_MODE_GET_AWAKE_INTERVAL(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define SET_PWR_MODE_GET_B_ALL_QUEUE_UAPSD(h2c_pkt)                            \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 1)
+#define SET_PWR_MODE_SET_B_ALL_QUEUE_UAPSD(h2c_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 1, value)
+#define SET_PWR_MODE_GET_BCN_EARLY_RPT(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 2, 1)
+#define SET_PWR_MODE_SET_BCN_EARLY_RPT(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 2, 1, value)
+#define SET_PWR_MODE_GET_PORT_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 5, 3)
+#define SET_PWR_MODE_SET_PORT_ID(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 5, 3, value)
+#define SET_PWR_MODE_GET_PWR_STATE(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define SET_PWR_MODE_SET_PWR_STATE(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define SET_PWR_MODE_GET_LOW_POWER_RX_BCN(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 1)
+#define SET_PWR_MODE_SET_LOW_POWER_RX_BCN(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 1, value)
+#define SET_PWR_MODE_GET_ANT_AUTO_SWITCH(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 17, 1)
+#define SET_PWR_MODE_SET_ANT_AUTO_SWITCH(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 17, 1, value)
+#define SET_PWR_MODE_GET_PS_ALLOW_BT_HIGH_PRIORITY(h2c_pkt)                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 18, 1)
+#define SET_PWR_MODE_SET_PS_ALLOW_BT_HIGH_PRIORITY(h2c_pkt, value)             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 18, 1, value)
+#define SET_PWR_MODE_GET_PROTECT_BCN(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 19, 1)
+#define SET_PWR_MODE_SET_PROTECT_BCN(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 19, 1, value)
+#define SET_PWR_MODE_GET_SILENCE_PERIOD(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 20, 1)
+#define SET_PWR_MODE_SET_SILENCE_PERIOD(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 20, 1, value)
+#define SET_PWR_MODE_GET_FAST_BT_CONNECT(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 21, 1)
+#define SET_PWR_MODE_SET_FAST_BT_CONNECT(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 21, 1, value)
+#define SET_PWR_MODE_GET_TWO_ANTENNA_EN(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 22, 1)
+#define SET_PWR_MODE_SET_TWO_ANTENNA_EN(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 22, 1, value)
+#define SET_PWR_MODE_GET_ADOPT_USER_SETTING(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 24, 1)
+#define SET_PWR_MODE_SET_ADOPT_USER_SETTING(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 24, 1, value)
+#define SET_PWR_MODE_GET_DRV_BCN_EARLY_SHIFT(h2c_pkt)                          \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 25, 3)
+#define SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT(h2c_pkt, value)                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 25, 3, value)
+#define SET_PWR_MODE_GET_DRV_BCN_EARLY_SHIFT2(h2c_pkt)                         \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 28, 4)
+#define SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT2(h2c_pkt, value)                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 28, 4, value)
+#define PS_TUNING_PARA_GET_CMD_ID(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define PS_TUNING_PARA_SET_CMD_ID(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define PS_TUNING_PARA_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define PS_TUNING_PARA_SET_CLASS(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define PS_TUNING_PARA_GET_BCN_TO_LIMIT(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 7)
+#define PS_TUNING_PARA_SET_BCN_TO_LIMIT(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 7, value)
+#define PS_TUNING_PARA_GET_DTIM_TIME_OUT(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 15, 1)
+#define PS_TUNING_PARA_SET_DTIM_TIME_OUT(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 15, 1, value)
+#define PS_TUNING_PARA_GET_PS_TIME_OUT(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 4)
+#define PS_TUNING_PARA_SET_PS_TIME_OUT(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 4, value)
+#define PS_TUNING_PARA_GET_ADOPT(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define PS_TUNING_PARA_SET_ADOPT(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define PS_TUNING_PARA_II_GET_CMD_ID(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define PS_TUNING_PARA_II_SET_CMD_ID(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define PS_TUNING_PARA_II_GET_CLASS(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define PS_TUNING_PARA_II_SET_CLASS(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define PS_TUNING_PARA_II_GET_BCN_TO_PERIOD(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 7)
+#define PS_TUNING_PARA_II_SET_BCN_TO_PERIOD(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 7, value)
+#define PS_TUNING_PARA_II_GET_ADOPT(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 15, 1)
+#define PS_TUNING_PARA_II_SET_ADOPT(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 15, 1, value)
+#define PS_TUNING_PARA_II_GET_DRV_EARLY_IVL(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define PS_TUNING_PARA_II_SET_DRV_EARLY_IVL(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define PS_LPS_PARA_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define PS_LPS_PARA_SET_CMD_ID(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define PS_LPS_PARA_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define PS_LPS_PARA_SET_CLASS(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define PS_LPS_PARA_GET_LPS_CONTROL(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define PS_LPS_PARA_SET_LPS_CONTROL(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define P2P_PS_OFFLOAD_GET_CMD_ID(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define P2P_PS_OFFLOAD_SET_CMD_ID(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define P2P_PS_OFFLOAD_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define P2P_PS_OFFLOAD_SET_CLASS(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define P2P_PS_OFFLOAD_GET_OFFLOAD_EN(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define P2P_PS_OFFLOAD_SET_OFFLOAD_EN(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define P2P_PS_OFFLOAD_GET_ROLE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define P2P_PS_OFFLOAD_SET_ROLE(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define P2P_PS_OFFLOAD_GET_CTWINDOW_EN(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 10, 1)
+#define P2P_PS_OFFLOAD_SET_CTWINDOW_EN(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 10, 1, value)
+#define P2P_PS_OFFLOAD_GET_NOA0_EN(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 11, 1)
+#define P2P_PS_OFFLOAD_SET_NOA0_EN(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 11, 1, value)
+#define P2P_PS_OFFLOAD_GET_NOA1_EN(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 12, 1)
+#define P2P_PS_OFFLOAD_SET_NOA1_EN(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 12, 1, value)
+#define P2P_PS_OFFLOAD_GET_ALL_STA_SLEEP(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 13, 1)
+#define P2P_PS_OFFLOAD_SET_ALL_STA_SLEEP(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 13, 1, value)
+#define P2P_PS_OFFLOAD_GET_DISCOVERY(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 14, 1)
+#define P2P_PS_OFFLOAD_SET_DISCOVERY(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 14, 1, value)
+#define PS_SCAN_EN_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define PS_SCAN_EN_SET_CMD_ID(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define PS_SCAN_EN_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define PS_SCAN_EN_SET_CLASS(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define PS_SCAN_EN_GET_ENABLE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define PS_SCAN_EN_SET_ENABLE(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define SAP_PS_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define SAP_PS_SET_CMD_ID(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define SAP_PS_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define SAP_PS_SET_CLASS(h2c_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define SAP_PS_GET_ENABLE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define SAP_PS_SET_ENABLE(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define SAP_PS_GET_EN_PS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define SAP_PS_SET_EN_PS(h2c_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define SAP_PS_GET_EN_LP_RX(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 10, 1)
+#define SAP_PS_SET_EN_LP_RX(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 10, 1, value)
+#define SAP_PS_GET_MANUAL_32K(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 11, 1)
+#define SAP_PS_SET_MANUAL_32K(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 11, 1, value)
+#define SAP_PS_GET_DURATION(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define SAP_PS_SET_DURATION(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define INACTIVE_PS_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define INACTIVE_PS_SET_CMD_ID(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define INACTIVE_PS_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define INACTIVE_PS_SET_CLASS(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define INACTIVE_PS_GET_ENABLE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define INACTIVE_PS_SET_ENABLE(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define INACTIVE_PS_GET_IGNORE_PS_CONDITION(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define INACTIVE_PS_SET_IGNORE_PS_CONDITION(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define INACTIVE_PS_GET_FREQUENCY(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define INACTIVE_PS_SET_FREQUENCY(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define INACTIVE_PS_GET_DURATION(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define INACTIVE_PS_SET_DURATION(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define MACID_CFG_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define MACID_CFG_SET_CMD_ID(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define MACID_CFG_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define MACID_CFG_SET_CLASS(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define MACID_CFG_GET_MAC_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define MACID_CFG_SET_MAC_ID(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define MACID_CFG_GET_RATE_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 5)
+#define MACID_CFG_SET_RATE_ID(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 5, value)
+#define MACID_CFG_GET_INIT_RATE_LV(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 21, 2)
+#define MACID_CFG_SET_INIT_RATE_LV(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 21, 2, value)
+#define MACID_CFG_GET_SGI(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 23, 1)
+#define MACID_CFG_SET_SGI(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 23, 1, value)
+#define MACID_CFG_GET_BW(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 2)
+#define MACID_CFG_SET_BW(h2c_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 2, value)
+#define MACID_CFG_GET_LDPC_CAP(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 26, 1)
+#define MACID_CFG_SET_LDPC_CAP(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 26, 1, value)
+#define MACID_CFG_GET_NO_UPDATE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 27, 1)
+#define MACID_CFG_SET_NO_UPDATE(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 27, 1, value)
+#define MACID_CFG_GET_WHT_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 28, 2)
+#define MACID_CFG_SET_WHT_EN(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 28, 2, value)
+#define MACID_CFG_GET_DISPT(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 30, 1)
+#define MACID_CFG_SET_DISPT(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 30, 1, value)
+#define MACID_CFG_GET_DISRA(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 31, 1)
+#define MACID_CFG_SET_DISRA(h2c_pkt, value)                                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 31, 1, value)
+#define MACID_CFG_GET_RATE_MASK7_0(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define MACID_CFG_SET_RATE_MASK7_0(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define MACID_CFG_GET_RATE_MASK15_8(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define MACID_CFG_SET_RATE_MASK15_8(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define MACID_CFG_GET_RATE_MASK23_16(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 8)
+#define MACID_CFG_SET_RATE_MASK23_16(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 8, value)
+#define MACID_CFG_GET_RATE_MASK31_24(h2c_pkt)                                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 24, 8)
+#define MACID_CFG_SET_RATE_MASK31_24(h2c_pkt, value)                           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 24, 8, value)
+#define TXBF_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define TXBF_SET_CMD_ID(h2c_pkt, value)                                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define TXBF_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define TXBF_SET_CLASS(h2c_pkt, value)                                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define TXBF_GET_NDPA0_HEAD_PAGE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define TXBF_SET_NDPA0_HEAD_PAGE(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define TXBF_GET_NDPA1_HEAD_PAGE(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define TXBF_SET_NDPA1_HEAD_PAGE(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define TXBF_GET_PERIOD_0(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define TXBF_SET_PERIOD_0(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define RSSI_SETTING_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define RSSI_SETTING_SET_CMD_ID(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define RSSI_SETTING_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define RSSI_SETTING_SET_CLASS(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define RSSI_SETTING_GET_MAC_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define RSSI_SETTING_SET_MAC_ID(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define RSSI_SETTING_GET_RSSI(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 7)
+#define RSSI_SETTING_SET_RSSI(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 7, value)
+#define RSSI_SETTING_GET_RA_INFO(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define RSSI_SETTING_SET_RA_INFO(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define AP_REQ_TXRPT_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define AP_REQ_TXRPT_SET_CMD_ID(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define AP_REQ_TXRPT_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define AP_REQ_TXRPT_SET_CLASS(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define AP_REQ_TXRPT_GET_STA1_MACID(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define AP_REQ_TXRPT_SET_STA1_MACID(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define AP_REQ_TXRPT_GET_STA2_MACID(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define AP_REQ_TXRPT_SET_STA2_MACID(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define AP_REQ_TXRPT_GET_RTY_OK_TOTAL(h2c_pkt)                                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 1)
+#define AP_REQ_TXRPT_SET_RTY_OK_TOTAL(h2c_pkt, value)                          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 1, value)
+#define AP_REQ_TXRPT_GET_RTY_CNT_MACID(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 25, 1)
+#define AP_REQ_TXRPT_SET_RTY_CNT_MACID(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 25, 1, value)
+#define INIT_RATE_COLLECTION_GET_CMD_ID(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define INIT_RATE_COLLECTION_SET_CMD_ID(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define INIT_RATE_COLLECTION_GET_CLASS(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define INIT_RATE_COLLECTION_SET_CLASS(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define INIT_RATE_COLLECTION_GET_STA1_MACID(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define INIT_RATE_COLLECTION_SET_STA1_MACID(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define INIT_RATE_COLLECTION_GET_STA2_MACID(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define INIT_RATE_COLLECTION_SET_STA2_MACID(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define INIT_RATE_COLLECTION_GET_STA3_MACID(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define INIT_RATE_COLLECTION_SET_STA3_MACID(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define INIT_RATE_COLLECTION_GET_STA4_MACID(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define INIT_RATE_COLLECTION_SET_STA4_MACID(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define INIT_RATE_COLLECTION_GET_STA5_MACID(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define INIT_RATE_COLLECTION_SET_STA5_MACID(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define INIT_RATE_COLLECTION_GET_STA6_MACID(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 8)
+#define INIT_RATE_COLLECTION_SET_STA6_MACID(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 8, value)
+#define INIT_RATE_COLLECTION_GET_STA7_MACID(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 24, 8)
+#define INIT_RATE_COLLECTION_SET_STA7_MACID(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 24, 8, value)
+#define IQK_OFFLOAD_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define IQK_OFFLOAD_SET_CMD_ID(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define IQK_OFFLOAD_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define IQK_OFFLOAD_SET_CLASS(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define IQK_OFFLOAD_GET_CHANNEL(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define IQK_OFFLOAD_SET_CHANNEL(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define IQK_OFFLOAD_GET_BWBAND(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define IQK_OFFLOAD_SET_BWBAND(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define IQK_OFFLOAD_GET_EXTPALNA(h2c_pkt)                                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define IQK_OFFLOAD_SET_EXTPALNA(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define MACID_CFG_3SS_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define MACID_CFG_3SS_SET_CMD_ID(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define MACID_CFG_3SS_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define MACID_CFG_3SS_SET_CLASS(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define MACID_CFG_3SS_GET_MACID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define MACID_CFG_3SS_SET_MACID(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define MACID_CFG_3SS_GET_RATE_MASK_39_32(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define MACID_CFG_3SS_SET_RATE_MASK_39_32(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define MACID_CFG_3SS_GET_RATE_MASK_47_40(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define MACID_CFG_3SS_SET_RATE_MASK_47_40(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define RA_PARA_ADJUST_GET_CMD_ID(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define RA_PARA_ADJUST_SET_CMD_ID(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define RA_PARA_ADJUST_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define RA_PARA_ADJUST_SET_CLASS(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define RA_PARA_ADJUST_GET_MAC_ID(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define RA_PARA_ADJUST_SET_MAC_ID(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define RA_PARA_ADJUST_GET_PARAMETER_INDEX(h2c_pkt)                            \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define RA_PARA_ADJUST_SET_PARAMETER_INDEX(h2c_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define RA_PARA_ADJUST_GET_RATE_ID(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define RA_PARA_ADJUST_SET_RATE_ID(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define RA_PARA_ADJUST_GET_VALUE_BYTE0(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define RA_PARA_ADJUST_SET_VALUE_BYTE0(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define RA_PARA_ADJUST_GET_VALUE_BYTE1(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define RA_PARA_ADJUST_SET_VALUE_BYTE1(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define RA_PARA_ADJUST_GET_ASK_FW_FOR_FW_PARA(h2c_pkt)                         \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 8)
+#define RA_PARA_ADJUST_SET_ASK_FW_FOR_FW_PARA(h2c_pkt, value)                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 8, value)
+#define WWLAN_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define WWLAN_SET_CMD_ID(h2c_pkt, value)                                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define WWLAN_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define WWLAN_SET_CLASS(h2c_pkt, value)                                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define WWLAN_GET_FUNC_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define WWLAN_SET_FUNC_EN(h2c_pkt, value)                                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define WWLAN_GET_PATTERM_MAT_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define WWLAN_SET_PATTERM_MAT_EN(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define WWLAN_GET_MAGIC_PKT_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 10, 1)
+#define WWLAN_SET_MAGIC_PKT_EN(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 10, 1, value)
+#define WWLAN_GET_UNICAST_WAKEUP_EN(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 11, 1)
+#define WWLAN_SET_UNICAST_WAKEUP_EN(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 11, 1, value)
+#define WWLAN_GET_ALL_PKT_DROP(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 12, 1)
+#define WWLAN_SET_ALL_PKT_DROP(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 12, 1, value)
+#define WWLAN_GET_GPIO_ACTIVE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 13, 1)
+#define WWLAN_SET_GPIO_ACTIVE(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 13, 1, value)
+#define WWLAN_GET_REKEY_WAKEUP_EN(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 14, 1)
+#define WWLAN_SET_REKEY_WAKEUP_EN(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 14, 1, value)
+#define WWLAN_GET_DEAUTH_WAKEUP_EN(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 15, 1)
+#define WWLAN_SET_DEAUTH_WAKEUP_EN(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 15, 1, value)
+#define WWLAN_GET_GPIO_NUM(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 7)
+#define WWLAN_SET_GPIO_NUM(h2c_pkt, value)                                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 7, value)
+#define WWLAN_GET_DATAPIN_WAKEUP_EN(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 23, 1)
+#define WWLAN_SET_DATAPIN_WAKEUP_EN(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 23, 1, value)
+#define WWLAN_GET_GPIO_DURATION(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define WWLAN_SET_GPIO_DURATION(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define WWLAN_GET_GPIO_PLUS_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 1)
+#define WWLAN_SET_GPIO_PLUS_EN(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 1, value)
+#define WWLAN_GET_GPIO_PULSE_COUNT(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 1, 7)
+#define WWLAN_SET_GPIO_PULSE_COUNT(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 1, 7, value)
+#define WWLAN_GET_DISABLE_UPHY(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 1)
+#define WWLAN_SET_DISABLE_UPHY(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 1, value)
+#define WWLAN_GET_HST2DEV_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 9, 1)
+#define WWLAN_SET_HST2DEV_EN(h2c_pkt, value)                                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 9, 1, value)
+#define WWLAN_GET_GPIO_DURATION_MS(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 10, 1)
+#define WWLAN_SET_GPIO_DURATION_MS(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 10, 1, value)
+#define REMOTE_WAKE_CTRL_GET_CMD_ID(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define REMOTE_WAKE_CTRL_SET_CMD_ID(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define REMOTE_WAKE_CTRL_GET_CLASS(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define REMOTE_WAKE_CTRL_SET_CLASS(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define REMOTE_WAKE_CTRL_GET_REMOTE_WAKE_CTRL_EN(h2c_pkt)                      \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define REMOTE_WAKE_CTRL_SET_REMOTE_WAKE_CTRL_EN(h2c_pkt, value)               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define REMOTE_WAKE_CTRL_GET_ARP_EN(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 9, 1)
+#define REMOTE_WAKE_CTRL_SET_ARP_EN(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 9, 1, value)
+#define REMOTE_WAKE_CTRL_GET_NDP_EN(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 10, 1)
+#define REMOTE_WAKE_CTRL_SET_NDP_EN(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 10, 1, value)
+#define REMOTE_WAKE_CTRL_GET_GTK_EN(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 11, 1)
+#define REMOTE_WAKE_CTRL_SET_GTK_EN(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 11, 1, value)
+#define REMOTE_WAKE_CTRL_GET_NLO_OFFLOAD_EN(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 12, 1)
+#define REMOTE_WAKE_CTRL_SET_NLO_OFFLOAD_EN(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 12, 1, value)
+#define REMOTE_WAKE_CTRL_GET_REAL_WOW_V1_EN(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 13, 1)
+#define REMOTE_WAKE_CTRL_SET_REAL_WOW_V1_EN(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 13, 1, value)
+#define REMOTE_WAKE_CTRL_GET_REAL_WOW_V2_EN(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 14, 1)
+#define REMOTE_WAKE_CTRL_SET_REAL_WOW_V2_EN(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 14, 1, value)
+#define REMOTE_WAKE_CTRL_GET_FW_UNICAST(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 15, 1)
+#define REMOTE_WAKE_CTRL_SET_FW_UNICAST(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 15, 1, value)
+#define REMOTE_WAKE_CTRL_GET_P2P_OFFLOAD_EN(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 1)
+#define REMOTE_WAKE_CTRL_SET_P2P_OFFLOAD_EN(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 1, value)
+#define REMOTE_WAKE_CTRL_GET_RUNTIME_PM_EN(h2c_pkt)                            \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 17, 1)
+#define REMOTE_WAKE_CTRL_SET_RUNTIME_PM_EN(h2c_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 17, 1, value)
+#define REMOTE_WAKE_CTRL_GET_NET_BIOS_DROP_EN(h2c_pkt)                         \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 18, 1)
+#define REMOTE_WAKE_CTRL_SET_NET_BIOS_DROP_EN(h2c_pkt, value)                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 18, 1, value)
+#define REMOTE_WAKE_CTRL_GET_ARP_ACTION(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 1)
+#define REMOTE_WAKE_CTRL_SET_ARP_ACTION(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 1, value)
+#define REMOTE_WAKE_CTRL_GET_FW_PARSING_UNTIL_WAKEUP(h2c_pkt)                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 28, 1)
+#define REMOTE_WAKE_CTRL_SET_FW_PARSING_UNTIL_WAKEUP(h2c_pkt, value)           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 28, 1, value)
+#define REMOTE_WAKE_CTRL_GET_FW_PARSING_AFTER_WAKEUP(h2c_pkt)                  \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 29, 1)
+#define REMOTE_WAKE_CTRL_SET_FW_PARSING_AFTER_WAKEUP(h2c_pkt, value)           \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 29, 1, value)
+#define AOAC_GLOBAL_INFO_GET_CMD_ID(h2c_pkt)                                   \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define AOAC_GLOBAL_INFO_SET_CMD_ID(h2c_pkt, value)                            \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define AOAC_GLOBAL_INFO_GET_CLASS(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define AOAC_GLOBAL_INFO_SET_CLASS(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define AOAC_GLOBAL_INFO_GET_PAIR_WISE_ENC_ALG(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define AOAC_GLOBAL_INFO_SET_PAIR_WISE_ENC_ALG(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define AOAC_GLOBAL_INFO_GET_GROUP_ENC_ALG(h2c_pkt)                            \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define AOAC_GLOBAL_INFO_SET_GROUP_ENC_ALG(h2c_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define AOAC_RSVD_PAGE_GET_CMD_ID(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define AOAC_RSVD_PAGE_SET_CMD_ID(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define AOAC_RSVD_PAGE_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define AOAC_RSVD_PAGE_SET_CLASS(h2c_pkt, value)                               \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define AOAC_RSVD_PAGE_GET_LOC_REMOTE_CTRL_INFO(h2c_pkt)                       \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_REMOTE_CTRL_INFO(h2c_pkt, value)                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define AOAC_RSVD_PAGE_GET_LOC_ARP_RESPONSE(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_ARP_RESPONSE(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define AOAC_RSVD_PAGE_GET_LOC_NEIGHBOR_ADVERTISEMENT(h2c_pkt)                 \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_NEIGHBOR_ADVERTISEMENT(h2c_pkt, value)          \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define AOAC_RSVD_PAGE_GET_LOC_GTK_RSP(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_GTK_RSP(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define AOAC_RSVD_PAGE_GET_LOC_GTK_INFO(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_GTK_INFO(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define AOAC_RSVD_PAGE_GET_LOC_GTK_EXT_MEM(h2c_pkt)                            \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_GTK_EXT_MEM(h2c_pkt, value)                     \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 8, value)
+#define AOAC_RSVD_PAGE_GET_LOC_NDP_INFO(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 24, 8)
+#define AOAC_RSVD_PAGE_SET_LOC_NDP_INFO(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 24, 8, value)
+#define AOAC_RSVD_PAGE2_GET_CMD_ID(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define AOAC_RSVD_PAGE2_SET_CMD_ID(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define AOAC_RSVD_PAGE2_GET_CLASS(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define AOAC_RSVD_PAGE2_SET_CLASS(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define AOAC_RSVD_PAGE2_GET_LOC_ROUTER_SOLICATION(h2c_pkt)                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_ROUTER_SOLICATION(h2c_pkt, value)              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define AOAC_RSVD_PAGE2_GET_LOC_BUBBLE_PACKET(h2c_pkt)                         \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_BUBBLE_PACKET(h2c_pkt, value)                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define AOAC_RSVD_PAGE2_GET_LOC_TEREDO_INFO(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_TEREDO_INFO(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define AOAC_RSVD_PAGE2_GET_LOC_REALWOW_INFO(h2c_pkt)                          \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 0, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_REALWOW_INFO(h2c_pkt, value)                   \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 0, 8, value)
+#define AOAC_RSVD_PAGE2_GET_LOC_KEEP_ALIVE_PKT(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 8, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_KEEP_ALIVE_PKT(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 8, 8, value)
+#define AOAC_RSVD_PAGE2_GET_LOC_ACK_PATTERN(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 16, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_ACK_PATTERN(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 16, 8, value)
+#define AOAC_RSVD_PAGE2_GET_LOC_WAKEUP_PATTERN(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X04, 24, 8)
+#define AOAC_RSVD_PAGE2_SET_LOC_WAKEUP_PATTERN(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 24, 8, value)
+#define D0_SCAN_OFFLOAD_INFO_GET_CMD_ID(h2c_pkt)                               \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define D0_SCAN_OFFLOAD_INFO_SET_CMD_ID(h2c_pkt, value)                        \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define D0_SCAN_OFFLOAD_INFO_GET_CLASS(h2c_pkt)                                \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define D0_SCAN_OFFLOAD_INFO_SET_CLASS(h2c_pkt, value)                         \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define D0_SCAN_OFFLOAD_INFO_GET_LOC_CHANNEL_INFO(h2c_pkt)                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define D0_SCAN_OFFLOAD_INFO_SET_LOC_CHANNEL_INFO(h2c_pkt, value)              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_CMD_ID(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define CHANNEL_SWITCH_OFFLOAD_SET_CMD_ID(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_CLASS(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define CHANNEL_SWITCH_OFFLOAD_SET_CLASS(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_CHANNEL_NUM(h2c_pkt)                        \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define CHANNEL_SWITCH_OFFLOAD_SET_CHANNEL_NUM(h2c_pkt, value)                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_EN_RFE(h2c_pkt)                             \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define CHANNEL_SWITCH_OFFLOAD_SET_EN_RFE(h2c_pkt, value)                      \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define CHANNEL_SWITCH_OFFLOAD_GET_RFE_TYPE(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 24, 8)
+#define CHANNEL_SWITCH_OFFLOAD_SET_RFE_TYPE(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 24, 8, value)
+#define AOAC_RSVD_PAGE3_GET_CMD_ID(h2c_pkt)                                    \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define AOAC_RSVD_PAGE3_SET_CMD_ID(h2c_pkt, value)                             \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define AOAC_RSVD_PAGE3_GET_CLASS(h2c_pkt)                                     \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define AOAC_RSVD_PAGE3_SET_CLASS(h2c_pkt, value)                              \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define AOAC_RSVD_PAGE3_GET_LOC_NLO_INFO(h2c_pkt)                              \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 8)
+#define AOAC_RSVD_PAGE3_SET_LOC_NLO_INFO(h2c_pkt, value)                       \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 8, value)
+#define AOAC_RSVD_PAGE3_GET_LOC_AOAC_REPORT(h2c_pkt)                           \
+	LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 16, 8)
+#define AOAC_RSVD_PAGE3_SET_LOC_AOAC_REPORT(h2c_pkt, value)                    \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 16, 8, value)
+#define DBG_MSG_CTRL_GET_CMD_ID(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 0, 5)
+#define DBG_MSG_CTRL_SET_CMD_ID(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 0, 5, value)
+#define DBG_MSG_CTRL_GET_CLASS(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 5, 3)
+#define DBG_MSG_CTRL_SET_CLASS(h2c_pkt, value)                                 \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 5, 3, value)
+#define DBG_MSG_CTRL_GET_FUN_EN(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 8, 1)
+#define DBG_MSG_CTRL_SET_FUN_EN(h2c_pkt, value)                                \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 8, 1, value)
+#define DBG_MSG_CTRL_GET_MODE(h2c_pkt) LE_BITS_TO_4BYTE(h2c_pkt + 0X00, 12, 4)
+#define DBG_MSG_CTRL_SET_MODE(h2c_pkt, value)                                  \
+	SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X00, 12, 4, value)
+#endif
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 14/17] rtlwifi: halmac: add bus interface commands
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (11 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 13/17] rtlwifi: halmac: add firmware related functions and definitions pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 15/17] rtlwifi: halmac: add to control WiFi mac functions and registers pkshih
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

The halmac supports three buses interfaces, PCI, USB and SDIO, and this
commit makes it possible to change their phy parameters.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../halmac_88xx/halmac_8822b/halmac_pcie_8822b.c   | 218 +++++
 .../halmac_88xx/halmac_8822b/halmac_pcie_8822b.h   |  38 +
 .../halmac_88xx/halmac_8822b/halmac_phy_8822b.c    | 148 ++++
 .../halmac_88xx/halmac_8822b/halmac_sdio_8822b.c   | 880 ++++++++++++++++++++
 .../halmac_88xx/halmac_8822b/halmac_sdio_8822b.h   |  62 ++
 .../halmac_88xx/halmac_8822b/halmac_usb_8822b.c    | 161 ++++
 .../halmac_88xx/halmac_8822b/halmac_usb_8822b.h    |  38 +
 .../rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.c  | 538 +++++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.h  |  98 +++
 .../rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.c  | 895 +++++++++++++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.h  |  75 ++
 .../rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.c   | 522 ++++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.h   |  83 ++
 .../realtek/rtlwifi/halmac/halmac_intf_phy_cmd.h   |  45 ++
 .../realtek/rtlwifi/halmac/halmac_pcie_reg.h       |  36 +
 .../realtek/rtlwifi/halmac/halmac_sdio_reg.h       |  53 ++
 .../realtek/rtlwifi/halmac/halmac_usb_reg.h        |  19 +
 17 files changed, 3909 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_intf_phy_cmd.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pcie_reg.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_sdio_reg.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_usb_reg.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.c
new file mode 100644
index 000000000000..88a148e528a5
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.c
@@ -0,0 +1,218 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_pcie_8822b.h"
+#include "halmac_pwr_seq_8822b.h"
+#include "../halmac_init_88xx.h"
+#include "../halmac_common_88xx.h"
+#include "../halmac_pcie_88xx.h"
+#include "../halmac_88xx_cfg.h"
+
+/**
+ * mac_pwr_switch_pcie_8822b() - switch mac power
+ * @adapter : the adapter of halmac
+ * @pwr : power state
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+mac_pwr_switch_pcie_8822b(struct halmac_adapter *adapter,
+			  enum halmac_mac_power pwr)
+{
+	u8 value8;
+	u8 rpwm;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "pwr = %x\n",
+		 pwr);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "8822B pwr seq ver = %s\n", HALMAC_8822B_PWR_SEQ_VER);
+
+	adapter->rpwm = HALMAC_REG_R8(REG_PCIE_HRPWM1_V1);
+
+	/* Check FW still exist or not */
+	if (HALMAC_REG_R16(REG_MCUFW_CTRL) == 0xC078) {
+		/* Leave 32K */
+		rpwm = (u8)((adapter->rpwm ^ BIT(7)) & 0x80);
+		HALMAC_REG_W8(REG_PCIE_HRPWM1_V1, rpwm);
+	}
+
+	value8 = HALMAC_REG_R8(REG_CR);
+	if (value8 == 0xEA)
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_OFF;
+	else
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_ON;
+
+	/* Check if power switch is needed */
+	if (pwr == HALMAC_MAC_POWER_ON &&
+	    adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_ON) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "power state unchange!!\n");
+		return HALMAC_RET_PWR_UNCHANGE;
+	}
+
+	if (pwr == HALMAC_MAC_POWER_OFF) {
+		status = trxdma_check_idle_88xx(adapter);
+		if (status != HALMAC_RET_SUCCESS)
+			return status;
+		if (pwr_seq_parser_88xx(adapter, card_dis_flow_8822b) !=
+		    HALMAC_RET_SUCCESS) {
+			pr_err("Handle power off cmd error\n");
+			return HALMAC_RET_POWER_OFF_FAIL;
+		}
+
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_OFF;
+		adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
+		init_adapter_dynamic_param_88xx(adapter);
+	} else {
+		if (pwr_seq_parser_88xx(adapter, card_en_flow_8822b) !=
+		    HALMAC_RET_SUCCESS) {
+			pr_err("Handle power on cmd error\n");
+			return HALMAC_RET_POWER_ON_FAIL;
+		}
+
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_ON;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_pcie_switch_8822b() - pcie gen1/gen2 switch
+ * @adapter : the adapter of halmac
+ * @cfg : gen1/gen2 selection
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pcie_switch_8822b(struct halmac_adapter *adapter, enum halmac_pcie_cfg cfg)
+{
+	u8 value8;
+	u32 value32;
+	u8 speed = 0;
+	u32 cnt = 0;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (cfg == HALMAC_PCIE_GEN1) {
+		value8 = dbi_r8_88xx(adapter, LINK_CTRL2_REG_OFFSET) & 0xF0;
+		dbi_w8_88xx(adapter, LINK_CTRL2_REG_OFFSET, value8 | BIT(0));
+
+		value32 = dbi_r32_88xx(adapter, GEN2_CTRL_OFFSET);
+		dbi_w32_88xx(adapter, GEN2_CTRL_OFFSET, value32 | BIT(17));
+
+		speed = dbi_r8_88xx(adapter, LINK_STATUS_REG_OFFSET) & 0x0F;
+		cnt = 2000;
+
+		while ((speed != PCIE_GEN1_SPEED) && (cnt != 0)) {
+			usleep_range(50, 60);
+			speed = dbi_r8_88xx(adapter, LINK_STATUS_REG_OFFSET);
+			speed &= 0x0F;
+			cnt--;
+		}
+
+		if (speed != PCIE_GEN1_SPEED) {
+			pr_err("Speed change to GEN1 fail !\n");
+			return HALMAC_RET_FAIL;
+		}
+
+	} else if (cfg == HALMAC_PCIE_GEN2) {
+		value8 = dbi_r8_88xx(adapter, LINK_CTRL2_REG_OFFSET) & 0xF0;
+		dbi_w8_88xx(adapter, LINK_CTRL2_REG_OFFSET, value8 | BIT(1));
+
+		value32 = dbi_r32_88xx(adapter, GEN2_CTRL_OFFSET);
+		dbi_w32_88xx(adapter, GEN2_CTRL_OFFSET, value32 | BIT(17));
+
+		speed = dbi_r8_88xx(adapter, LINK_STATUS_REG_OFFSET) & 0x0F;
+		cnt = 2000;
+
+		while ((speed != PCIE_GEN2_SPEED) && (cnt != 0)) {
+			usleep_range(50, 60);
+			speed = dbi_r8_88xx(adapter, LINK_STATUS_REG_OFFSET);
+			speed &= 0x0F;
+			cnt--;
+		}
+
+		if (speed != PCIE_GEN2_SPEED) {
+			pr_err("Speed change to GEN1 fail !\n");
+			return HALMAC_RET_FAIL;
+		}
+
+	} else {
+		pr_err("Error Speed !\n");
+		return HALMAC_RET_FAIL;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * phy_cfg_pcie_8822b() - phy config
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+phy_cfg_pcie_8822b(struct halmac_adapter *adapter,
+		   enum halmac_intf_phy_platform pltfm)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = parse_intf_phy_88xx(adapter, pcie_gen1_phy_param_8822b, pltfm,
+				     HAL_INTF_PHY_PCIE_GEN1);
+
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	status = parse_intf_phy_88xx(adapter, pcie_gen2_phy_param_8822b, pltfm,
+				     HAL_INTF_PHY_PCIE_GEN2);
+
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * intf_tun_pcie_8822b() - pcie interface fine tuning
+ * @adapter : the adapter of halmac
+ * Author : Rick Liu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+intf_tun_pcie_8822b(struct halmac_adapter *adapter)
+{
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.h
new file mode 100644
index 000000000000..6616f53df7a8
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_pcie_8822b.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_API_8822B_PCIE_H_
+#define _HALMAC_API_8822B_PCIE_H_
+
+#include "../../halmac_api.h"
+
+extern struct halmac_intf_phy_para pcie_gen1_phy_param_8822b[];
+extern struct halmac_intf_phy_para pcie_gen2_phy_param_8822b[];
+
+enum halmac_ret_status
+mac_pwr_switch_pcie_8822b(struct halmac_adapter *adapter,
+			  enum halmac_mac_power pwr);
+
+enum halmac_ret_status
+pcie_switch_8822b(struct halmac_adapter *adapter, enum halmac_pcie_cfg cfg);
+
+enum halmac_ret_status
+phy_cfg_pcie_8822b(struct halmac_adapter *adapter,
+		   enum halmac_intf_phy_platform pltfm);
+
+enum halmac_ret_status
+intf_tun_pcie_8822b(struct halmac_adapter *adapter);
+
+#endif/* _HALMAC_API_8822B_PCIE_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c
new file mode 100644
index 000000000000..3d5db54c6f26
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_phy_8822b.c
@@ -0,0 +1,148 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "../../halmac_type.h"
+#include "halmac_usb_8822b.h"
+#include "halmac_pcie_8822b.h"
+
+/**
+ * ============ip sel item list============
+ * HALMAC_IP_INTF_PHY
+ *	USB2 : usb2 phy, 1byte value
+ *	USB3 : usb3 phy, 2byte value
+ *	PCIE1 : pcie gen1 mdio, 2byte value
+ *	PCIE2 : pcie gen2 mdio, 2byte value
+ * HALMAC_IP_SEL_MAC
+ *	USB2, USB3, PCIE1, PCIE2 : mac ip, 1byte value
+ * HALMAC_IP_PCIE_DBI
+ *	USB2 USB3 : none
+ *	PCIE1, PCIE2 : pcie dbi, 1byte value
+ */
+
+struct halmac_intf_phy_para usb2_phy_param_8822b[] = {
+	/* {offset, value, ip sel, cut mask, platform mask} */
+	{0xFFFF, 0x00,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_ALL,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+};
+
+struct halmac_intf_phy_para usb3_phy_param_8822b[] = {
+	/* {offset, value, ip sel, cut mask, platform mask} */
+	{0x0001, 0xA841,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_D,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0xFFFF, 0x0000,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_ALL,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+};
+
+struct halmac_intf_phy_para pcie_gen1_phy_param_8822b[] = {
+	/* {offset, value, ip sel, cut mask, platform mask} */
+	{0x0001, 0xA841,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0002, 0x60C6,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0008, 0x3596,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0009, 0x321C,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x000A, 0x9623,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0020, 0x94FF,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0021, 0xFFCF,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0026, 0xC006,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0029, 0xFF0E,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x002A, 0x1840,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0xFFFF, 0x0000,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_ALL,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+};
+
+struct halmac_intf_phy_para pcie_gen2_phy_param_8822b[] = {
+	/* {offset, value, ip sel, cut mask, platform mask} */
+	{0x0001, 0xA841,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0002, 0x60C6,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0008, 0x3597,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0009, 0x321C,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x000A, 0x9623,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0020, 0x94FF,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0021, 0xFFCF,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0026, 0xC006,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x0029, 0xFF0E,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0x002A, 0x3040,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_C,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+	{0xFFFF, 0x0000,
+	 HALMAC_IP_INTF_PHY,
+	 HALMAC_INTF_PHY_CUT_ALL,
+	 HALMAC_INTF_PHY_PLATFORM_ALL},
+};
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.c
new file mode 100644
index 000000000000..e014f02e30cd
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.c
@@ -0,0 +1,880 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_sdio_8822b.h"
+#include "halmac_pwr_seq_8822b.h"
+#include "../halmac_init_88xx.h"
+#include "../halmac_common_88xx.h"
+#include "../halmac_sdio_88xx.h"
+
+#define WLAN_ACQ_NUM_MAX	8
+
+static enum halmac_ret_status
+chk_oqt_8822b(struct halmac_adapter *adapter, u32 tx_agg_num, u8 *buf,
+	      u8 macid_cnt);
+
+static enum halmac_ret_status
+update_oqt_free_space_8822b(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+update_sdio_free_page_8822b(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+chk_qsel_8822b(struct halmac_adapter *adapter, u8 qsel_first, u8 *pkt,
+	       u8 *macid_cnt);
+
+static enum halmac_ret_status
+chk_dma_mapping_8822b(struct halmac_adapter *adapter, u16 **cur_fs,
+		      u8 qsel_first);
+
+static enum halmac_ret_status
+chk_rqd_page_num_8822b(struct halmac_adapter *adapter, u8 *buf, u32 *rqd_pg_num,
+		       u16 **cur_fs, u8 *macid_cnt, u32 tx_agg_num);
+
+/**
+ * mac_pwr_switch_sdio_8822b() - switch mac power
+ * @adapter : the adapter of halmac
+ * @pwr : power state
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+mac_pwr_switch_sdio_8822b(struct halmac_adapter *adapter,
+			  enum halmac_mac_power pwr)
+{
+	u8 value8;
+	u8 rpwm;
+	u32 imr_backup;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "8822B pwr seq ver = %s\n", HALMAC_8822B_PWR_SEQ_VER);
+
+	adapter->rpwm = HALMAC_REG_R8(REG_SDIO_HRPWM1);
+
+	/* Check FW still exist or not */
+	if (HALMAC_REG_R16(REG_MCUFW_CTRL) == 0xC078) {
+		/* Leave 32K */
+		rpwm = (u8)((adapter->rpwm ^ BIT(7)) & 0x80);
+		HALMAC_REG_W8(REG_SDIO_HRPWM1, rpwm);
+	}
+
+	value8 = HALMAC_REG_R8(REG_CR);
+	if (value8 == 0xEA)
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_OFF;
+	else
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_ON;
+
+	/*Check if power switch is needed*/
+	if (pwr == HALMAC_MAC_POWER_ON &&
+	    adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_ON) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "power state unchange!!\n");
+		return HALMAC_RET_PWR_UNCHANGE;
+	}
+
+	imr_backup = HALMAC_REG_R32(REG_SDIO_HIMR);
+	HALMAC_REG_W32(REG_SDIO_HIMR, 0);
+
+	if (pwr == HALMAC_MAC_POWER_OFF) {
+		adapter->pwr_off_flow_flag = 1;
+		if (pwr_seq_parser_88xx(adapter, card_dis_flow_8822b) !=
+		    HALMAC_RET_SUCCESS) {
+			pr_err("Handle power off cmd error\n");
+			HALMAC_REG_W32(REG_SDIO_HIMR, imr_backup);
+			return HALMAC_RET_POWER_OFF_FAIL;
+		}
+
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_OFF;
+		adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
+		adapter->pwr_off_flow_flag = 0;
+		init_adapter_dynamic_param_88xx(adapter);
+	} else {
+		if (pwr_seq_parser_88xx(adapter, card_en_flow_8822b) !=
+		    HALMAC_RET_SUCCESS) {
+			pr_err("Handle power on cmd error\n");
+			HALMAC_REG_W32(REG_SDIO_HIMR, imr_backup);
+			return HALMAC_RET_POWER_ON_FAIL;
+		}
+
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_ON;
+	}
+
+	HALMAC_REG_W32(REG_SDIO_HIMR, imr_backup);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_tx_allowed_sdio_88xx() - check tx status
+ * @adapter : the adapter of halmac
+ * @buf : tx packet, include txdesc
+ * @size : tx packet size, include txdesc
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+tx_allowed_sdio_8822b(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u16 *cur_fs = NULL;
+	u32 cnt;
+	u32 tx_agg_num;
+	u32 rqd_pg_num = 0;
+	u8 macid_cnt = 0;
+	struct halmac_sdio_free_space *fs_info = &adapter->sdio_fs;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_qsel qsel;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (!fs_info->macid_map) {
+		pr_err("halmac allocate Macid_map Fail!!\n");
+		return HALMAC_RET_MALLOC_FAIL;
+	}
+
+	memset(fs_info->macid_map, 0x00, fs_info->macid_map_size);
+
+	tx_agg_num = GET_TX_DESC_DMA_TXAGG_NUM(buf);
+	tx_agg_num = (tx_agg_num == 0) ? 1 : tx_agg_num;
+
+	status = chk_rqd_page_num_8822b(adapter, buf, &rqd_pg_num, &cur_fs,
+					&macid_cnt, tx_agg_num);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	qsel = (enum halmac_qsel)GET_TX_DESC_QSEL(buf);
+	if (qsel == HALMAC_QSEL_BCN || qsel == HALMAC_QSEL_CMD)
+		return HALMAC_RET_SUCCESS;
+
+	cnt = 10;
+	do {
+		if ((u32)(*cur_fs + fs_info->pubq_pg_num) > rqd_pg_num) {
+			status = chk_oqt_8822b(adapter, tx_agg_num, buf,
+					       macid_cnt);
+			if (status != HALMAC_RET_SUCCESS) {
+				RT_TRACE(adapter->drv_adapter, COMP_HALMAC,
+					 DBG_WARNING, "oqt buffer full!!\n");
+				return status;
+			}
+
+			if (*cur_fs >= rqd_pg_num) {
+				*cur_fs -= (u16)rqd_pg_num;
+			} else {
+				fs_info->pubq_pg_num -=
+						(u16)(rqd_pg_num - *cur_fs);
+				*cur_fs = 0;
+			}
+
+			break;
+		}
+
+		update_sdio_free_page_8822b(adapter);
+
+		cnt--;
+		if (cnt == 0)
+			return HALMAC_RET_FREE_SPACE_NOT_ENOUGH;
+	} while (1);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_8_sdio_88xx() - read 1byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u8
+reg_r8_sdio_8822b(struct halmac_adapter *adapter, u32 offset)
+{
+	u8 value8;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if ((offset & 0xFFFF0000) == 0) {
+		value8 = (u8)r_indir_sdio_88xx(adapter, offset, HALMAC_IO_BYTE);
+	} else {
+		status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("convert offset\n");
+			return status;
+		}
+		value8 = PLTFM_SDIO_CMD52_R(offset);
+	}
+
+	return value8;
+}
+
+/**
+ * halmac_reg_write_8_sdio_88xx() - write 1byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w8_sdio_8822b(struct halmac_adapter *adapter, u32 offset, u8 value)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if ((offset & 0xFFFF0000) == 0)
+		offset |= WLAN_IOREG_OFFSET;
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("convert offset\n");
+		return status;
+	}
+
+	PLTFM_SDIO_CMD52_W(offset, value);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_reg_read_16_sdio_88xx() - read 2byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u16
+reg_r16_sdio_8822b(struct halmac_adapter *adapter, u32 offset)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	union {
+		__le16 word;
+		u8 byte[2];
+	} value16 = { 0x0000 };
+
+	if ((offset & 0xFFFF0000) == 0)
+		return (u16)r_indir_sdio_88xx(adapter, offset, HALMAC_IO_WORD);
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("convert offset\n");
+		return status;
+	}
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF ||
+	    ((offset & (2 - 1)) != 0) ||
+	    adapter->sdio_cmd53_4byte == HALMAC_SDIO_CMD53_4BYTE_MODE_RW ||
+	    adapter->sdio_cmd53_4byte == HALMAC_SDIO_CMD53_4BYTE_MODE_R) {
+		value16.byte[0] = PLTFM_SDIO_CMD52_R(offset);
+		value16.byte[1] = PLTFM_SDIO_CMD52_R(offset + 1);
+
+		return le16_to_cpu(value16.word);
+	}
+
+	return PLTFM_SDIO_CMD53_R16(offset);
+}
+
+/**
+ * halmac_reg_write_16_sdio_88xx() - write 2byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w16_sdio_8822b(struct halmac_adapter *adapter, u32 offset, u16 value)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF ||
+	    ((offset & (2 - 1)) != 0) ||
+	    adapter->sdio_cmd53_4byte == HALMAC_SDIO_CMD53_4BYTE_MODE_RW ||
+	    adapter->sdio_cmd53_4byte == HALMAC_SDIO_CMD53_4BYTE_MODE_W) {
+		if ((offset & 0xFFFF0000) == 0 && ((offset & (2 - 1)) == 0)) {
+			status = w_indir_sdio_88xx(adapter, offset, value,
+						   HALMAC_IO_WORD);
+		} else {
+			if ((offset & 0xFFFF0000) == 0)
+				offset |= WLAN_IOREG_OFFSET;
+
+			status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+			if (status != HALMAC_RET_SUCCESS) {
+				pr_err("convert offset\n");
+				return status;
+			}
+			PLTFM_SDIO_CMD52_W(offset, (u8)(value & 0xFF));
+			PLTFM_SDIO_CMD52_W(offset + 1,
+					   (u8)((value & 0xFF00) >> 8));
+		}
+	} else {
+		if ((offset & 0xFFFF0000) == 0)
+			offset |= WLAN_IOREG_OFFSET;
+
+		status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("convert offset\n");
+			return status;
+		}
+
+		PLTFM_SDIO_CMD53_W16(offset, value);
+	}
+	return status;
+}
+
+/**
+ * halmac_reg_read_32_sdio_88xx() - read 4byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32
+reg_r32_sdio_8822b(struct halmac_adapter *adapter, u32 offset)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	union {
+		__le32 dword;
+		u8 byte[4];
+	} value32 = { 0x00000000 };
+
+	if ((offset & 0xFFFF0000) == 0)
+		return r_indir_sdio_88xx(adapter, offset, HALMAC_IO_DWORD);
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("convert offset\n");
+		return status;
+	}
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF ||
+	    (offset & (4 - 1)) != 0) {
+		value32.byte[0] = PLTFM_SDIO_CMD52_R(offset);
+		value32.byte[1] = PLTFM_SDIO_CMD52_R(offset + 1);
+		value32.byte[2] = PLTFM_SDIO_CMD52_R(offset + 2);
+		value32.byte[3] = PLTFM_SDIO_CMD52_R(offset + 3);
+
+		return le32_to_cpu(value32.dword);
+	}
+
+	return PLTFM_SDIO_CMD53_R32(offset);
+}
+
+/**
+ * halmac_reg_write_32_sdio_88xx() - write 4byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w32_sdio_8822b(struct halmac_adapter *adapter, u32 offset, u32 value)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF ||
+	    (offset & (4 - 1)) !=  0) {
+		if ((offset & 0xFFFF0000) == 0 && ((offset & (4 - 1)) == 0)) {
+			status = w_indir_sdio_88xx(adapter, offset, value,
+						   HALMAC_IO_DWORD);
+		} else {
+			if ((offset & 0xFFFF0000) == 0)
+				offset |= WLAN_IOREG_OFFSET;
+
+			status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+			if (status != HALMAC_RET_SUCCESS) {
+				pr_err("convert offset\n");
+				return status;
+			}
+			PLTFM_SDIO_CMD52_W(offset, (u8)(value & 0xFF));
+			PLTFM_SDIO_CMD52_W(offset + 1,
+					   (u8)((value >> 8) & 0xFF));
+			PLTFM_SDIO_CMD52_W(offset + 2,
+					   (u8)((value >> 16) & 0xFF));
+			PLTFM_SDIO_CMD52_W(offset + 3,
+					   (u8)((value >> 24) & 0xFF));
+		}
+	} else {
+		if ((offset & 0xFFFF0000) == 0)
+			offset |= WLAN_IOREG_OFFSET;
+
+		status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("convert offset\n");
+			return status;
+		}
+		PLTFM_SDIO_CMD53_W32(offset, value);
+	}
+
+	return status;
+}
+
+static enum halmac_ret_status
+chk_oqt_8822b(struct halmac_adapter *adapter, u32 tx_agg_num, u8 *buf,
+	      u8 macid_cnt)
+{
+	u32 cnt = 10;
+	struct halmac_sdio_free_space *fs_info = &adapter->sdio_fs;
+
+	/*S0, S1 are not allowed to use, 0x4E4[0] should be 0. Soar 20160323*/
+	/*no need to check non_ac_oqt_number*/
+	/*HI and MGQ blocked will cause protocal issue before H_OQT being full*/
+	switch ((enum halmac_qsel)GET_TX_DESC_QSEL(buf)) {
+	case HALMAC_QSEL_VO:
+	case HALMAC_QSEL_VO_V2:
+	case HALMAC_QSEL_VI:
+	case HALMAC_QSEL_VI_V2:
+	case HALMAC_QSEL_BE:
+	case HALMAC_QSEL_BE_V2:
+	case HALMAC_QSEL_BK:
+	case HALMAC_QSEL_BK_V2:
+		if (macid_cnt > WLAN_ACQ_NUM_MAX &&
+		    tx_agg_num > OQT_ENTRY_AC_8822B) {
+			RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+				 "txagg num %d > oqt entry\n", tx_agg_num);
+			RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+				 "macid cnt %d > acq max\n", macid_cnt);
+		}
+
+		cnt = 10;
+		do {
+			if (fs_info->ac_empty >= macid_cnt) {
+				fs_info->ac_empty -= macid_cnt;
+				break;
+			}
+
+			if (fs_info->ac_oqt_num >= tx_agg_num) {
+				fs_info->ac_empty = 0;
+				fs_info->ac_oqt_num -= (u8)tx_agg_num;
+				break;
+			}
+
+			update_oqt_free_space_8822b(adapter);
+
+			cnt--;
+			if (cnt == 0)
+				return HALMAC_RET_OQT_NOT_ENOUGH;
+		} while (1);
+		break;
+	case HALMAC_QSEL_MGNT:
+	case HALMAC_QSEL_HIGH:
+		if (tx_agg_num > OQT_ENTRY_NOAC_8822B)
+			RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+				 "tx_agg_num %d > oqt entry\n", tx_agg_num);
+
+		cnt = 10;
+		do {
+			if (fs_info->non_ac_oqt_num >= tx_agg_num) {
+				fs_info->non_ac_oqt_num -= (u8)tx_agg_num;
+				break;
+			}
+
+			update_oqt_free_space_8822b(adapter);
+
+			cnt--;
+			if (cnt == 0)
+				return HALMAC_RET_OQT_NOT_ENOUGH;
+		} while (1);
+		break;
+	default:
+		break;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+update_oqt_free_space_8822b(struct halmac_adapter *adapter)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	struct halmac_sdio_free_space *fs_info = &adapter->sdio_fs;
+	u8 value;
+	u32 oqt_free_page;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	oqt_free_page = HALMAC_REG_R32(REG_SDIO_OQT_FREE_TXPG_V1);
+	fs_info->ac_oqt_num = (u8)BIT_GET_AC_OQT_FREEPG_V1(oqt_free_page);
+	fs_info->non_ac_oqt_num = (u8)BIT_GET_NOAC_OQT_FREEPG_V1(oqt_free_page);
+	fs_info->ac_empty = 0;
+	if (fs_info->ac_oqt_num == OQT_ENTRY_AC_8822B) {
+		value = HALMAC_REG_R8(REG_TXPKT_EMPTY);
+		while (value > 0) {
+			value = value & (value - 1);
+			fs_info->ac_empty++;
+		};
+	} else {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "free_space->ac_oqt_num %d != %d\n",
+			 fs_info->ac_oqt_num, OQT_ENTRY_AC_8822B);
+	}
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+update_sdio_free_page_8822b(struct halmac_adapter *adapter)
+{
+	u32 free_page = 0;
+	u32 free_page2 = 0;
+	u32 free_page3 = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	struct halmac_sdio_free_space *fs_info = &adapter->sdio_fs;
+	u8 data[12] = {0};
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	HALMAC_REG_SDIO_RN(REG_SDIO_FREE_TXPG, 12, data);
+
+	free_page = le32_to_cpu(*(__le32 *)(data + 0));
+	free_page2 = le32_to_cpu(*(__le32 *)(data + 4));
+	free_page3 = le32_to_cpu(*(__le32 *)(data + 8));
+
+	fs_info->hiq_pg_num = (u16)BIT_GET_HIQ_FREEPG_V1(free_page);
+	fs_info->miq_pg_num = (u16)BIT_GET_MID_FREEPG_V1(free_page);
+	fs_info->lowq_pg_num = (u16)BIT_GET_LOW_FREEPG_V1(free_page2);
+	fs_info->pubq_pg_num = (u16)BIT_GET_PUB_FREEPG_V1(free_page2);
+	fs_info->exq_pg_num = (u16)BIT_GET_EXQ_FREEPG_V1(free_page3);
+	fs_info->ac_oqt_num = (u8)BIT_GET_AC_OQT_FREEPG_V1(free_page3);
+	fs_info->non_ac_oqt_num = (u8)BIT_GET_NOAC_OQT_FREEPG_V1(free_page3);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * phy_cfg_sdio_8822b() - phy config
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+phy_cfg_sdio_8822b(struct halmac_adapter *adapter,
+		   enum halmac_intf_phy_platform pltfm)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_pcie_switch_8821c() - pcie gen1/gen2 switch
+ * @adapter : the adapter of halmac
+ * @cfg : gen1/gen2 selection
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pcie_switch_sdio_8822b(struct halmac_adapter *adapter,
+		       enum halmac_pcie_cfg cfg)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * intf_tun_sdio_8822b() - sdio interface fine tuning
+ * @adapter : the adapter of halmac
+ * Author : Ivan
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+intf_tun_sdio_8822b(struct halmac_adapter *adapter)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_get_sdio_tx_addr_sdio_88xx() - get CMD53 addr for the TX packet
+ * @adapter : the adapter of halmac
+ * @buf : tx packet, include txdesc
+ * @size : tx packet size
+ * @cmd53_addr : cmd53 addr value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_sdio_tx_addr_8822b(struct halmac_adapter *adapter, u8 *buf, u32 size,
+		       u32 *cmd53_addr)
+{
+	u32 len_unit4;
+	enum halmac_qsel queue_sel;
+	enum halmac_dma_mapping dma_mapping;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (!buf) {
+		pr_err("buf is NULL!!\n");
+		return HALMAC_RET_DATA_BUF_NULL;
+	}
+
+	if (size == 0) {
+		pr_err("size is 0!!\n");
+		return HALMAC_RET_DATA_SIZE_INCORRECT;
+	}
+
+	queue_sel = (enum halmac_qsel)GET_TX_DESC_QSEL(buf);
+
+	switch (queue_sel) {
+	case HALMAC_QSEL_VO:
+	case HALMAC_QSEL_VO_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_VO];
+		break;
+	case HALMAC_QSEL_VI:
+	case HALMAC_QSEL_VI_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_VI];
+		break;
+	case HALMAC_QSEL_BE:
+	case HALMAC_QSEL_BE_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_BE];
+		break;
+	case HALMAC_QSEL_BK:
+	case HALMAC_QSEL_BK_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_BK];
+		break;
+	case HALMAC_QSEL_MGNT:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_MG];
+		break;
+	case HALMAC_QSEL_HIGH:
+	case HALMAC_QSEL_BCN:
+	case HALMAC_QSEL_CMD:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_HI];
+		break;
+	default:
+		pr_err("Qsel is out of range\n");
+		return HALMAC_RET_QSEL_INCORRECT;
+	}
+
+	len_unit4 = (size >> 2) + ((size & (4 - 1)) ? 1 : 0);
+
+	switch (dma_mapping) {
+	case HALMAC_DMA_MAPPING_HIGH:
+		*cmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_HIGH;
+		break;
+	case HALMAC_DMA_MAPPING_NORMAL:
+		*cmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_NORMAL;
+		break;
+	case HALMAC_DMA_MAPPING_LOW:
+		*cmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_LOW;
+		break;
+	case HALMAC_DMA_MAPPING_EXTRA:
+		*cmd53_addr = HALMAC_SDIO_CMD_ADDR_TXFF_EXTRA;
+		break;
+	default:
+		pr_err("DmaMapping is out of range\n");
+		return HALMAC_RET_DMA_MAP_INCORRECT;
+	}
+
+	*cmd53_addr = (*cmd53_addr << 13) |
+				(len_unit4 & HALMAC_SDIO_4BYTE_LEN_MASK);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+chk_qsel_8822b(struct halmac_adapter *adapter, u8 qsel_first, u8 *pkt,
+	       u8 *macid_cnt)
+{
+	u8 flag = 0;
+	u8 qsel_now;
+	u8 macid;
+	struct halmac_sdio_free_space *fs_info = &adapter->sdio_fs;
+
+	macid = (u8)GET_TX_DESC_MACID(pkt);
+	qsel_now = (u8)GET_TX_DESC_QSEL(pkt);
+	if (qsel_first == qsel_now) {
+		if (*(fs_info->macid_map + macid) == 0) {
+			*(fs_info->macid_map + macid) = 1;
+			(*macid_cnt)++;
+		}
+	} else {
+		switch ((enum halmac_qsel)qsel_now) {
+		case HALMAC_QSEL_VO:
+			if ((enum halmac_qsel)qsel_first != HALMAC_QSEL_VO_V2)
+				flag = 1;
+			break;
+		case HALMAC_QSEL_VO_V2:
+			if ((enum halmac_qsel)qsel_first != HALMAC_QSEL_VO)
+				flag = 1;
+			break;
+		case HALMAC_QSEL_VI:
+			if ((enum halmac_qsel)qsel_first != HALMAC_QSEL_VI_V2)
+				flag = 1;
+			break;
+		case HALMAC_QSEL_VI_V2:
+			if ((enum halmac_qsel)qsel_first != HALMAC_QSEL_VI)
+				flag = 1;
+			break;
+		case HALMAC_QSEL_BE:
+			if ((enum halmac_qsel)qsel_first != HALMAC_QSEL_BE_V2)
+				flag = 1;
+			break;
+		case HALMAC_QSEL_BE_V2:
+			if ((enum halmac_qsel)qsel_first != HALMAC_QSEL_BE)
+				flag = 1;
+			break;
+		case HALMAC_QSEL_BK:
+			if ((enum halmac_qsel)qsel_first != HALMAC_QSEL_BK_V2)
+				flag = 1;
+			break;
+		case HALMAC_QSEL_BK_V2:
+			if ((enum halmac_qsel)qsel_first != HALMAC_QSEL_BK)
+				flag = 1;
+			break;
+		case HALMAC_QSEL_MGNT:
+		case HALMAC_QSEL_HIGH:
+		case HALMAC_QSEL_BCN:
+		case HALMAC_QSEL_CMD:
+			flag = 1;
+			break;
+		default:
+			pr_err("Qsel is out of range\n");
+			return HALMAC_RET_QSEL_INCORRECT;
+		}
+		if (flag == 1) {
+			pr_err("Multi-Qsel is not allowed\n");
+			pr_err("qsel = %d, %d\n", qsel_first, qsel_now);
+			return HALMAC_RET_QSEL_INCORRECT;
+		}
+		if (*(fs_info->macid_map + macid + MACID_MAX_8822B) == 0) {
+			*(fs_info->macid_map + macid + MACID_MAX_8822B) = 1;
+			(*macid_cnt)++;
+		}
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+chk_dma_mapping_8822b(struct halmac_adapter *adapter, u16 **cur_fs,
+		      u8 qsel_first)
+{
+	enum halmac_dma_mapping dma_mapping;
+
+	switch ((enum halmac_qsel)qsel_first) {
+	case HALMAC_QSEL_VO:
+	case HALMAC_QSEL_VO_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_VO];
+		break;
+	case HALMAC_QSEL_VI:
+	case HALMAC_QSEL_VI_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_VI];
+		break;
+	case HALMAC_QSEL_BE:
+	case HALMAC_QSEL_BE_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_BE];
+		break;
+	case HALMAC_QSEL_BK:
+	case HALMAC_QSEL_BK_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_BK];
+		break;
+	case HALMAC_QSEL_MGNT:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_MG];
+		break;
+	case HALMAC_QSEL_HIGH:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_HI];
+		break;
+	case HALMAC_QSEL_BCN:
+	case HALMAC_QSEL_CMD:
+		*cur_fs = &adapter->sdio_fs.hiq_pg_num;
+		return HALMAC_RET_SUCCESS;
+	default:
+		pr_err("Qsel is out of range: %d\n", qsel_first);
+		return HALMAC_RET_QSEL_INCORRECT;
+	}
+
+	switch (dma_mapping) {
+	case HALMAC_DMA_MAPPING_HIGH:
+		*cur_fs = &adapter->sdio_fs.hiq_pg_num;
+		break;
+	case HALMAC_DMA_MAPPING_NORMAL:
+		*cur_fs = &adapter->sdio_fs.miq_pg_num;
+		break;
+	case HALMAC_DMA_MAPPING_LOW:
+		*cur_fs = &adapter->sdio_fs.lowq_pg_num;
+		break;
+	case HALMAC_DMA_MAPPING_EXTRA:
+		*cur_fs = &adapter->sdio_fs.exq_pg_num;
+		break;
+	default:
+		pr_err("DmaMapping is out of range\n");
+		return HALMAC_RET_DMA_MAP_INCORRECT;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+chk_rqd_page_num_8822b(struct halmac_adapter *adapter, u8 *buf, u32 *rqd_pg_num,
+		       u16 **cur_fs, u8 *macid_cnt, u32 tx_agg_num)
+{
+	u8 *pkt;
+	u8 qsel_first;
+	u32 i;
+	u32 pkt_size;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	pkt = buf;
+
+	qsel_first = (u8)GET_TX_DESC_QSEL(pkt);
+
+	status = chk_dma_mapping_8822b(adapter, cur_fs, qsel_first);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	for (i = 0; i < tx_agg_num; i++) {
+		/*QSEL parser*/
+		status = chk_qsel_8822b(adapter, qsel_first, pkt, macid_cnt);
+		if (status != HALMAC_RET_SUCCESS)
+			return status;
+
+		/*Page number parser*/
+		pkt_size = GET_TX_DESC_TXPKTSIZE(pkt) + GET_TX_DESC_OFFSET(pkt);
+		*rqd_pg_num += (pkt_size >> TX_PAGE_SIZE_SHIFT_88XX) +
+				((pkt_size & (TX_PAGE_SIZE_88XX - 1)) ? 1 : 0);
+
+		pkt += ALIGN(GET_TX_DESC_TXPKTSIZE(pkt) +
+			     (GET_TX_DESC_PKT_OFFSET(pkt) << 3) +
+			     TX_DESC_SIZE_88XX, 8);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.h
new file mode 100644
index 000000000000..c29fba2d8a8f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_sdio_8822b.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_API_8822B_SDIO_H_
+#define _HALMAC_API_8822B_SDIO_H_
+
+#include "../../halmac_api.h"
+#include "halmac_8822b_cfg.h"
+
+enum halmac_ret_status
+mac_pwr_switch_sdio_8822b(struct halmac_adapter *adapter,
+			  enum halmac_mac_power pwr);
+
+enum halmac_ret_status
+tx_allowed_sdio_8822b(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+u8
+reg_r8_sdio_8822b(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w8_sdio_8822b(struct halmac_adapter *adapter, u32 offset, u8 value);
+
+u16
+reg_r16_sdio_8822b(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w16_sdio_8822b(struct halmac_adapter *adapter, u32 offset, u16 value);
+
+u32
+reg_r32_sdio_8822b(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w32_sdio_8822b(struct halmac_adapter *adapter, u32 offset, u32 value);
+
+enum halmac_ret_status
+phy_cfg_sdio_8822b(struct halmac_adapter *adapter,
+		   enum halmac_intf_phy_platform pltfm);
+
+enum halmac_ret_status
+pcie_switch_sdio_8822b(struct halmac_adapter *adapter,
+		       enum halmac_pcie_cfg cfg);
+
+enum halmac_ret_status
+intf_tun_sdio_8822b(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+get_sdio_tx_addr_8822b(struct halmac_adapter *adapter, u8 *buf, u32 size,
+		       u32 *cmd53_addr);
+
+#endif/* _HALMAC_API_8822B_SDIO_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.c
new file mode 100644
index 000000000000..a8d8b6d50063
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.c
@@ -0,0 +1,161 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_usb_8822b.h"
+#include "halmac_pwr_seq_8822b.h"
+#include "../halmac_init_88xx.h"
+#include "../halmac_common_88xx.h"
+
+/**
+ * mac_pwr_switch_usb_8822b() - switch mac power
+ * @adapter : the adapter of halmac
+ * @pwr : power state
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+mac_pwr_switch_usb_8822b(struct halmac_adapter *adapter,
+			 enum halmac_mac_power pwr)
+{
+	u8 value8;
+	u8 rpwm;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s\n",
+		 __func__);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%x\n", pwr);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "8821C pwr seq ver = %s\n", HALMAC_8822B_PWR_SEQ_VER);
+
+	adapter->rpwm = HALMAC_REG_R8(0xFE58);
+
+	/* Check FW still exist or not */
+	if (HALMAC_REG_R16(REG_MCUFW_CTRL) == 0xC078) {
+		/* Leave 32K */
+		rpwm = (u8)((adapter->rpwm ^ BIT(7)) & 0x80);
+		HALMAC_REG_W8(0xFE58, rpwm);
+	}
+
+	value8 = HALMAC_REG_R8(REG_CR);
+	if (value8 == 0xEA) {
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_OFF;
+	} else {
+		if (BIT(0) == (HALMAC_REG_R8(REG_SYS_STATUS1 + 1) & BIT(0)))
+			adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_OFF;
+		else
+			adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_ON;
+	}
+
+	/*Check if power switch is needed*/
+	if (pwr == HALMAC_MAC_POWER_ON &&
+	    adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_ON) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "power state unchange!!\n");
+		return HALMAC_RET_PWR_UNCHANGE;
+	}
+
+	if (pwr == HALMAC_MAC_POWER_OFF) {
+		if (pwr_seq_parser_88xx(adapter, card_dis_flow_8822b) !=
+		    HALMAC_RET_SUCCESS) {
+			pr_err("Handle power off cmd error\n");
+			return HALMAC_RET_POWER_OFF_FAIL;
+		}
+
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_OFF;
+		adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
+		init_adapter_dynamic_param_88xx(adapter);
+	} else {
+		if (pwr_seq_parser_88xx(adapter, card_en_flow_8822b) !=
+		    HALMAC_RET_SUCCESS) {
+			pr_err("Handle power on cmd error\n");
+			return HALMAC_RET_POWER_ON_FAIL;
+		}
+
+		HALMAC_REG_W8_CLR(REG_SYS_STATUS1 + 1, BIT(0));
+
+		if ((HALMAC_REG_R8(REG_SW_MDIO + 3) & BIT(0)) == BIT(0))
+			RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+				 "[ALWAYS]shall R reg twice!!\n");
+
+		adapter->halmac_state.mac_pwr = HALMAC_MAC_POWER_ON;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * phy_cfg_usb_8822b() - phy config
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+phy_cfg_usb_8822b(struct halmac_adapter *adapter,
+		  enum halmac_intf_phy_platform pltfm)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = parse_intf_phy_88xx(adapter, usb2_phy_param_8822b, pltfm,
+				     HAL_INTF_PHY_USB2);
+
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	status = parse_intf_phy_88xx(adapter, usb3_phy_param_8822b, pltfm,
+				     HAL_INTF_PHY_USB3);
+
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * halmac_pcie_switch_8822b() - pcie gen1/gen2 switch
+ * @adapter : the adapter of halmac
+ * @cfg : gen1/gen2 selection
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pcie_switch_usb_8822b(struct halmac_adapter *adapter, enum halmac_pcie_cfg cfg)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * intf_tun_usb_8822b() - usb interface fine tuning
+ * @adapter : the adapter of halmac
+ * Author : Ivan
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+intf_tun_usb_8822b(struct halmac_adapter *adapter)
+{
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.h
new file mode 100644
index 000000000000..683b45e36c3b
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_usb_8822b.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_API_8822B_USB_H_
+#define _HALMAC_API_8822B_USB_H_
+
+#include "../../halmac_api.h"
+
+extern struct halmac_intf_phy_para usb2_phy_param_8822b[];
+extern struct halmac_intf_phy_para usb3_phy_param_8822b[];
+
+enum halmac_ret_status
+mac_pwr_switch_usb_8822b(struct halmac_adapter *adapter,
+			 enum halmac_mac_power pwr);
+
+enum halmac_ret_status
+phy_cfg_usb_8822b(struct halmac_adapter *adapter,
+		  enum halmac_intf_phy_platform pltfm);
+
+enum halmac_ret_status
+pcie_switch_usb_8822b(struct halmac_adapter *adapter, enum halmac_pcie_cfg cfg);
+
+enum halmac_ret_status
+intf_tun_usb_8822b(struct halmac_adapter *adapter);
+
+#endif/* _HALMAC_API_8822B_USB_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.c
new file mode 100644
index 000000000000..01450a84cfde
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.c
@@ -0,0 +1,538 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_pcie_88xx.h"
+
+/**
+ * init_pcie_cfg_88xx() -  init PCIe
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_pcie_cfg_88xx(struct halmac_adapter *adapter)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * deinit_pcie_cfg_88xx() - deinit PCIE
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+deinit_pcie_cfg_88xx(struct halmac_adapter *adapter)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_pcie_rx_agg_88xx() - config rx aggregation
+ * @adapter : the adapter of halmac
+ * @halmac_rx_agg_mode
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_pcie_rx_agg_88xx(struct halmac_adapter *adapter,
+		     struct halmac_rxagg_cfg *cfg)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * reg_r8_pcie_88xx() - read 1byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u8
+reg_r8_pcie_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return PLTFM_REG_R8(offset);
+}
+
+/**
+ * reg_w8_pcie_88xx() - write 1byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w8_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
+{
+	PLTFM_REG_W8(offset, value);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * reg_r16_pcie_88xx() - read 2byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u16
+reg_r16_pcie_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return PLTFM_REG_R16(offset);
+}
+
+/**
+ * reg_w16_pcie_88xx() - write 2byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w16_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u16 value)
+{
+	PLTFM_REG_W16(offset, value);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * reg_r32_pcie_88xx() - read 4byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32
+reg_r32_pcie_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return PLTFM_REG_R32(offset);
+}
+
+/**
+ * reg_w32_pcie_88xx() - write 4byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w32_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u32 value)
+{
+	PLTFM_REG_W32(offset, value);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_txagg_pcie_align_88xx() -config sdio bus tx agg alignment
+ * @adapter : the adapter of halmac
+ * @enable : function enable(1)/disable(0)
+ * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
+ * Author : Soar Tu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_txagg_pcie_align_88xx(struct halmac_adapter *adapter, u8 enable,
+			  u16 align_size)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * tx_allowed_pcie_88xx() - check tx status
+ * @adapter : the adapter of halmac
+ * @buf : tx packet, include txdesc
+ * @size : tx packet size, include txdesc
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+tx_allowed_pcie_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * pcie_indirect_reg_r32_88xx() - read MAC reg by SDIO reg
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32
+pcie_indirect_reg_r32_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return 0xFFFFFFFF;
+}
+
+/**
+ * pcie_reg_rn_88xx() - read n byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @size : register value size
+ * @value : register value
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+pcie_reg_rn_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+		 u8 *value)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * set_pcie_bulkout_num_88xx() - inform bulk-out num
+ * @adapter : the adapter of halmac
+ * @num : usb bulk-out number
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+set_pcie_bulkout_num_88xx(struct halmac_adapter *adapter, u8 num)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * get_pcie_tx_addr_88xx() - get CMD53 addr for the TX packet
+ * @adapter : the adapter of halmac
+ * @buf : tx packet, include txdesc
+ * @size : tx packet size
+ * @cmd53_addr : cmd53 addr value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_pcie_tx_addr_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+		      u32 *cmd53_addr)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * get_pcie_bulkout_id_88xx() - get bulk out id for the TX packet
+ * @adapter : the adapter of halmac
+ * @buf : tx packet, include txdesc
+ * @size : tx packet size
+ * @id : usb bulk-out id
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_pcie_bulkout_id_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+			 u8 *id)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+enum halmac_ret_status
+mdio_write_88xx(struct halmac_adapter *adapter, u8 addr, u16 data, u8 speed)
+{
+	u8 tmp_u1b = 0;
+	u32 cnt = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u8 real_addr = 0;
+
+	HALMAC_REG_W16(REG_MDIO_V1, data);
+
+	real_addr = (addr & 0x1F);
+	HALMAC_REG_W8(REG_PCIE_MIX_CFG, real_addr);
+
+	if (speed == HAL_INTF_PHY_PCIE_GEN1) {
+		if (addr < 0x20)
+			HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x00);
+		else
+			HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x01);
+	} else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
+		if (addr < 0x20)
+			HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x02);
+		else
+			HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x03);
+	} else {
+		pr_err("Error Speed !\n");
+	}
+
+	HALMAC_REG_W8_SET(REG_PCIE_MIX_CFG, BIT_MDIO_WFLAG_V1);
+
+	tmp_u1b = HALMAC_REG_R8(REG_PCIE_MIX_CFG) & BIT_MDIO_WFLAG_V1;
+	cnt = 20;
+
+	while (tmp_u1b && (cnt != 0)) {
+		usleep_range(10, 20);
+		tmp_u1b = HALMAC_REG_R8(REG_PCIE_MIX_CFG) & BIT_MDIO_WFLAG_V1;
+		cnt--;
+	}
+
+	if (tmp_u1b) {
+		pr_err("MDIO write fail!\n");
+		return HALMAC_RET_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+u16
+mdio_read_88xx(struct halmac_adapter *adapter, u8 addr, u8 speed)
+{
+	u16 ret = 0;
+	u8 tmp_u1b = 0;
+	u32 cnt = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u8 real_addr = 0;
+
+	real_addr = (addr & 0x1F);
+	HALMAC_REG_W8(REG_PCIE_MIX_CFG, real_addr);
+
+	if (speed == HAL_INTF_PHY_PCIE_GEN1) {
+		if (addr < 0x20)
+			HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x00);
+		else
+			HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x01);
+	} else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
+		if (addr < 0x20)
+			HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x02);
+		else
+			HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x03);
+	} else {
+		pr_err("Error Speed !\n");
+	}
+
+	HALMAC_REG_W8_SET(REG_PCIE_MIX_CFG, BIT_MDIO_RFLAG_V1);
+
+	tmp_u1b = HALMAC_REG_R8(REG_PCIE_MIX_CFG) & BIT_MDIO_RFLAG_V1;
+	cnt = 20;
+	while (tmp_u1b && (cnt != 0)) {
+		usleep_range(10, 20);
+		tmp_u1b = HALMAC_REG_R8(REG_PCIE_MIX_CFG) & BIT_MDIO_RFLAG_V1;
+		cnt--;
+	}
+
+	if (tmp_u1b) {
+		ret  = 0xFFFF;
+		pr_err("MDIO read fail!\n");
+	} else {
+		ret = HALMAC_REG_R16(REG_MDIO_V1 + 2);
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Value-R = %x\n", ret);
+	}
+
+	return ret;
+}
+
+enum halmac_ret_status
+dbi_w32_88xx(struct halmac_adapter *adapter, u16 addr, u32 data)
+{
+	u8 tmp_u1b = 0;
+	u32 cnt = 0;
+	u16 write_addr = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	HALMAC_REG_W32(REG_DBI_WDATA_V1, data);
+
+	write_addr = ((addr & 0x0ffc) | (0x000F << 12));
+	HALMAC_REG_W16(REG_DBI_FLAG_V1, write_addr);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "Addr-W = %x\n",
+		 write_addr);
+
+	HALMAC_REG_W8(REG_DBI_FLAG_V1 + 2, 0x01);
+	tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
+
+	cnt = 20;
+	while (tmp_u1b && (cnt != 0)) {
+		usleep_range(10, 20);
+		tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
+		cnt--;
+	}
+
+	if (tmp_u1b) {
+		pr_err("DBI write fail!\n");
+		return HALMAC_RET_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+u32
+dbi_r32_88xx(struct halmac_adapter *adapter, u16 addr)
+{
+	u16 read_addr = addr & 0x0ffc;
+	u8 tmp_u1b = 0;
+	u32 cnt = 0;
+	u32 ret = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	HALMAC_REG_W16(REG_DBI_FLAG_V1, read_addr);
+
+	HALMAC_REG_W8(REG_DBI_FLAG_V1 + 2, 0x2);
+	tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
+
+	cnt = 20;
+	while (tmp_u1b && (cnt != 0)) {
+		usleep_range(10, 20);
+		tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
+		cnt--;
+	}
+
+	if (tmp_u1b) {
+		ret  = 0xFFFF;
+		pr_err("DBI read fail!\n");
+	} else {
+		ret = HALMAC_REG_R32(REG_DBI_RDATA_V1);
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Value-R = %x\n", ret);
+	}
+
+	return ret;
+}
+
+enum halmac_ret_status
+dbi_w8_88xx(struct halmac_adapter *adapter, u16 addr, u8 data)
+{
+	u8 tmp_u1b = 0;
+	u32 cnt = 0;
+	u16 write_addr = 0;
+	u16 remainder = addr & (4 - 1);
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	HALMAC_REG_W8(REG_DBI_WDATA_V1 + remainder, data);
+
+	write_addr = ((addr & 0x0ffc) | (BIT(0) << (remainder + 12)));
+
+	HALMAC_REG_W16(REG_DBI_FLAG_V1, write_addr);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "Addr-W = %x\n",
+		 write_addr);
+
+	HALMAC_REG_W8(REG_DBI_FLAG_V1 + 2, 0x01);
+
+	tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
+
+	cnt = 20;
+	while (tmp_u1b && (cnt != 0)) {
+		usleep_range(10, 20);
+		tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
+		cnt--;
+	}
+
+	if (tmp_u1b) {
+		pr_err("DBI write fail!\n");
+		return HALMAC_RET_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+u8
+dbi_r8_88xx(struct halmac_adapter *adapter, u16 addr)
+{
+	u16 read_addr = addr & 0x0ffc;
+	u8 tmp_u1b = 0;
+	u32 cnt = 0;
+	u8 ret = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	HALMAC_REG_W16(REG_DBI_FLAG_V1, read_addr);
+	HALMAC_REG_W8(REG_DBI_FLAG_V1 + 2, 0x2);
+
+	tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
+
+	cnt = 20;
+	while (tmp_u1b && (cnt != 0)) {
+		usleep_range(10, 20);
+		tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
+		cnt--;
+	}
+
+	if (tmp_u1b) {
+		ret  = 0xFF;
+		pr_err("DBI read fail!\n");
+	} else {
+		ret = HALMAC_REG_R8(REG_DBI_RDATA_V1 + (addr & (4 - 1)));
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Value-R = %x\n", ret);
+	}
+
+	return ret;
+}
+
+enum halmac_ret_status
+trxdma_check_idle_88xx(struct halmac_adapter *adapter)
+{
+	u32 cnt = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	/* Stop Tx & Rx DMA */
+	HALMAC_REG_W32_SET(REG_RXPKT_NUM, BIT(18));
+	HALMAC_REG_W16_SET(REG_PCIE_CTRL, ~(BIT(15) | BIT(8)));
+
+	/* Stop FW */
+	HALMAC_REG_W16_CLR(REG_SYS_FUNC_EN, BIT(10));
+
+	/* Check Tx DMA is idle */
+	cnt = 20;
+	while ((HALMAC_REG_R8(REG_SYS_CFG5) & BIT(2)) == BIT(2)) {
+		usleep_range(10, 20);
+		cnt--;
+		if (cnt == 0) {
+			pr_err("Chk tx idle\n");
+			return HALMAC_RET_POWER_OFF_FAIL;
+		}
+	}
+
+	/* Check Rx DMA is idle */
+	cnt = 20;
+	while ((HALMAC_REG_R32(REG_RXPKT_NUM) & BIT(17)) != BIT(17)) {
+		usleep_range(10, 20);
+		cnt--;
+		if (cnt == 0) {
+			pr_err("Chk rx idle\n");
+			return HALMAC_RET_POWER_OFF_FAIL;
+		}
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+void
+en_ref_autok_88xx(struct halmac_adapter *adapter, u8 en)
+{
+	if (en == 1)
+		adapter->pcie_refautok_en = 1;
+	else
+		adapter->pcie_refautok_en = 0;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.h
new file mode 100644
index 000000000000..3c9bc50a327f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_pcie_88xx.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_PCIE_88XX_H_
+#define _HALMAC_PCIE_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+init_pcie_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+deinit_pcie_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+cfg_pcie_rx_agg_88xx(struct halmac_adapter *adapter,
+		     struct halmac_rxagg_cfg *cfg);
+
+u8
+reg_r8_pcie_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w8_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u8 value);
+
+u16
+reg_r16_pcie_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w16_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u16 value);
+
+u32
+reg_r32_pcie_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w32_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u32 value);
+
+enum halmac_ret_status
+cfg_txagg_pcie_align_88xx(struct halmac_adapter *adapter, u8 enable,
+			  u16 align_size);
+
+enum halmac_ret_status
+tx_allowed_pcie_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+u32
+pcie_indirect_reg_r32_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+pcie_reg_rn_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+		 u8 *value);
+
+enum halmac_ret_status
+set_pcie_bulkout_num_88xx(struct halmac_adapter *adapter, u8 num);
+
+enum halmac_ret_status
+get_pcie_tx_addr_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+		      u32 *cmd53_addr);
+
+enum halmac_ret_status
+get_pcie_bulkout_id_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+			 u8 *id);
+
+enum halmac_ret_status
+mdio_write_88xx(struct halmac_adapter *adapter, u8 addr, u16 data, u8 speed);
+
+u16
+mdio_read_88xx(struct halmac_adapter *adapter, u8 addr, u8 speed);
+
+enum halmac_ret_status
+dbi_w32_88xx(struct halmac_adapter *adapter, u16 addr, u32 data);
+
+u32
+dbi_r32_88xx(struct halmac_adapter *adapter, u16 addr);
+
+enum halmac_ret_status
+dbi_w8_88xx(struct halmac_adapter *adapter, u16 addr, u8 data);
+
+u8
+dbi_r8_88xx(struct halmac_adapter *adapter, u16 addr);
+
+enum halmac_ret_status
+trxdma_check_idle_88xx(struct halmac_adapter *adapter);
+
+void
+en_ref_autok_88xx(struct halmac_adapter *dapter, u8 en);
+
+#endif/* _HALMAC_PCIE_88XX_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.c
new file mode 100644
index 000000000000..97a3112e63c6
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.c
@@ -0,0 +1,895 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_sdio_88xx.h"
+#include "halmac_88xx_cfg.h"
+
+/* define the SDIO Bus CLK threshold */
+/* for avoiding CMD53 fails that result from SDIO CLK sync to ana_clk fail */
+#define SDIO_CLK_HIGH_SPEED_TH		50 /* 50MHz */
+#define SDIO_CLK_SPEED_MAX		208 /* 208MHz */
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u8
+r_indir_cmd52_88xx(struct halmac_adapter *adapter, u32 offset);
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u32
+r_indir_cmd53_88xx(struct halmac_adapter *adapter, u32 offset);
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u32
+r8_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr);
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u32
+r16_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr);
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u32
+r32_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr);
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w_indir_cmd52_88xx(struct halmac_adapter *adapter, u32 adr, u32 val,
+		   enum halmac_io_size size);
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w_indir_cmd53_88xx(struct halmac_adapter *adapter, u32 adr, u32 val,
+		   enum halmac_io_size size);
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w8_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr, u32 val);
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w16_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr, u32 val);
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w32_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr, u32 val);
+
+/**
+ * init_sdio_cfg_88xx() - init SDIO
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_sdio_cfg_88xx(struct halmac_adapter *adapter)
+{
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (adapter->intf != HALMAC_INTERFACE_SDIO)
+		return HALMAC_RET_WRONG_INTF;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	HALMAC_REG_R32(REG_SDIO_FREE_TXPG);
+
+	value32 = HALMAC_REG_R32(REG_SDIO_TX_CTRL) & 0xFFFF;
+	value32 &= ~(BIT_CMD_ERR_STOP_INT_EN | BIT_EN_MASK_TIMER |
+							BIT_EN_RXDMA_MASK_INT);
+	HALMAC_REG_W32(REG_SDIO_TX_CTRL, value32);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * deinit_sdio_cfg_88xx() - deinit SDIO
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+deinit_sdio_cfg_88xx(struct halmac_adapter *adapter)
+{
+	if (adapter->intf != HALMAC_INTERFACE_SDIO)
+		return HALMAC_RET_WRONG_INTF;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_sdio_rx_agg_88xx() - config rx aggregation
+ * @adapter : the adapter of halmac
+ * @halmac_rx_agg_mode
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_sdio_rx_agg_88xx(struct halmac_adapter *adapter,
+		     struct halmac_rxagg_cfg *cfg)
+{
+	u8 value8;
+	u8 size;
+	u8 timeout;
+	u8 agg_enable;
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	agg_enable = HALMAC_REG_R8(REG_TXDMA_PQ_MAP);
+
+	switch (cfg->mode) {
+	case HALMAC_RX_AGG_MODE_NONE:
+		agg_enable &= ~(BIT_RXDMA_AGG_EN);
+		break;
+	case HALMAC_RX_AGG_MODE_DMA:
+	case HALMAC_RX_AGG_MODE_USB:
+		agg_enable |= BIT_RXDMA_AGG_EN;
+		break;
+	default:
+		pr_err("unsupported mode\n");
+		agg_enable &= ~BIT_RXDMA_AGG_EN;
+		break;
+	}
+
+	if (cfg->threshold.drv_define == 0) {
+		size = 0xFF;
+		timeout = 0x01;
+	} else {
+		size = cfg->threshold.size;
+		timeout = cfg->threshold.timeout;
+	}
+
+	value32 = HALMAC_REG_R32(REG_RXDMA_AGG_PG_TH);
+	if (cfg->threshold.size_limit_en == 0)
+		HALMAC_REG_W32(REG_RXDMA_AGG_PG_TH, value32 & ~BIT_EN_PRE_CALC);
+	else
+		HALMAC_REG_W32(REG_RXDMA_AGG_PG_TH, value32 | BIT_EN_PRE_CALC);
+
+	HALMAC_REG_W8(REG_TXDMA_PQ_MAP, agg_enable);
+	HALMAC_REG_W16(REG_RXDMA_AGG_PG_TH,
+		       (u16)(size | (timeout << BIT_SHIFT_DMA_AGG_TO_V1)));
+
+	value8 = HALMAC_REG_R8(REG_RXDMA_MODE);
+	if (0 != (agg_enable & BIT_RXDMA_AGG_EN))
+		HALMAC_REG_W8(REG_RXDMA_MODE, value8 | BIT_DMA_MODE);
+	else
+		HALMAC_REG_W8(REG_RXDMA_MODE, value8 & ~(BIT_DMA_MODE));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * sdio_reg_rn_88xx() - read n byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @halmac_size : register value size
+ * @value : register value
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+sdio_reg_rn_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+		 u8 *value)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (0 == (offset & 0xFFFF0000)) {
+		pr_err("offset 0x%x\n", offset);
+		return HALMAC_RET_FAIL;
+	}
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &offset);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("convert offset\n");
+		return status;
+	}
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF) {
+		pr_err("power off\n");
+		return HALMAC_RET_FAIL;
+	}
+
+	PLTFM_SDIO_CMD53_RN(offset, size, value);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_txagg_sdio_align_88xx() -config sdio bus tx agg alignment
+ * @adapter : the adapter of halmac
+ * @enable : function enable(1)/disable(0)
+ * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
+ * Author : Soar Tu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_txagg_sdio_align_88xx(struct halmac_adapter *adapter, u8 enable,
+			  u16 align_size)
+{
+	u8 i;
+	u8 flag = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (adapter->chip_id == HALMAC_CHIP_ID_8822B)
+		return HALMAC_RET_NOT_SUPPORT;
+
+	if ((align_size & 0xF000) != 0) {
+		pr_err("out of range\n");
+		return HALMAC_RET_FAIL;
+	}
+
+	for (i = 3; i <= 11; i++) {
+		if (align_size == 1 << i) {
+			flag = 1;
+			break;
+		}
+	}
+
+	if (flag == 0) {
+		pr_err("not 2^3 ~ 2^11\n");
+		return HALMAC_RET_FAIL;
+	}
+
+	adapter->hw_cfg_info.tx_align_size = align_size;
+
+	if (enable)
+		HALMAC_REG_W16(REG_RQPN_CTRL_2, 0x8000 | align_size);
+	else
+		HALMAC_REG_W16(REG_RQPN_CTRL_2, align_size);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * sdio_indirect_reg_r32_88xx() - read MAC reg by SDIO reg
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32
+sdio_indirect_reg_r32_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return r_indir_sdio_88xx(adapter, offset, HALMAC_IO_DWORD);
+}
+
+/**
+ * set_sdio_bulkout_num_88xx() - inform bulk-out num
+ * @adapter : the adapter of halmac
+ * @bulkout_num : usb bulk-out number
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+set_sdio_bulkout_num_88xx(struct halmac_adapter *adapter, u8 num)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * get_sdio_bulkout_id_88xx() - get bulk out id for the TX packet
+ * @adapter : the adapter of halmac
+ * @halmac_buf : tx packet, include txdesc
+ * @halmac_size : tx packet size
+ * @bulkout_id : usb bulk-out id
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_sdio_bulkout_id_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+			 u8 *id)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * sdio_cmd53_4byte_88xx() - cmd53 only for 4byte len register IO
+ * @adapter : the adapter of halmac
+ * @enable : 1->CMD53 only use in 4byte reg, 0 : No limitation
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+sdio_cmd53_4byte_88xx(struct halmac_adapter *adapter,
+		      enum halmac_sdio_cmd53_4byte_mode mode)
+{
+	if (adapter->intf != HALMAC_INTERFACE_SDIO)
+		return HALMAC_RET_WRONG_INTF;
+
+	if (adapter->api_registry.sdio_cmd53_4byte_en == 0)
+		return HALMAC_RET_NOT_SUPPORT;
+
+	adapter->sdio_cmd53_4byte = mode;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * sdio_hw_info_88xx() - info sdio hw info
+ * @adapter : the adapter of halmac
+ * @HALMAC_SDIO_CMD53_4BYTE_MODE :
+ * clock_speed : sdio bus clock. Unit -> MHz
+ * spec_ver : sdio spec version
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+sdio_hw_info_88xx(struct halmac_adapter *adapter,
+		  struct halmac_sdio_hw_info *info)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (adapter->intf != HALMAC_INTERFACE_SDIO)
+		return HALMAC_RET_WRONG_INTF;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "SDIO clock:%d, spec:%d\n", info->clock_speed, info->spec_ver);
+
+	if (info->clock_speed > SDIO_CLK_SPEED_MAX)
+		return HALMAC_RET_SDIO_CLOCK_ERR;
+
+	if (info->clock_speed > SDIO_CLK_HIGH_SPEED_TH)
+		adapter->sdio_hw_info.io_hi_speed_flag = 1;
+
+	adapter->sdio_hw_info.io_indir_flag = info->io_indir_flag;
+	if (info->clock_speed > SDIO_CLK_HIGH_SPEED_TH &&
+	    adapter->sdio_hw_info.io_indir_flag == 0)
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "SDIO clock:%d, indir access is better\n",
+			 info->clock_speed);
+
+	adapter->sdio_hw_info.clock_speed = info->clock_speed;
+	adapter->sdio_hw_info.spec_ver = info->spec_ver;
+	adapter->sdio_hw_info.block_size = info->block_size;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+void
+cfg_sdio_tx_page_threshold_88xx(struct halmac_adapter *adapter,
+				struct halmac_tx_page_threshold_info *info)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u32 threshold = info->threshold;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (info->enable == 1) {
+		threshold = BIT(31) | threshold;
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "enable\n");
+	} else {
+		threshold = ~(BIT(31)) & threshold;
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "disable\n");
+	}
+
+	switch (info->dma_queue_sel) {
+	case HALMAC_MAP2_HQ:
+		HALMAC_REG_W32(REG_TQPNT1, threshold);
+		break;
+	case HALMAC_MAP2_NQ:
+		HALMAC_REG_W32(REG_TQPNT2, threshold);
+		break;
+	case HALMAC_MAP2_LQ:
+		HALMAC_REG_W32(REG_TQPNT3, threshold);
+		break;
+	case HALMAC_MAP2_EXQ:
+		HALMAC_REG_W32(REG_TQPNT4, threshold);
+		break;
+	default:
+		break;
+	}
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+}
+
+enum halmac_ret_status
+cnv_to_sdio_bus_offset_88xx(struct halmac_adapter *adapter, u32 *offset)
+{
+	switch ((*offset) & 0xFFFF0000) {
+	case WLAN_IOREG_OFFSET:
+		*offset &= HALMAC_WLAN_MAC_REG_MSK;
+		*offset |= HALMAC_SDIO_CMD_ADDR_MAC_REG << 13;
+		break;
+	case SDIO_LOCAL_OFFSET:
+		*offset &= HALMAC_SDIO_LOCAL_MSK;
+		*offset |= HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13;
+		break;
+	default:
+		*offset = 0xFFFFFFFF;
+		pr_err("base address!!\n");
+		return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+leave_sdio_suspend_88xx(struct halmac_adapter *adapter)
+{
+	u8 value8;
+	u32 cnt;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	value8 = HALMAC_REG_R8(REG_SDIO_HSUS_CTRL);
+	HALMAC_REG_W8(REG_SDIO_HSUS_CTRL, value8 & ~(BIT(0)));
+
+	cnt = 10000;
+	while (!(HALMAC_REG_R8(REG_SDIO_HSUS_CTRL) & 0x02)) {
+		cnt--;
+		if (cnt == 0)
+			return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
+	}
+
+	value8 = HALMAC_REG_R8(REG_HCI_OPT_CTRL + 2);
+	if (adapter->sdio_hw_info.spec_ver == HALMAC_SDIO_SPEC_VER_3_00)
+		HALMAC_REG_W8(REG_HCI_OPT_CTRL + 2, value8 | BIT(2));
+	else
+		HALMAC_REG_W8(REG_HCI_OPT_CTRL + 2, value8 & ~(BIT(2)));
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u8
+r_indir_cmd52_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	u8 value8, tmp, cnt = 50;
+	u32 reg_cfg = REG_SDIO_INDIRECT_REG_CFG;
+	u32 reg_data = REG_SDIO_INDIRECT_REG_DATA;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_cfg);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_data);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	PLTFM_SDIO_CMD52_W(reg_cfg, (u8)offset);
+	PLTFM_SDIO_CMD52_W(reg_cfg + 1, (u8)(offset >> 8));
+	PLTFM_SDIO_CMD52_W(reg_cfg + 2, (u8)(BIT(3) | BIT(4)));
+
+	do {
+		tmp = PLTFM_SDIO_CMD52_R(reg_cfg + 2);
+		cnt--;
+	} while (((tmp & BIT(4)) == 0) && (cnt > 0));
+
+	if (((cnt & BIT(4)) == 0) && cnt == 0)
+		pr_err("sdio indirect CMD52 read\n");
+
+	value8 = PLTFM_SDIO_CMD52_R(reg_data);
+
+	return value8;
+}
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u32
+r_indir_cmd53_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	u8 cnt = 50;
+	u8 value[6];
+	u32 reg_cfg = REG_SDIO_INDIRECT_REG_CFG;
+	u32 reg_data = REG_SDIO_INDIRECT_REG_DATA;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	union {
+		__le32 dword;
+		u8 byte[4];
+	} value32 = { 0x00000000 };
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_cfg);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_data);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	PLTFM_SDIO_CMD53_W32(reg_cfg, offset | BIT(19) | BIT(20));
+
+	do {
+		PLTFM_SDIO_CMD53_RN(reg_cfg + 2, sizeof(value), value);
+		cnt--;
+	} while (((value[0] & BIT(4)) == 0) && (cnt > 0));
+
+	if (((cnt & BIT(4)) == 0) && cnt == 0)
+		pr_err("sdio indirect CMD53 read\n");
+
+	value32.byte[0] = value[2];
+	value32.byte[1] = value[3];
+	value32.byte[2] = value[4];
+	value32.byte[3] = value[5];
+
+	return le32_to_cpu(value32.dword);
+}
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u32
+r8_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr)
+{
+	union {
+		__le32 dword;
+		u8 byte[4];
+	} val = { 0x00000000 };
+
+	if (adapter->pwr_off_flow_flag == 1 ||
+	    adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF) {
+		val.byte[0] = r_indir_cmd52_88xx(adapter, adr);
+		return le32_to_cpu(val.dword);
+	}
+
+	return r_indir_cmd53_88xx(adapter, adr);
+}
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u32
+r16_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr)
+{
+	u32 reg_data = REG_SDIO_INDIRECT_REG_DATA;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	union {
+		__le32 dword;
+		u8 byte[4];
+	} val = { 0x00000000 };
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_data);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF) {
+		if (0 != (adr & (2 - 1))) {
+			val.byte[0] = r_indir_cmd52_88xx(adapter, adr);
+			val.byte[1] = r_indir_cmd52_88xx(adapter, adr + 1);
+		} else {
+			val.byte[0] = r_indir_cmd52_88xx(adapter, adr);
+			val.byte[1] = PLTFM_SDIO_CMD52_R(reg_data + 1);
+		}
+
+		return  le32_to_cpu(val.dword);
+	}
+
+	if (0 != (adr & (2 - 1))) {
+		val.byte[0] = (u8)r_indir_cmd53_88xx(adapter, adr);
+		val.byte[1] = (u8)r_indir_cmd53_88xx(adapter, adr + 1);
+
+		return le32_to_cpu(val.dword);
+	}
+
+	return r_indir_cmd53_88xx(adapter, adr);
+}
+
+/*only for r_indir_sdio_88xx !!, Soar 20171222*/
+static u32
+r32_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr)
+{
+	u32 reg_data = REG_SDIO_INDIRECT_REG_DATA;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	union {
+		__le32 dword;
+		u8 byte[4];
+	} val = { 0x00000000 };
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_data);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF) {
+		if (0 != (adr & (4 - 1))) {
+			val.byte[0] = r_indir_cmd52_88xx(adapter, adr);
+			val.byte[1] = r_indir_cmd52_88xx(adapter, adr + 1);
+			val.byte[2] = r_indir_cmd52_88xx(adapter, adr + 2);
+			val.byte[3] = r_indir_cmd52_88xx(adapter, adr + 3);
+		} else {
+			val.byte[0] = r_indir_cmd52_88xx(adapter, adr);
+			val.byte[1] = PLTFM_SDIO_CMD52_R(reg_data + 1);
+			val.byte[2] = PLTFM_SDIO_CMD52_R(reg_data + 2);
+			val.byte[3] = PLTFM_SDIO_CMD52_R(reg_data + 3);
+		}
+
+		return le32_to_cpu(val.dword);
+	}
+
+	if (0 != (adr & (4 - 1))) {
+		val.byte[0] = (u8)r_indir_cmd53_88xx(adapter, adr);
+		val.byte[1] = (u8)r_indir_cmd53_88xx(adapter, adr + 1);
+		val.byte[2] = (u8)r_indir_cmd53_88xx(adapter, adr + 2);
+		val.byte[3] = (u8)r_indir_cmd53_88xx(adapter, adr + 3);
+
+		return le32_to_cpu(val.dword);
+	}
+
+	return r_indir_cmd53_88xx(adapter, adr);
+}
+
+u32
+r_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr,
+		  enum halmac_io_size size)
+{
+	u32 value32 = 0;
+
+	mutex_lock(&adapter->sdio_indir_mutex);
+
+	switch (size) {
+	case HALMAC_IO_BYTE:
+		value32 = r8_indir_sdio_88xx(adapter, adr);
+		break;
+	case HALMAC_IO_WORD:
+		value32 = r16_indir_sdio_88xx(adapter, adr);
+		break;
+	case HALMAC_IO_DWORD:
+		value32 = r32_indir_sdio_88xx(adapter, adr);
+		break;
+	default:
+		break;
+	}
+
+	mutex_unlock(&adapter->sdio_indir_mutex);
+
+	return value32;
+}
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w_indir_cmd52_88xx(struct halmac_adapter *adapter, u32 adr, u32 val,
+		   enum halmac_io_size size)
+{
+	u8 tmp, cnt = 50;
+	u32 reg_cfg = REG_SDIO_INDIRECT_REG_CFG;
+	u32 reg_data = REG_SDIO_INDIRECT_REG_DATA;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_cfg);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_data);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	PLTFM_SDIO_CMD52_W(reg_cfg, (u8)adr);
+	PLTFM_SDIO_CMD52_W(reg_cfg + 1, (u8)(adr >> 8));
+	switch (size) {
+	case HALMAC_IO_BYTE:
+		PLTFM_SDIO_CMD52_W(reg_data, (u8)val);
+		PLTFM_SDIO_CMD52_W(reg_cfg + 2, (u8)(BIT(2) | BIT(4)));
+		break;
+	case HALMAC_IO_WORD:
+		PLTFM_SDIO_CMD52_W(reg_data, (u8)val);
+		PLTFM_SDIO_CMD52_W(reg_data + 1, (u8)(val >> 8));
+		PLTFM_SDIO_CMD52_W(reg_cfg + 2,
+				   (u8)(BIT(0) | BIT(2) | BIT(4)));
+		break;
+	case HALMAC_IO_DWORD:
+		PLTFM_SDIO_CMD52_W(reg_data, (u8)val);
+		PLTFM_SDIO_CMD52_W(reg_data + 1, (u8)(val >> 8));
+		PLTFM_SDIO_CMD52_W(reg_data + 2, (u8)(val >> 16));
+		PLTFM_SDIO_CMD52_W(reg_data + 3, (u8)(val >> 24));
+		PLTFM_SDIO_CMD52_W(reg_cfg + 2,
+				   (u8)(BIT(1) | BIT(2) | BIT(4)));
+		break;
+	default:
+		break;
+	}
+
+	do {
+		tmp = PLTFM_SDIO_CMD52_R(reg_cfg + 2);
+		cnt--;
+	} while (((tmp & BIT(4)) == 0) && (cnt > 0));
+
+	if (((cnt & BIT(4)) == 0) && cnt == 0)
+		pr_err("sdio indirect CMD52 write\n");
+
+	return status;
+}
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w_indir_cmd53_88xx(struct halmac_adapter *adapter, u32 adr, u32 val,
+		   enum halmac_io_size size)
+{
+	u8 tmp, cnt = 50;
+	u32 reg_cfg = REG_SDIO_INDIRECT_REG_CFG;
+	u32 reg_data = REG_SDIO_INDIRECT_REG_DATA;
+	u32 value32 = 0;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_cfg);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+	status = cnv_to_sdio_bus_offset_88xx(adapter, &reg_data);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	switch (size) {
+	case HALMAC_IO_BYTE:
+		value32 = adr | BIT(18) | BIT(20);
+		break;
+	case HALMAC_IO_WORD:
+		value32 = adr | BIT(16) | BIT(18) | BIT(20);
+		break;
+	case HALMAC_IO_DWORD:
+		value32 = adr | BIT(17) | BIT(18) | BIT(20);
+		break;
+	default:
+		return HALMAC_RET_FAIL;
+	}
+
+	PLTFM_SDIO_CMD53_W32(reg_data, val);
+	PLTFM_SDIO_CMD53_W32(reg_cfg, value32);
+
+	do {
+		tmp = PLTFM_SDIO_CMD52_R(reg_cfg + 2);
+		cnt--;
+	} while (((tmp & BIT(4)) == 0) && (cnt > 0));
+
+	if (((cnt & BIT(4)) == 0) && cnt == 0)
+		pr_err("sdio indirect CMD53 read\n");
+
+	return status;
+}
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w8_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr, u32 val)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (adapter->pwr_off_flow_flag == 1 ||
+	    adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
+		status = w_indir_cmd52_88xx(adapter, adr, val, HALMAC_IO_BYTE);
+	else
+		status = w_indir_cmd53_88xx(adapter, adr, val, HALMAC_IO_BYTE);
+	return status;
+}
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w16_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr, u32 val)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF) {
+		if (0 != (adr & (2 - 1))) {
+			status = w_indir_cmd52_88xx(adapter, adr, val,
+						    HALMAC_IO_BYTE);
+			if (status != HALMAC_RET_SUCCESS)
+				return status;
+			status = w_indir_cmd52_88xx(adapter, adr + 1, val >> 8,
+						    HALMAC_IO_BYTE);
+		} else {
+			status = w_indir_cmd52_88xx(adapter, adr, val,
+						    HALMAC_IO_WORD);
+		}
+	} else {
+		if (0 != (adr & (2 - 1))) {
+			status = w_indir_cmd53_88xx(adapter, adr, val,
+						    HALMAC_IO_BYTE);
+			if (status != HALMAC_RET_SUCCESS)
+				return status;
+			status = w_indir_cmd53_88xx(adapter, adr + 1, val >> 8,
+						    HALMAC_IO_BYTE);
+		} else {
+			status = w_indir_cmd53_88xx(adapter, adr, val,
+						    HALMAC_IO_WORD);
+		}
+	}
+	return status;
+}
+
+/*only for w_indir_sdio_88xx !!, Soar 20171222*/
+static enum halmac_ret_status
+w32_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr, u32 val)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF) {
+		if (0 != (adr & (4 - 1))) {
+			status = w_indir_cmd52_88xx(adapter, adr, val,
+						    HALMAC_IO_BYTE);
+			if (status != HALMAC_RET_SUCCESS)
+				return status;
+			status = w_indir_cmd52_88xx(adapter, adr + 1, val >> 8,
+						    HALMAC_IO_BYTE);
+			if (status != HALMAC_RET_SUCCESS)
+				return status;
+			status = w_indir_cmd52_88xx(adapter, adr + 2, val >> 16,
+						    HALMAC_IO_BYTE);
+			if (status != HALMAC_RET_SUCCESS)
+				return status;
+			status = w_indir_cmd52_88xx(adapter, adr + 3, val >> 24,
+						    HALMAC_IO_BYTE);
+		} else {
+			status = w_indir_cmd52_88xx(adapter, adr, val,
+						    HALMAC_IO_DWORD);
+		}
+	} else {
+		if (0 != (adr & (4 - 1))) {
+			status = w_indir_cmd53_88xx(adapter, adr, val,
+						    HALMAC_IO_BYTE);
+			if (status != HALMAC_RET_SUCCESS)
+				return status;
+			status = w_indir_cmd53_88xx(adapter, adr + 1, val >> 8,
+						    HALMAC_IO_BYTE);
+			if (status != HALMAC_RET_SUCCESS)
+				return status;
+			status = w_indir_cmd53_88xx(adapter, adr + 2, val >> 16,
+						    HALMAC_IO_BYTE);
+			if (status != HALMAC_RET_SUCCESS)
+				return status;
+			status = w_indir_cmd53_88xx(adapter, adr + 3, val >> 24,
+						    HALMAC_IO_BYTE);
+		} else {
+			status = w_indir_cmd53_88xx(adapter, adr, val,
+						    HALMAC_IO_DWORD);
+		}
+	}
+	return status;
+}
+
+enum halmac_ret_status
+w_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr, u32 val,
+		  enum halmac_io_size size)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	mutex_lock(&adapter->sdio_indir_mutex);
+
+	switch (size) {
+	case HALMAC_IO_BYTE:
+		status = w8_indir_sdio_88xx(adapter, adr, val);
+		break;
+	case HALMAC_IO_WORD:
+		status = w16_indir_sdio_88xx(adapter, adr, val);
+		break;
+	case HALMAC_IO_DWORD:
+		status = w32_indir_sdio_88xx(adapter, adr, val);
+		break;
+	default:
+		break;
+	}
+
+	mutex_unlock(&adapter->sdio_indir_mutex);
+
+	return status;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.h
new file mode 100644
index 000000000000..d16c80902486
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_sdio_88xx.h
@@ -0,0 +1,75 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_SDIO_88XX_H_
+#define _HALMAC_SDIO_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+init_sdio_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+deinit_sdio_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+cfg_sdio_rx_agg_88xx(struct halmac_adapter *adapter,
+		     struct halmac_rxagg_cfg *cfg);
+
+enum halmac_ret_status
+cfg_txagg_sdio_align_88xx(struct halmac_adapter *adapter, u8 enable,
+			  u16 align_size);
+
+u32
+sdio_indirect_reg_r32_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+sdio_reg_rn_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+		 u8 *value);
+
+enum halmac_ret_status
+set_sdio_bulkout_num_88xx(struct halmac_adapter *adapter, u8 num);
+
+enum halmac_ret_status
+get_sdio_bulkout_id_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+			 u8 *id);
+
+enum halmac_ret_status
+sdio_cmd53_4byte_88xx(struct halmac_adapter *adapter,
+		      enum halmac_sdio_cmd53_4byte_mode mode);
+
+enum halmac_ret_status
+sdio_hw_info_88xx(struct halmac_adapter *adapter,
+		  struct halmac_sdio_hw_info *info);
+
+void
+cfg_sdio_tx_page_threshold_88xx(struct halmac_adapter *adapter,
+				struct halmac_tx_page_threshold_info *info);
+
+enum halmac_ret_status
+cnv_to_sdio_bus_offset_88xx(struct halmac_adapter *adapter, u32 *offset);
+
+enum halmac_ret_status
+leave_sdio_suspend_88xx(struct halmac_adapter *adapter);
+
+u32
+r_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr,
+		  enum halmac_io_size size);
+
+enum halmac_ret_status
+w_indir_sdio_88xx(struct halmac_adapter *adapter, u32 adr, u32 val,
+		  enum halmac_io_size size);
+
+#endif/* _HALMAC_SDIO_88XX_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.c
new file mode 100644
index 000000000000..8ab1d31fb227
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.c
@@ -0,0 +1,522 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_usb_88xx.h"
+
+enum usb_burst_size {
+	USB_BURST_SIZE_3_0 = 0x0,
+	USB_BURST_SIZE_2_0_HS = 0x1,
+	USB_BURST_SIZE_2_0_FS = 0x2,
+	USB_BURST_SIZE_2_0_OTHERS = 0x3,
+	USB_BURST_SIZE_UNDEFINE = 0x7F,
+};
+
+/**
+ * init_usb_cfg_88xx() - init USB
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_usb_cfg_88xx(struct halmac_adapter *adapter)
+{
+	u8 value8 = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	value8 |= (BIT_DMA_MODE | (0x3 << BIT_SHIFT_BURST_CNT));
+
+	if (HALMAC_REG_R8(REG_SYS_CFG2 + 3) == 0x20) {
+		 /* usb3.0 */
+		value8 |= (USB_BURST_SIZE_3_0 << BIT_SHIFT_BURST_SIZE);
+	} else {
+		if ((HALMAC_REG_R8(REG_USB_USBSTAT) & 0x3) == 0x1)/* usb2.0 */
+			value8 |= USB_BURST_SIZE_2_0_HS << BIT_SHIFT_BURST_SIZE;
+		else /* usb1.1 */
+			value8 |= USB_BURST_SIZE_2_0_FS << BIT_SHIFT_BURST_SIZE;
+	}
+
+	HALMAC_REG_W8(REG_RXDMA_MODE, value8);
+	HALMAC_REG_W16_SET(REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * deinit_usb_cfg_88xx() - deinit USB
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+deinit_usb_cfg_88xx(struct halmac_adapter *adapter)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_usb_rx_agg_88xx() - config rx aggregation
+ * @adapter : the adapter of halmac
+ * @halmac_rx_agg_mode
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_usb_rx_agg_88xx(struct halmac_adapter *adapter,
+		    struct halmac_rxagg_cfg *cfg)
+{
+	u8 dma_usb_agg;
+	u8 size;
+	u8 timeout;
+	u8 agg_enable;
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	dma_usb_agg = HALMAC_REG_R8(REG_RXDMA_AGG_PG_TH + 3);
+	agg_enable = HALMAC_REG_R8(REG_TXDMA_PQ_MAP);
+
+	switch (cfg->mode) {
+	case HALMAC_RX_AGG_MODE_NONE:
+		agg_enable &= ~BIT_RXDMA_AGG_EN;
+		break;
+	case HALMAC_RX_AGG_MODE_DMA:
+		agg_enable |= BIT_RXDMA_AGG_EN;
+		dma_usb_agg |= BIT(7);
+		break;
+
+	case HALMAC_RX_AGG_MODE_USB:
+		agg_enable |= BIT_RXDMA_AGG_EN;
+		dma_usb_agg &= ~BIT(7);
+		break;
+	default:
+		pr_err("unsupported mode\n");
+		agg_enable &= ~BIT_RXDMA_AGG_EN;
+		break;
+	}
+
+	if (cfg->threshold.drv_define == 0) {
+		if (HALMAC_REG_R8(REG_SYS_CFG2 + 3) == 0x20) {
+			/* usb3.0 */
+			size = 0x5;
+			timeout = 0xA;
+		} else {
+			/* usb2.0 */
+			size = 0x5;
+			timeout = 0x20;
+		}
+	} else {
+		size = cfg->threshold.size;
+		timeout = cfg->threshold.timeout;
+	}
+
+	value32 = HALMAC_REG_R32(REG_RXDMA_AGG_PG_TH);
+	if (cfg->threshold.size_limit_en == 0)
+		HALMAC_REG_W32(REG_RXDMA_AGG_PG_TH, value32 & ~BIT_EN_PRE_CALC);
+	else
+		HALMAC_REG_W32(REG_RXDMA_AGG_PG_TH, value32 | BIT_EN_PRE_CALC);
+
+	HALMAC_REG_W8(REG_TXDMA_PQ_MAP, agg_enable);
+	HALMAC_REG_W8(REG_RXDMA_AGG_PG_TH + 3, dma_usb_agg);
+	HALMAC_REG_W16(REG_RXDMA_AGG_PG_TH,
+		       (u16)(size | (timeout << BIT_SHIFT_DMA_AGG_TO_V1)));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * reg_r8_usb_88xx() - read 1byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u8
+reg_r8_usb_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return PLTFM_REG_R8(offset);
+}
+
+/**
+ * reg_w8_usb_88xx() - write 1byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w8_usb_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
+{
+	PLTFM_REG_W8(offset, value);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * reg_r16_usb_88xx() - read 2byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u16
+reg_r16_usb_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return PLTFM_REG_R16(offset);
+}
+
+/**
+ * reg_w16_usb_88xx() - write 2byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w16_usb_88xx(struct halmac_adapter *adapter, u32 offset, u16 value)
+{
+	PLTFM_REG_W16(offset, value);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * reg_r32_usb_88xx() - read 4byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32
+reg_r32_usb_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return PLTFM_REG_R32(offset);
+}
+
+/**
+ * reg_w32_usb_88xx() - write 4byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @value : register value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+reg_w32_usb_88xx(struct halmac_adapter *adapter, u32 offset, u32 value)
+{
+	PLTFM_REG_W32(offset, value);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * set_usb_bulkout_num_88xx() - inform bulk-out num
+ * @adapter : the adapter of halmac
+ * @bulkout_num : usb bulk-out number
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+set_usb_bulkout_num_88xx(struct halmac_adapter *adapter, u8 num)
+{
+	adapter->bulkout_num = num;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * get_usb_bulkout_id_88xx() - get bulk out id for the TX packet
+ * @adapter : the adapter of halmac
+ * @buf : tx packet, include txdesc
+ * @size : tx packet size
+ * @id : usb bulk-out id
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_usb_bulkout_id_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+			u8 *id)
+{
+	enum halmac_qsel queue_sel;
+	enum halmac_dma_mapping dma_mapping;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (!buf) {
+		pr_err("buf is NULL!!\n");
+		return HALMAC_RET_DATA_BUF_NULL;
+	}
+
+	if (size == 0) {
+		pr_err("size is 0!!\n");
+		return HALMAC_RET_DATA_SIZE_INCORRECT;
+	}
+
+	queue_sel = (enum halmac_qsel)GET_TX_DESC_QSEL(buf);
+
+	switch (queue_sel) {
+	case HALMAC_QSEL_VO:
+	case HALMAC_QSEL_VO_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_VO];
+		break;
+	case HALMAC_QSEL_VI:
+	case HALMAC_QSEL_VI_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_VI];
+		break;
+	case HALMAC_QSEL_BE:
+	case HALMAC_QSEL_BE_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_BE];
+		break;
+	case HALMAC_QSEL_BK:
+	case HALMAC_QSEL_BK_V2:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_BK];
+		break;
+	case HALMAC_QSEL_MGNT:
+		dma_mapping = adapter->pq_map[HALMAC_PQ_MAP_MG];
+		break;
+	case HALMAC_QSEL_HIGH:
+	case HALMAC_QSEL_BCN:
+	case HALMAC_QSEL_CMD:
+		dma_mapping = HALMAC_DMA_MAPPING_HIGH;
+		break;
+	default:
+		pr_err("Qsel is out of range\n");
+		return HALMAC_RET_QSEL_INCORRECT;
+	}
+
+	switch (dma_mapping) {
+	case HALMAC_DMA_MAPPING_HIGH:
+		*id = 0;
+		break;
+	case HALMAC_DMA_MAPPING_NORMAL:
+		*id = 1;
+		break;
+	case HALMAC_DMA_MAPPING_LOW:
+		*id = 2;
+		break;
+	case HALMAC_DMA_MAPPING_EXTRA:
+		*id = 3;
+		break;
+	default:
+		pr_err("out of range\n");
+		return HALMAC_RET_DMA_MAP_INCORRECT;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_txagg_usb_align_88xx() -config sdio bus tx agg alignment
+ * @adapter : the adapter of halmac
+ * @enable : function enable(1)/disable(0)
+ * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
+ * Author : Soar Tu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_txagg_usb_align_88xx(struct halmac_adapter *adapter, u8 enable,
+			 u16 align_size)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * tx_allowed_usb_88xx() - check tx status
+ * @adapter : the adapter of halmac
+ * @buf : tx packet, include txdesc
+ * @size : tx packet size, include txdesc
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+tx_allowed_usb_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * usb_indirect_reg_r32_88xx() - read MAC reg by SDIO reg
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+u32
+usb_indirect_reg_r32_88xx(struct halmac_adapter *adapter, u32 offset)
+{
+	return 0xFFFFFFFF;
+}
+
+/**
+ * usb_reg_rn_88xx() - read n byte register
+ * @adapter : the adapter of halmac
+ * @offset : register offset
+ * @size : register value size
+ * @value : register value
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+usb_reg_rn_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+		u8 *value)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+/**
+ * get_usb_tx_addr_88xx() - get CMD53 addr for the TX packet
+ * @adapter : the adapter of halmac
+ * @buf : tx packet, include txdesc
+ * @size : tx packet size
+ * @pcmd53_addr : cmd53 addr value
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_usb_tx_addr_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+		     u32 *cmd53_addr)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+enum halmac_ret_status
+set_usb_mode_88xx(struct halmac_adapter *adapter, enum halmac_usb_mode mode)
+{
+	u32 usb_tmp;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_usb_mode cur_mode;
+
+	cur_mode = (HALMAC_REG_R8(REG_SYS_CFG2 + 3) == 0x20) ?
+					HALMAC_USB_MODE_U3 : HALMAC_USB_MODE_U2;
+
+	/* check if HW supports usb2_usb3 switch */
+	usb_tmp = HALMAC_REG_R32(REG_PAD_CTRL2);
+	if (0 == (BIT_GET_USB23_SW_MODE_V1(usb_tmp) |
+	    (usb_tmp & BIT_USB3_USB2_TRANSITION))) {
+		pr_err("u2/u3 switch\n");
+		return HALMAC_RET_USB2_3_SWITCH_UNSUPPORT;
+	}
+
+	if (mode == cur_mode) {
+		pr_err("u2/u3 unchange\n");
+		return HALMAC_RET_USB_MODE_UNCHANGE;
+	}
+
+	/* Enable IO wrapper timeout */
+	if (adapter->chip_id == HALMAC_CHIP_ID_8822B ||
+	    adapter->chip_id == HALMAC_CHIP_ID_8821C)
+		HALMAC_REG_W8_CLR(REG_SW_MDIO + 3, BIT(0));
+
+	usb_tmp &= ~(BIT_USB23_SW_MODE_V1(0x3));
+
+	if (mode == HALMAC_USB_MODE_U2)
+		HALMAC_REG_W32(REG_PAD_CTRL2,
+			       usb_tmp |
+			       BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U2) |
+			       BIT_RSM_EN_V1);
+	else
+		HALMAC_REG_W32(REG_PAD_CTRL2,
+			       usb_tmp |
+			       BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U3) |
+			       BIT_RSM_EN_V1);
+
+	HALMAC_REG_W8(REG_PAD_CTRL2 + 1, 4);
+	HALMAC_REG_W16_SET(REG_SYS_PW_CTRL, BIT_APFM_OFFMAC);
+	usleep_range(1000, 1100);
+	HALMAC_REG_W32_SET(REG_PAD_CTRL2, BIT_NO_PDN_CHIPOFF_V1);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+usbphy_write_88xx(struct halmac_adapter *adapter, u8 addr, u16 data, u8 speed)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (speed == HAL_INTF_PHY_USB3) {
+		HALMAC_REG_W8(0xff0d, (u8)data);
+		HALMAC_REG_W8(0xff0e, (u8)(data >> 8));
+		HALMAC_REG_W8(0xff0c, addr | BIT(7));
+	} else if (speed == HAL_INTF_PHY_USB2) {
+		HALMAC_REG_W8(0xfe41, (u8)data);
+		HALMAC_REG_W8(0xfe40, addr);
+		HALMAC_REG_W8(0xfe42, 0x81);
+	} else {
+		pr_err("Error USB Speed !\n");
+		return HALMAC_RET_NOT_SUPPORT;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+u16
+usbphy_read_88xx(struct halmac_adapter *adapter, u8 addr, u8 speed)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u16 value = 0;
+
+	if (speed == HAL_INTF_PHY_USB3) {
+		HALMAC_REG_W8(0xff0c, addr | BIT(6));
+		value = (u16)(HALMAC_REG_R32(0xff0c) >> 8);
+	} else if (speed == HAL_INTF_PHY_USB2) {
+		if (addr >= 0xE0)
+			addr -= 0x20;
+		if (addr >= 0xC0 && addr <= 0xDF) {
+			HALMAC_REG_W8(0xfe40, addr);
+			HALMAC_REG_W8(0xfe42, 0x81);
+			value = HALMAC_REG_R8(0xfe43);
+		} else {
+			pr_err("phy offset\n");
+			return HALMAC_RET_NOT_SUPPORT;
+		}
+	} else {
+		pr_err("usb speed !\n");
+		return HALMAC_RET_NOT_SUPPORT;
+	}
+
+	return value;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.h
new file mode 100644
index 000000000000..895215f8df1f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_usb_88xx.h
@@ -0,0 +1,83 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_USB_88XX_H_
+#define _HALMAC_USB_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+init_usb_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+deinit_usb_cfg_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+cfg_usb_rx_agg_88xx(struct halmac_adapter *adapter,
+		    struct halmac_rxagg_cfg *cfg);
+
+u8
+reg_r8_usb_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w8_usb_88xx(struct halmac_adapter *adapter, u32 offset, u8 value);
+
+u16
+reg_r16_usb_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w16_usb_88xx(struct halmac_adapter *adapter, u32 offset, u16 value);
+
+u32
+reg_r32_usb_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+reg_w32_usb_88xx(struct halmac_adapter *adapter, u32 offset, u32 value);
+
+enum halmac_ret_status
+set_usb_bulkout_num_88xx(struct halmac_adapter *adapter, u8 num);
+
+enum halmac_ret_status
+get_usb_bulkout_id_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+			u8 *id);
+
+enum halmac_ret_status
+cfg_txagg_usb_align_88xx(struct halmac_adapter *adapter, u8 enable,
+			 u16 align_size);
+
+enum halmac_ret_status
+tx_allowed_usb_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+u32
+usb_indirect_reg_r32_88xx(struct halmac_adapter *adapter, u32 offset);
+
+enum halmac_ret_status
+usb_reg_rn_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+		u8 *value);
+
+enum halmac_ret_status
+get_usb_tx_addr_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+		     u32 *cmd53_addr);
+
+enum halmac_ret_status
+set_usb_mode_88xx(struct halmac_adapter *adapter, enum halmac_usb_mode mode);
+
+enum halmac_ret_status
+usbphy_write_88xx(struct halmac_adapter *adapter, u8 addr, u16 data, u8 speed);
+
+u16
+usbphy_read_88xx(struct halmac_adapter *adapter, u8 addr, u8 speed);
+
+#endif/* _HALMAC_API_88XX_USB_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_intf_phy_cmd.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_intf_phy_cmd.h
new file mode 100644
index 000000000000..f44bfa11e4d9
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_intf_phy_cmd.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef HALMAC_INTF_PHY_CMD
+#define HALMAC_INTF_PHY_CMD
+
+/* Cut mask */
+enum halmac_intf_phy_cut {
+	HALMAC_INTF_PHY_CUT_TESTCHIP = BIT(0),
+	HALMAC_INTF_PHY_CUT_A = BIT(1),
+	HALMAC_INTF_PHY_CUT_B = BIT(2),
+	HALMAC_INTF_PHY_CUT_C = BIT(3),
+	HALMAC_INTF_PHY_CUT_D = BIT(4),
+	HALMAC_INTF_PHY_CUT_E = BIT(5),
+	HALMAC_INTF_PHY_CUT_F = BIT(6),
+	HALMAC_INTF_PHY_CUT_G = BIT(7),
+	HALMAC_INTF_PHY_CUT_ALL = 0x7FFF,
+};
+
+/* IP selection */
+enum halmac_ip_sel {
+	HALMAC_IP_INTF_PHY = 0,
+	HALMAC_IP_SEL_MAC = 1,
+	HALMAC_IP_PCIE_DBI = 2,
+	HALMAC_IP_SEL_UNDEFINE = 0x7FFF,
+};
+
+/* Platform mask */
+enum halmac_intf_phy_platform {
+	HALMAC_INTF_PHY_PLATFORM_ALL = 0x7FFF,
+};
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pcie_reg.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pcie_reg.h
new file mode 100644
index 000000000000..a2406bea00be
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_pcie_reg.h
@@ -0,0 +1,36 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef __HALMAC_PCIE_REG_H__
+#define __HALMAC_PCIE_REG_H__
+
+/* PCIE PHY register */
+#define RAC_CTRL_PPR		0x00
+#define RAC_SET_PPR		0x20
+#define RAC_TRG_PPR		0x21
+
+/* PCIE CFG register */
+#define PCIE_L1_BACKDOOR		0x719
+#define PCIE_ASPM_CTRL			0x70F
+
+/* PCIE MAC register */
+#define LINK_CTRL2_REG_OFFSET		0xA0
+#define GEN2_CTRL_OFFSET		0x80C
+#define LINK_STATUS_REG_OFFSET		0x82
+
+#define PCIE_GEN1_SPEED			0x01
+#define PCIE_GEN2_SPEED			0x02
+
+#endif/* __HALMAC_PCIE_REG_H__ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_sdio_reg.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_sdio_reg.h
new file mode 100644
index 000000000000..53b6b85d0e43
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_sdio_reg.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef __HALMAC_SDIO_REG_H__
+#define __HALMAC_SDIO_REG_H__
+
+/* SDIO CMD address mapping */
+
+#define HALMAC_SDIO_4BYTE_LEN_MASK      0x1FFF
+#define HALMAC_SDIO_LOCAL_MSK           0x0FFF
+#define HALMAC_WLAN_MAC_REG_MSK		0xFFFF
+#define	HALMAC_WLAN_IOREG_MSK		0xFFFF
+
+/* Sdio Address for SDIO Local Reg, TRX FIFO, MAC Reg */
+enum halmac_sdio_cmd_addr {
+	HALMAC_SDIO_CMD_ADDR_SDIO_REG = 0,
+	HALMAC_SDIO_CMD_ADDR_MAC_REG = 8,
+	HALMAC_SDIO_CMD_ADDR_TXFF_HIGH = 4,
+	HALMAC_SDIO_CMD_ADDR_TXFF_LOW = 6,
+	HALMAC_SDIO_CMD_ADDR_TXFF_NORMAL = 5,
+	HALMAC_SDIO_CMD_ADDR_TXFF_EXTRA = 7,
+	HALMAC_SDIO_CMD_ADDR_RXFF = 7,
+};
+
+/* IO Bus domain address mapping */
+#define SDIO_LOCAL_OFFSET		0x10250000
+#define WLAN_IOREG_OFFSET		0x10260000
+#define FW_FIFO_OFFSET			0x10270000
+#define TX_HIQ_OFFSET			0x10310000
+#define TX_MIQ_OFFSET			0x10320000
+#define TX_LOQ_OFFSET			0x10330000
+#define TX_EXQ_OFFSET			0x10350000
+#define RX_RXOFF_OFFSET			0x10340000
+
+/* Get TX WLAN FIFO information in CMD53 addr  */
+#define GET_WLAN_TXFF_DEVICE_ID(cmd53_addr) \
+			LE_BITS_TO_4BYTE((u32 *)cmd53_addr, 13, 4)
+#define GET_WLAN_TXFF_PKT_SIZE(cmd53_addr) \
+			(LE_BITS_TO_4BYTE((u32 *)cmd53_addr, 0, 13) << 2)
+
+#endif/* __HALMAC_SDIO_REG_H__ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_usb_reg.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_usb_reg.h
new file mode 100644
index 000000000000..b856c55ef6cf
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_usb_reg.h
@@ -0,0 +1,19 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef __HALMAC_USB_REG_H__
+#define __HALMAC_USB_REG_H__
+
+#endif/* __HALMAC_USB_REG_H__ */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 15/17] rtlwifi: halmac: add to control WiFi mac functions and registers
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (12 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 14/17] rtlwifi: halmac: add bus interface commands pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 16/17] rtlwifi: halmac: add to support BB and RF functions pkshih
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

This commit provides WiFi mac functions to control wifi easier, and also
provides generic access entries for driver and other modules.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../halmac_8822b/halmac_cfg_wmac_8822b.c           |  144 +
 .../halmac_8822b/halmac_cfg_wmac_8822b.h           |   36 +
 .../halmac_88xx/halmac_8822b/halmac_common_8822b.c |  173 ++
 .../halmac_88xx/halmac_8822b/halmac_common_8822b.h |   32 +
 .../halmac/halmac_88xx/halmac_cfg_wmac_88xx.c      | 1158 ++++++++
 .../halmac/halmac_88xx/halmac_cfg_wmac_88xx.h      |  122 +
 .../halmac/halmac_88xx/halmac_common_88xx.c        | 2931 ++++++++++++++++++++
 .../halmac/halmac_88xx/halmac_common_88xx.h        |  151 +
 8 files changed, 4747 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.c
new file mode 100644
index 000000000000..7de83d7bf922
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.c
@@ -0,0 +1,144 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2017 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_cfg_wmac_8822b.h"
+#include "halmac_8822b_cfg.h"
+
+/**
+ * cfg_drv_info_8822b() - config driver info
+ * @adapter : the adapter of halmac
+ * @drv_info : driver information selection
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_drv_info_8822b(struct halmac_adapter *adapter,
+		   enum halmac_drv_info drv_info)
+{
+	u8 drv_info_size = 0;
+	u8 phy_status_en = 0;
+	u8 sniffer_en = 0;
+	u8 plcp_hdr_en = 0;
+	u8 value8;
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "drv info = %d\n", drv_info);
+
+	switch (drv_info) {
+	case HALMAC_DRV_INFO_NONE:
+		drv_info_size = 0;
+		phy_status_en = 0;
+		sniffer_en = 0;
+		plcp_hdr_en = 0;
+		break;
+	case HALMAC_DRV_INFO_PHY_STATUS:
+		drv_info_size = 4;
+		phy_status_en = 1;
+		sniffer_en = 0;
+		plcp_hdr_en = 0;
+		break;
+	case HALMAC_DRV_INFO_PHY_SNIFFER:
+		drv_info_size = 5; /* phy status 4byte, sniffer info 1byte */
+		phy_status_en = 1;
+		sniffer_en = 1;
+		plcp_hdr_en = 0;
+		break;
+	case HALMAC_DRV_INFO_PHY_PLCP:
+		drv_info_size = 6; /* phy status 4byte, plcp header 2byte */
+		phy_status_en = 1;
+		sniffer_en = 0;
+		plcp_hdr_en = 1;
+		break;
+	default:
+		return HALMAC_RET_SW_CASE_NOT_SUPPORT;
+	}
+
+	if (adapter->txff_alloc.rx_fifo_exp_mode !=
+	    HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE)
+		drv_info_size = RX_DESC_DUMMY_SIZE_8822B >> 3;
+
+	HALMAC_REG_W8(REG_RX_DRVINFO_SZ, drv_info_size);
+
+	value8 = HALMAC_REG_R8(REG_TRXFF_BNDY + 1);
+	value8 &= 0xF0;
+	/* For rxdesc len = 0 issue */
+	value8 |= 0xF;
+	HALMAC_REG_W8(REG_TRXFF_BNDY + 1, value8);
+
+	adapter->drv_info_size = drv_info_size;
+
+	value32 = HALMAC_REG_R32(REG_RCR);
+	value32 = (value32 & (~BIT_APP_PHYSTS));
+	if (phy_status_en == 1)
+		value32 = value32 | BIT_APP_PHYSTS;
+	HALMAC_REG_W32(REG_RCR, value32);
+
+	value32 = HALMAC_REG_R32(REG_WMAC_OPTION_FUNCTION + 4);
+	value32 = (value32 & (~(BIT(8) | BIT(9))));
+	if (sniffer_en == 1)
+		value32 = value32 | BIT(9);
+	if (plcp_hdr_en == 1)
+		value32 = value32 | BIT(8);
+	HALMAC_REG_W32(REG_WMAC_OPTION_FUNCTION + 4, value32);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * init_low_pwr_8822b() - config WMAC register
+ * @adapter
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+init_low_pwr_8822b(struct halmac_adapter *adapter)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+void
+cfg_rx_ignore_8822b(struct halmac_adapter *adapter,
+		    struct halmac_mac_rx_ignore_cfg *cfg)
+{
+}
+
+enum halmac_ret_status
+cfg_ampdu_8822b(struct halmac_adapter *adapter,
+		struct halmac_ampdu_config *cfg)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (cfg->ht_max_len != cfg->vht_max_len) {
+		pr_err("max len ht != vht!!\n");
+		return HALMAC_RET_PARA_NOT_SUPPORT;
+	}
+
+	HALMAC_REG_W8(REG_PROT_MODE_CTRL + 2, cfg->max_agg_num);
+	HALMAC_REG_W8(REG_PROT_MODE_CTRL + 3, cfg->max_agg_num);
+
+	if (cfg->max_len_en == 1)
+		HALMAC_REG_W32(REG_AMPDU_MAX_LENGTH, cfg->ht_max_len);
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.h
new file mode 100644
index 000000000000..36f54e74abff
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.h
@@ -0,0 +1,36 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2017 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_CFG_WMAC_8822B_H_
+#define _HALMAC_CFG_WMAC_8822B_H_
+
+#include "../../halmac_api.h"
+
+enum halmac_ret_status
+cfg_drv_info_8822b(struct halmac_adapter *adapter,
+		   enum halmac_drv_info drv_info);
+
+enum halmac_ret_status
+init_low_pwr_8822b(struct halmac_adapter *adapter);
+
+void
+cfg_rx_ignore_8822b(struct halmac_adapter *adapter,
+		    struct halmac_mac_rx_ignore_cfg *cfg);
+
+enum halmac_ret_status
+cfg_ampdu_8822b(struct halmac_adapter *adapter,
+		struct halmac_ampdu_config *cfg);
+
+#endif/* _HALMAC_CFG_WMAC_8822B_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.c
new file mode 100644
index 000000000000..bc51d941cb0c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.c
@@ -0,0 +1,173 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2017 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_8822b_cfg.h"
+#include "halmac_common_8822b.h"
+#include "../halmac_common_88xx.h"
+#include "halmac_cfg_wmac_8822b.h"
+
+static void
+cfg_ldo25_8822b(struct halmac_adapter *adapter, u8 enable);
+
+/**
+ * get_hw_value_8822b() -get hw config value
+ * @adapter : the adapter of halmac
+ * @hw_id : hw id for driver to query
+ * @pvalue : hw value, reference table to get data type
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_hw_value_8822b(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
+		   void *value)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (!value) {
+		pr_err("%s (NULL ==pvalue)\n", __func__);
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	if (get_hw_value_88xx(adapter, hw_id, value) == HALMAC_RET_SUCCESS)
+		return HALMAC_RET_SUCCESS;
+
+	switch (hw_id) {
+	case HALMAC_HW_FW_MAX_SIZE:
+		*(u32 *)value = WLAN_FW_MAX_SIZE_8822B;
+		break;
+	case HALMAC_HW_SDIO_INT_LAT:
+		break;
+	case HALMAC_HW_SDIO_CLK_CNT:
+		break;
+	default:
+		return HALMAC_RET_PARA_NOT_SUPPORT;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * set_hw_value_8822b() -set hw config value
+ * @adapter : the adapter of halmac
+ * @hw_id : hw id for driver to config
+ * @pvalue : hw value, reference table to get data type
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+set_hw_value_8822b(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
+		   void *value)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (!value) {
+		pr_err("null pointer\n");
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	if (set_hw_value_88xx(adapter, hw_id, value) == HALMAC_RET_SUCCESS)
+		return HALMAC_RET_SUCCESS;
+
+	switch (hw_id) {
+	case HALMAC_HW_AMPDU_CONFIG:
+		status = cfg_ampdu_8822b(adapter,
+					 (struct halmac_ampdu_config *)value);
+		break;
+	case HALMAC_HW_SDIO_TX_FORMAT:
+		break;
+	case HALMAC_HW_RXGCK_FIFO:
+		break;
+	case HALMAC_HW_RX_IGNORE:
+		break;
+	case HALMAC_HW_LDO25_EN:
+		cfg_ldo25_8822b(adapter, *(u8 *)value);
+		break;
+	case HALMAC_HW_PCIE_REF_AUTOK:
+		break;
+	case HALMAC_HW_SDIO_WT_EN:
+		break;
+	case HALMAC_HW_SDIO_CLK_MONITOR:
+		break;
+	default:
+		return HALMAC_RET_PARA_NOT_SUPPORT;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return status;
+}
+
+/**
+ * halmac_fill_txdesc_check_sum_88xx() -  fill in tx desc check sum
+ * @adapter : the adapter of halmac
+ * @txdesc : tx desc packet
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+fill_txdesc_check_sum_8822b(struct halmac_adapter *adapter, u8 *txdesc)
+{
+	__le16 chksum = 0;
+	__le16 *data;
+	u32 i;
+
+	if (!txdesc) {
+		pr_err("null pointer");
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	if (adapter->tx_desc_checksum != 1)
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "chksum disable");
+
+	SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000);
+
+	data = (__le16 *)(txdesc);
+
+	/* HW clculates only 32byte */
+	for (i = 0; i < 8; i++)
+		chksum ^= (*(data + 2 * i) ^ *(data + (2 * i + 1)));
+
+	/* *(data + 2 * i) & *(data + (2 * i + 1) have endain issue*/
+	/* Process eniadn issue after checksum calculation */
+	SET_TX_DESC_TXDESC_CHECKSUM(txdesc, le16_to_cpu(chksum));
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+cfg_ldo25_8822b(struct halmac_adapter *adapter, u8 enable)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	value8 = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 3);
+
+	if (enable == 1)
+		HALMAC_REG_W8(REG_LDO_EFUSE_CTRL + 3, (u8)(value8 | BIT(7)));
+	else
+		HALMAC_REG_W8(REG_LDO_EFUSE_CTRL + 3, (u8)(value8 & ~BIT(7)));
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.h
new file mode 100644
index 000000000000..5484d1e73202
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_8822b/halmac_common_8822b.h
@@ -0,0 +1,32 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2017 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_COMMON_8822B_H_
+#define _HALMAC_COMMON_8822B_H_
+
+#include "../../halmac_api.h"
+
+enum halmac_ret_status
+get_hw_value_8822b(struct halmac_adapter *adapter,
+		   enum halmac_hw_id hw_id, void *value);
+
+enum halmac_ret_status
+set_hw_value_8822b(struct halmac_adapter *adapter,
+		   enum halmac_hw_id hw_id, void *value);
+
+enum halmac_ret_status
+fill_txdesc_check_sum_8822b(struct halmac_adapter *adapter, u8 *txdesc);
+
+#endif/* _HALMAC_COMMON_8822B_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.c
new file mode 100644
index 000000000000..f2214cdf30a5
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.c
@@ -0,0 +1,1158 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_cfg_wmac_88xx.h"
+#include "halmac_88xx_cfg.h"
+
+#define MAC_CLK_SPEED	80 /* 80M */
+
+enum mac_clock_hw_def {
+	MAC_CLK_HW_DEF_80M = 0,
+	MAC_CLK_HW_DEF_40M = 1,
+	MAC_CLK_HW_DEF_20M = 2,
+};
+
+/**
+ * cfg_mac_addr_88xx() - config mac address
+ * @adapter : the adapter of halmac
+ * @port : 0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @addr : mac address
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_mac_addr_88xx(struct halmac_adapter *adapter, u8 port,
+		  union halmac_wlan_addr *addr)
+{
+	u32 offset;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (port >= HALMAC_PORTID_NUM) {
+		pr_err("port index >= 5\n");
+		return HALMAC_RET_PORT_NOT_SUPPORT;
+	}
+
+	switch (port) {
+	case HALMAC_PORTID0:
+		offset = REG_MACID;
+		break;
+	case HALMAC_PORTID1:
+		offset = REG_MACID1;
+		break;
+	case HALMAC_PORTID2:
+		offset = REG_MACID2;
+		break;
+	case HALMAC_PORTID3:
+		offset = REG_MACID3;
+		break;
+	case HALMAC_PORTID4:
+		offset = REG_MACID4;
+		break;
+	default:
+		break;
+	}
+
+	HALMAC_REG_W32(offset, le32_to_cpu(addr->addr_l_h.low));
+	HALMAC_REG_W16(offset + 4, le16_to_cpu(addr->addr_l_h.high));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_bssid_88xx() - config BSSID
+ * @adapter : the adapter of halmac
+ * @port : 0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @addr : bssid
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_bssid_88xx(struct halmac_adapter *adapter, u8 port,
+	       union halmac_wlan_addr *addr)
+{
+	u32 offset;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (port >= HALMAC_PORTID_NUM) {
+		pr_err("port index > 5\n");
+		return HALMAC_RET_PORT_NOT_SUPPORT;
+	}
+
+	switch (port) {
+	case HALMAC_PORTID0:
+		offset = REG_BSSID;
+		break;
+	case HALMAC_PORTID1:
+		offset = REG_BSSID1;
+		break;
+	case HALMAC_PORTID2:
+		offset = REG_BSSID2;
+		break;
+	case HALMAC_PORTID3:
+		offset = REG_BSSID3;
+		break;
+	case HALMAC_PORTID4:
+		offset = REG_BSSID4;
+		break;
+	default:
+		break;
+	}
+
+	HALMAC_REG_W32(offset, le32_to_cpu(addr->addr_l_h.low));
+	HALMAC_REG_W16(offset + 4, le16_to_cpu(addr->addr_l_h.high));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_transmitter_addr_88xx() - config transmitter address
+ * @adapter : the adapter of halmac
+ * @port :  0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @addr :
+ * Author : Alan
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+cfg_transmitter_addr_88xx(struct halmac_adapter *adapter, u8 port,
+			  union halmac_wlan_addr *addr)
+{
+	u32 offset;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (port >= HALMAC_PORTID_NUM) {
+		pr_err("port index > 5\n");
+		return HALMAC_RET_PORT_NOT_SUPPORT;
+	}
+
+	switch (port) {
+	case HALMAC_PORTID0:
+		offset = REG_TRANSMIT_ADDRSS_0;
+		break;
+	case HALMAC_PORTID1:
+		offset = REG_TRANSMIT_ADDRSS_1;
+		break;
+	case HALMAC_PORTID2:
+		offset = REG_TRANSMIT_ADDRSS_2;
+		break;
+	case HALMAC_PORTID3:
+		offset = REG_TRANSMIT_ADDRSS_3;
+		break;
+	case HALMAC_PORTID4:
+		offset = REG_TRANSMIT_ADDRSS_4;
+		break;
+	default:
+		break;
+	}
+
+	HALMAC_REG_W32(offset, le32_to_cpu(addr->addr_l_h.low));
+	HALMAC_REG_W16(offset + 4, le16_to_cpu(addr->addr_l_h.high));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_net_type_88xx() - config network type
+ * @adapter : the adapter of halmac
+ * @port :  0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @addr : mac address
+ * Author : Alan
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+cfg_net_type_88xx(struct halmac_adapter *adapter, u8 port,
+		  enum halmac_network_type_select net_type)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u8 value8 = 0;
+	u8 net_type_tmp = 0;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (net_type == HALMAC_NETWORK_AP) {
+		if (port >= HALMAC_PORTID1) {
+			pr_err("AP port > 1\n");
+			return HALMAC_RET_PORT_NOT_SUPPORT;
+		}
+	}
+
+	switch (port) {
+	case HALMAC_PORTID0:
+		net_type_tmp = net_type;
+		value8 = ((HALMAC_REG_R8(REG_CR + 2) & 0xFC) | net_type_tmp);
+		HALMAC_REG_W8(REG_CR + 2, value8);
+		break;
+	case HALMAC_PORTID1:
+		net_type_tmp = (net_type << 2);
+		value8 = ((HALMAC_REG_R8(REG_CR + 2) & 0xF3) | net_type_tmp);
+		HALMAC_REG_W8(REG_CR + 2, value8);
+		break;
+	case HALMAC_PORTID2:
+		net_type_tmp = net_type;
+		value8 = ((HALMAC_REG_R8(REG_CR_EXT) & 0xFC) | net_type_tmp);
+		HALMAC_REG_W8(REG_CR_EXT, value8);
+		break;
+	case HALMAC_PORTID3:
+		net_type_tmp = (net_type << 2);
+		value8 = ((HALMAC_REG_R8(REG_CR_EXT) & 0xF3) | net_type_tmp);
+		HALMAC_REG_W8(REG_CR_EXT, value8);
+		break;
+	case HALMAC_PORTID4:
+		net_type_tmp = (net_type << 4);
+		value8 = ((HALMAC_REG_R8(REG_CR_EXT) & 0xCF) | net_type_tmp);
+		HALMAC_REG_W8(REG_CR_EXT, value8);
+		break;
+	default:
+		break;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_tsf_rst_88xx() - tsf reset
+ * @adapter : the adapter of halmac
+ * @port :  0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * Author : Alan
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+cfg_tsf_rst_88xx(struct halmac_adapter *adapter, u8 port)
+{
+	u8 tsf_rst = 0;
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	switch (port) {
+	case HALMAC_PORTID0:
+		tsf_rst = BIT_TSFTR_RST;
+		break;
+	case HALMAC_PORTID1:
+		tsf_rst = BIT_TSFTR_CLI0_RST;
+		break;
+	case HALMAC_PORTID2:
+		tsf_rst = BIT_TSFTR_CLI1_RST;
+		break;
+	case HALMAC_PORTID3:
+		tsf_rst = BIT_TSFTR_CLI2_RST;
+		break;
+	case HALMAC_PORTID4:
+		tsf_rst = BIT_TSFTR_CLI3_RST;
+		break;
+	default:
+		break;
+	}
+
+	value8 = HALMAC_REG_R8(REG_DUAL_TSF_RST);
+	HALMAC_REG_W8(REG_DUAL_TSF_RST, value8 | tsf_rst);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_bcn_space_88xx() - config beacon space
+ * @adapter : the adapter of halmac
+ * @port :  0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @bcn_space : beacon space
+ * Author : Alan
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+cfg_bcn_space_88xx(struct halmac_adapter *adapter, u8 port, u32 bcn_space)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u16 bcn_space_real = 0;
+	u16 value16 = 0;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	bcn_space_real = ((u16)bcn_space);
+
+	switch (port) {
+	case HALMAC_PORTID0:
+		HALMAC_REG_W16(REG_MBSSID_BCN_SPACE, bcn_space_real);
+		break;
+	case HALMAC_PORTID1:
+		value16 = HALMAC_REG_R16(REG_MBSSID_BCN_SPACE + 2) & 0xF000;
+		value16 |= bcn_space_real;
+		HALMAC_REG_W16(REG_MBSSID_BCN_SPACE + 2, value16);
+		break;
+	case HALMAC_PORTID2:
+		value16 = HALMAC_REG_R16(REG_MBSSID_BCN_SPACE2) & 0xF000;
+		value16 |= bcn_space_real;
+		HALMAC_REG_W16(REG_MBSSID_BCN_SPACE2, value16);
+		break;
+	case HALMAC_PORTID3:
+		value16 = HALMAC_REG_R16(REG_MBSSID_BCN_SPACE2 + 2) & 0xF000;
+		value16 |= bcn_space_real;
+		HALMAC_REG_W16(REG_MBSSID_BCN_SPACE2 + 2, value16);
+		break;
+	case HALMAC_PORTID4:
+		value16 = HALMAC_REG_R16(REG_MBSSID_BCN_SPACE3) & 0xF000;
+		value16 |= bcn_space_real;
+		HALMAC_REG_W16(REG_MBSSID_BCN_SPACE3, value16);
+		break;
+	default:
+		break;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * rw_bcn_ctrl_88xx() - r/w beacon control
+ * @adapter : the adapter of halmac
+ * @port :  0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @write_en : 1->write beacon function 0->read beacon function
+ * @pBcn_ctrl : beacon control info
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+rw_bcn_ctrl_88xx(struct halmac_adapter *adapter, u8 port, u8 write_en,
+		 struct halmac_bcn_ctrl *ctrl)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u8 ctrl_value = 0;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (write_en) {
+		if (ctrl->dis_rx_bssid_fit == 1)
+			ctrl_value |= BIT_DIS_RX_BSSID_FIT;
+
+		if (ctrl->en_txbcn_rpt == 1)
+			ctrl_value |= BIT_P0_EN_TXBCN_RPT;
+
+		if (ctrl->dis_tsf_udt == 1)
+			ctrl_value |= BIT_DIS_TSF_UDT;
+
+		if (ctrl->en_bcn == 1)
+			ctrl_value |= BIT_EN_BCN_FUNCTION;
+
+		if (ctrl->en_rxbcn_rpt == 1)
+			ctrl_value |= BIT_P0_EN_RXBCN_RPT;
+
+		if (ctrl->en_p2p_ctwin == 1)
+			ctrl_value |= BIT_EN_P2P_CTWINDOW;
+
+		if (ctrl->en_p2p_bcn_area == 1)
+			ctrl_value |= BIT_EN_P2P_BCNQ_AREA;
+
+		switch (port) {
+		case HALMAC_PORTID0:
+			HALMAC_REG_W8(REG_BCN_CTRL, ctrl_value);
+			break;
+		case HALMAC_PORTID1:
+			HALMAC_REG_W8(REG_BCN_CTRL_CLINT0, ctrl_value);
+			break;
+		case HALMAC_PORTID2:
+			HALMAC_REG_W8(REG_BCN_CTRL_CLINT1, ctrl_value);
+			break;
+		case HALMAC_PORTID3:
+			HALMAC_REG_W8(REG_BCN_CTRL_CLINT2, ctrl_value);
+			break;
+		case HALMAC_PORTID4:
+			HALMAC_REG_W8(REG_BCN_CTRL_CLINT3, ctrl_value);
+			break;
+		default:
+			break;
+		}
+
+	} else {
+		switch (port) {
+		case HALMAC_PORTID0:
+			ctrl_value = HALMAC_REG_R8(REG_BCN_CTRL);
+			break;
+		case HALMAC_PORTID1:
+			ctrl_value = HALMAC_REG_R8(REG_BCN_CTRL_CLINT0);
+			break;
+		case HALMAC_PORTID2:
+			ctrl_value = HALMAC_REG_R8(REG_BCN_CTRL_CLINT1);
+			break;
+		case HALMAC_PORTID3:
+			ctrl_value = HALMAC_REG_R8(REG_BCN_CTRL_CLINT2);
+			break;
+		case HALMAC_PORTID4:
+			ctrl_value = HALMAC_REG_R8(REG_BCN_CTRL_CLINT3);
+			break;
+		default:
+			break;
+		}
+
+		if (ctrl_value & BIT_EN_P2P_BCNQ_AREA)
+			ctrl->en_p2p_bcn_area = 1;
+		else
+			ctrl->en_p2p_bcn_area = 0;
+
+		if (ctrl_value & BIT_EN_P2P_CTWINDOW)
+			ctrl->en_p2p_ctwin = 1;
+		else
+			ctrl->en_p2p_ctwin = 0;
+
+		if (ctrl_value & BIT_P0_EN_RXBCN_RPT)
+			ctrl->en_rxbcn_rpt = 1;
+		else
+			ctrl->en_rxbcn_rpt = 0;
+
+		if (ctrl_value & BIT_EN_BCN_FUNCTION)
+			ctrl->en_bcn = 1;
+		else
+			ctrl->en_bcn = 0;
+
+		if (ctrl_value & BIT_DIS_TSF_UDT)
+			ctrl->dis_tsf_udt = 1;
+		else
+			ctrl->dis_tsf_udt = 0;
+
+		if (ctrl_value & BIT_P0_EN_TXBCN_RPT)
+			ctrl->en_txbcn_rpt = 1;
+		else
+			ctrl->en_txbcn_rpt = 0;
+
+		if (ctrl_value & BIT_DIS_RX_BSSID_FIT)
+			ctrl->dis_rx_bssid_fit = 1;
+		else
+			ctrl->dis_rx_bssid_fit = 0;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_multicast_addr_88xx() - config multicast address
+ * @adapter : the adapter of halmac
+ * @addr : multicast address
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_multicast_addr_88xx(struct halmac_adapter *adapter,
+			union halmac_wlan_addr *addr)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	HALMAC_REG_W32(REG_MAR, le32_to_cpu(addr->addr_l_h.low));
+	HALMAC_REG_W16(REG_MAR + 4, le16_to_cpu(addr->addr_l_h.high));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_operation_mode_88xx() - config operation mode
+ * @adapter : the adapter of halmac
+ * @mode : 802.11 standard(b/g/n/ac)
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_operation_mode_88xx(struct halmac_adapter *adapter,
+			enum halmac_wireless_mode mode)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_ch_bw_88xx() - config channel & bandwidth
+ * @adapter : the adapter of halmac
+ * @ch : WLAN channel, support 2.4G & 5G
+ * @idx : primary channel index, idx1, idx2, idx3, idx4
+ * @bw : band width, 20, 40, 80, 160, 5 ,10
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_ch_bw_88xx(struct halmac_adapter *adapter, u8 ch,
+	       enum halmac_pri_ch_idx idx, enum halmac_bw bw)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	cfg_pri_ch_idx_88xx(adapter, idx);
+	cfg_bw_88xx(adapter, bw);
+	cfg_ch_88xx(adapter, ch);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+cfg_ch_88xx(struct halmac_adapter *adapter, u8 ch)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	value8 = HALMAC_REG_R8(REG_CCK_CHECK);
+	value8 = value8 & (~(BIT(7)));
+
+	if (ch > 35)
+		value8 = value8 | BIT(7);
+
+	HALMAC_REG_W8(REG_CCK_CHECK, value8);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+cfg_pri_ch_idx_88xx(struct halmac_adapter *adapter, enum halmac_pri_ch_idx idx)
+{
+	u8 txsc40 = 0, txsc20 = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	txsc20 = idx;
+	if (txsc20 == HALMAC_CH_IDX_1 || txsc20 == HALMAC_CH_IDX_3)
+		txsc40 = 9;
+	else
+		txsc40 = 10;
+
+	HALMAC_REG_W8(REG_DATA_SC, BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_bw_88xx() - config bandwidth
+ * @adapter : the adapter of halmac
+ * @bw : band width, 20, 40, 80, 160, 5 ,10
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_bw_88xx(struct halmac_adapter *adapter, enum halmac_bw bw)
+{
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	value32 = HALMAC_REG_R32(REG_WMAC_TRXPTCL_CTL);
+	value32 = value32 & (~(BIT(7) | BIT(8)));
+
+	switch (bw) {
+	case HALMAC_BW_80:
+		value32 = value32 | BIT(7);
+		break;
+	case HALMAC_BW_40:
+		value32 = value32 | BIT(8);
+		break;
+	case HALMAC_BW_20:
+	case HALMAC_BW_10:
+	case HALMAC_BW_5:
+		break;
+	default:
+		break;
+	}
+
+	HALMAC_REG_W32(REG_WMAC_TRXPTCL_CTL, value32);
+
+	/* TODO:Move to change mac clk api later... */
+	value32 = HALMAC_REG_R32(REG_AFE_CTRL1) & ~(BIT(20) | BIT(21));
+	value32 |= (MAC_CLK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
+	HALMAC_REG_W32(REG_AFE_CTRL1, value32);
+
+	HALMAC_REG_W8(REG_USTIME_TSF, MAC_CLK_SPEED);
+	HALMAC_REG_W8(REG_USTIME_EDCA, MAC_CLK_SPEED);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+void
+enable_bb_rf_88xx(struct halmac_adapter *adapter, u8 enable)
+{
+	u8 value8;
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (enable == 1) {
+		value8 = HALMAC_REG_R8(REG_SYS_FUNC_EN);
+		value8 = value8 | BIT(0) | BIT(1);
+		HALMAC_REG_W8(REG_SYS_FUNC_EN, value8);
+
+		value8 = HALMAC_REG_R8(REG_RF_CTRL);
+		value8 = value8 | BIT(0) | BIT(1) | BIT(2);
+		HALMAC_REG_W8(REG_RF_CTRL, value8);
+
+		value32 = HALMAC_REG_R32(REG_WLRF1);
+		value32 = value32 | BIT(24) | BIT(25) | BIT(26);
+		HALMAC_REG_W32(REG_WLRF1, value32);
+	} else {
+		value8 = HALMAC_REG_R8(REG_SYS_FUNC_EN);
+		value8 = value8 & (~(BIT(0) | BIT(1)));
+		HALMAC_REG_W8(REG_SYS_FUNC_EN, value8);
+
+		value8 = HALMAC_REG_R8(REG_RF_CTRL);
+		value8 = value8 & (~(BIT(0) | BIT(1) | BIT(2)));
+		HALMAC_REG_W8(REG_RF_CTRL, value8);
+
+		value32 = HALMAC_REG_R32(REG_WLRF1);
+		value32 = value32 & (~(BIT(24) | BIT(25) | BIT(26)));
+		HALMAC_REG_W32(REG_WLRF1, value32);
+	}
+}
+
+/**
+ * cfg_la_mode_88xx() - config la mode
+ * @adapter : the adapter of halmac
+ * @mode :
+ *	disable : no TXFF space reserved for LA debug
+ *	partial : partial TXFF space is reserved for LA debug
+ *	full : all TXFF space is reserved for LA debug
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_la_mode_88xx(struct halmac_adapter *adapter, enum halmac_la_mode mode)
+{
+	if (adapter->api_registry.la_mode_en == 0)
+		return HALMAC_RET_NOT_SUPPORT;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	adapter->txff_alloc.la_mode = mode;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_rxfifo_expand_mode_88xx() - rx fifo expanding
+ * @adapter : the adapter of halmac
+ * @mode :
+ *	disable : normal mode
+ *	1 block : Rx FIFO + 1 FIFO block; Tx fifo - 1 FIFO block
+ *	2 block : Rx FIFO + 2 FIFO block; Tx fifo - 2 FIFO block
+ *	3 block : Rx FIFO + 3 FIFO block; Tx fifo - 3 FIFO block
+ * Author : Soar
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_rxfifo_expand_mode_88xx(struct halmac_adapter *adapter,
+			    enum halmac_rx_fifo_expanding_mode mode)
+{
+	if (adapter->api_registry.rx_exp_en == 0)
+		return HALMAC_RET_NOT_SUPPORT;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	adapter->txff_alloc.rx_fifo_exp_mode = mode;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+config_security_88xx(struct halmac_adapter *adapter,
+		     struct halmac_security_setting *setting)
+{
+	u8 sec_cfg;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	HALMAC_REG_W16_SET(REG_CR, BIT_MAC_SEC_EN);
+
+	if (setting->compare_keyid == 1) {
+		HALMAC_REG_W8_SET(REG_SECCFG + 1, BIT(0));
+		adapter->hw_cfg_info.chk_security_keyid = 1;
+	} else {
+		adapter->hw_cfg_info.chk_security_keyid = 0;
+	}
+
+	sec_cfg = HALMAC_REG_R8(REG_SECCFG);
+
+	/* BC/MC uses default key */
+	/* cam entry 0~3, kei id = 0 -> entry0, kei id = 1 -> entry1... */
+	sec_cfg |= (BIT_TXBCUSEDK | BIT_RXBCUSEDK);
+
+	if (setting->tx_encryption == 1)
+		sec_cfg |= BIT_TXENC;
+	else
+		sec_cfg &= ~BIT_TXENC;
+
+	if (setting->rx_decryption == 1)
+		sec_cfg |= BIT_RXDEC;
+	else
+		sec_cfg &= ~BIT_RXDEC;
+
+	HALMAC_REG_W8(REG_SECCFG, sec_cfg);
+
+	if (setting->bip_enable == 1) {
+		if (adapter->chip_id == HALMAC_CHIP_ID_8822B)
+			return HALMAC_RET_BIP_NO_SUPPORT;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+u8
+get_used_cam_entry_num_88xx(struct halmac_adapter *adapter,
+			    enum hal_security_type sec_type)
+{
+	u8 entry_num;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	switch (sec_type) {
+	case HAL_SECURITY_TYPE_WEP40:
+	case HAL_SECURITY_TYPE_WEP104:
+	case HAL_SECURITY_TYPE_TKIP:
+	case HAL_SECURITY_TYPE_AES128:
+	case HAL_SECURITY_TYPE_GCMP128:
+	case HAL_SECURITY_TYPE_GCMSMS4:
+	case HAL_SECURITY_TYPE_BIP:
+		entry_num = 1;
+		break;
+	case HAL_SECURITY_TYPE_WAPI:
+	case HAL_SECURITY_TYPE_AES256:
+	case HAL_SECURITY_TYPE_GCMP256:
+		entry_num = 2;
+		break;
+	default:
+		entry_num = 0;
+		break;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return entry_num;
+}
+
+enum halmac_ret_status
+write_cam_88xx(struct halmac_adapter *adapter, u32 idx,
+	       struct halmac_cam_entry_info *info)
+{
+	u32 i;
+	u32 cmd = 0x80010000;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	struct halmac_cam_entry_format *fmt = NULL;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (idx >= adapter->hw_cfg_info.cam_entry_num)
+		return HALMAC_RET_ENTRY_INDEX_ERROR;
+
+	if (info->key_id > 3)
+		return HALMAC_RET_FAIL;
+
+	fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
+	if (!fmt)
+		return HALMAC_RET_NULL_POINTER;
+	memset(fmt, 0x00, sizeof(*fmt));
+
+	if (adapter->hw_cfg_info.chk_security_keyid == 1)
+		fmt->key_id = info->key_id;
+	fmt->valid = info->valid;
+	memcpy(fmt->mac_address, info->mac_address, 6);
+	memcpy(fmt->key, info->key, 16);
+
+	switch (info->security_type) {
+	case HAL_SECURITY_TYPE_NONE:
+		fmt->type = 0;
+		break;
+	case HAL_SECURITY_TYPE_WEP40:
+		fmt->type = 1;
+		break;
+	case HAL_SECURITY_TYPE_WEP104:
+		fmt->type = 5;
+		break;
+	case HAL_SECURITY_TYPE_TKIP:
+		fmt->type = 2;
+		break;
+	case HAL_SECURITY_TYPE_AES128:
+		fmt->type = 4;
+		break;
+	case HAL_SECURITY_TYPE_WAPI:
+		fmt->type = 6;
+		break;
+	case HAL_SECURITY_TYPE_AES256:
+		fmt->type = 4;
+		fmt->ext_sectype = 1;
+		break;
+	case HAL_SECURITY_TYPE_GCMP128:
+		fmt->type = 7;
+		break;
+	case HAL_SECURITY_TYPE_GCMP256:
+	case HAL_SECURITY_TYPE_GCMSMS4:
+		fmt->type = 7;
+		fmt->ext_sectype = 1;
+		break;
+	case HAL_SECURITY_TYPE_BIP:
+		fmt->type = (info->unicast == 1) ? 4 : 0;
+		fmt->mgnt = 1;
+		fmt->grp = (info->unicast == 1) ? 0 : 1;
+		break;
+	default:
+		kfree(fmt);
+		return HALMAC_RET_FAIL;
+	}
+
+	for (i = 0; i < 8; i++) {
+		HALMAC_REG_W32(REG_CAMWRITE, *((u32 *)fmt + i));
+		HALMAC_REG_W32(REG_CAMCMD, cmd | ((idx << 3) + i));
+	}
+
+	if (info->security_type == HAL_SECURITY_TYPE_WAPI ||
+	    info->security_type == HAL_SECURITY_TYPE_AES256 ||
+	    info->security_type == HAL_SECURITY_TYPE_GCMP256 ||
+	    info->security_type == HAL_SECURITY_TYPE_GCMSMS4) {
+		fmt->mic = 1;
+		memcpy(fmt->key, info->key_ext, 16);
+		idx++;
+		for (i = 0; i < 8; i++) {
+			HALMAC_REG_W32(REG_CAMWRITE, *((u32 *)fmt + i));
+			HALMAC_REG_W32(REG_CAMCMD, cmd | ((idx << 3) + i));
+		}
+	}
+
+	kfree(fmt);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+read_cam_entry_88xx(struct halmac_adapter *adapter, u32 idx,
+		    struct halmac_cam_entry_format *content)
+{
+	u32 i;
+	u32 cmd = 0x80000000;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (idx >= adapter->hw_cfg_info.cam_entry_num)
+		return HALMAC_RET_ENTRY_INDEX_ERROR;
+
+	for (i = 0; i < 8; i++) {
+		HALMAC_REG_W32(REG_CAMCMD, cmd | ((idx << 3) + i));
+		*((u32 *)content + i) = HALMAC_REG_R32(REG_CAMREAD);
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+clear_cam_entry_88xx(struct halmac_adapter *adapter, u32 idx)
+{
+	u32 i;
+	u32 cmd = 0x80010000;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	struct halmac_cam_entry_format *fmt = NULL;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (idx >= adapter->hw_cfg_info.cam_entry_num)
+		return HALMAC_RET_ENTRY_INDEX_ERROR;
+
+	fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
+	if (!fmt)
+		return HALMAC_RET_NULL_POINTER;
+	memset(fmt, 0x00, sizeof(*fmt));
+
+	for (i = 0; i < 8; i++) {
+		HALMAC_REG_W32(REG_CAMWRITE, *((u32 *)fmt + i));
+		HALMAC_REG_W32(REG_CAMCMD, cmd | ((idx << 3) + i));
+	}
+
+	kfree(fmt);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+void
+rx_shift_88xx(struct halmac_adapter *adapter, u8 enable)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	value8 = HALMAC_REG_R8(REG_TXDMA_PQ_MAP);
+
+	if (enable == 1)
+		HALMAC_REG_W8(REG_TXDMA_PQ_MAP, value8 | BIT(1));
+	else
+		HALMAC_REG_W8(REG_TXDMA_PQ_MAP, value8 & ~(BIT(1)));
+}
+
+/**
+ * cfg_edca_para_88xx() - config edca parameter
+ * @adapter : the adapter of halmac
+ * @acq_id : VO/VI/BE/BK
+ * @param : aifs, cw, txop limit
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_edca_para_88xx(struct halmac_adapter *adapter, enum halmac_acq_id acq_id,
+		   struct halmac_edca_para *param)
+{
+	u32 offset;
+	u32 value32;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	switch (acq_id) {
+	case HALMAC_ACQ_ID_VO:
+		offset = REG_EDCA_VO_PARAM;
+		break;
+	case HALMAC_ACQ_ID_VI:
+		offset = REG_EDCA_VI_PARAM;
+		break;
+	case HALMAC_ACQ_ID_BE:
+		offset = REG_EDCA_BE_PARAM;
+		break;
+	case HALMAC_ACQ_ID_BK:
+		offset = REG_EDCA_BK_PARAM;
+		break;
+	default:
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	param->txop_limit &= 0x7FF;
+	value32 = (param->aifs) | (param->cw << 8) | (param->txop_limit << 16);
+
+	HALMAC_REG_W32(offset, value32);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+void
+rx_clk_gate_88xx(struct halmac_adapter *adapter, u8 enable)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	value8 = HALMAC_REG_R8(REG_RCR + 2);
+
+	if (enable == 1)
+		HALMAC_REG_W8(REG_RCR + 2, value8 & ~(BIT(3)));
+	else
+		HALMAC_REG_W8(REG_RCR + 2, value8 | BIT(3));
+}
+
+enum halmac_ret_status
+rx_cut_amsdu_cfg_88xx(struct halmac_adapter *adapter,
+		      struct halmac_cut_amsdu_cfg *cfg)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+enum halmac_ret_status
+fast_edca_cfg_88xx(struct halmac_adapter *adapter,
+		   struct halmac_fast_edca_cfg *cfg)
+{
+	u16 value16;
+	u32 offset;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	switch (cfg->acq_id) {
+	case HALMAC_ACQ_ID_VO:
+		offset = REG_FAST_EDCA_VOVI_SETTING;
+		break;
+	case HALMAC_ACQ_ID_VI:
+		offset = REG_FAST_EDCA_VOVI_SETTING + 2;
+		break;
+	case HALMAC_ACQ_ID_BE:
+		offset = REG_FAST_EDCA_BEBK_SETTING;
+		break;
+	case HALMAC_ACQ_ID_BK:
+		offset = REG_FAST_EDCA_BEBK_SETTING + 2;
+		break;
+	default:
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	value16 = HALMAC_REG_R16(offset);
+	value16 &= 0xFF;
+	value16 = value16 | (cfg->queue_to << 8);
+
+	HALMAC_REG_W16(offset, value16);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * get_mac_addr_88xx() - get mac address
+ * @adapter : the adapter of halmac
+ * @port : 0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
+ * @addr : mac address
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_mac_addr_88xx(struct halmac_adapter *adapter, u8 port,
+		  union halmac_wlan_addr *addr)
+{
+	u16 mac_addr_h;
+	u32 mac_addr_l;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (port >= HALMAC_PORTID_NUM) {
+		pr_err("port index >= 5\n");
+		return HALMAC_RET_PORT_NOT_SUPPORT;
+	}
+
+	switch (port) {
+	case HALMAC_PORTID0:
+		mac_addr_l = HALMAC_REG_R32(REG_MACID);
+		mac_addr_h = HALMAC_REG_R16(REG_MACID + 4);
+		break;
+	case HALMAC_PORTID1:
+		mac_addr_l = HALMAC_REG_R32(REG_MACID1);
+		mac_addr_h = HALMAC_REG_R16(REG_MACID1 + 4);
+		break;
+	case HALMAC_PORTID2:
+		mac_addr_l = HALMAC_REG_R32(REG_MACID2);
+		mac_addr_h = HALMAC_REG_R16(REG_MACID2 + 4);
+		break;
+	case HALMAC_PORTID3:
+		mac_addr_l = HALMAC_REG_R32(REG_MACID3);
+		mac_addr_h = HALMAC_REG_R16(REG_MACID3 + 4);
+		break;
+	case HALMAC_PORTID4:
+		mac_addr_l = HALMAC_REG_R32(REG_MACID4);
+		mac_addr_h = HALMAC_REG_R16(REG_MACID4 + 4);
+		break;
+	default:
+		return HALMAC_RET_PORT_NOT_SUPPORT;
+	}
+
+	addr->addr_l_h.low = cpu_to_le32(mac_addr_l);
+	addr->addr_l_h.high = cpu_to_le16(mac_addr_h);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+void
+rts_full_bw_88xx(struct halmac_adapter *adapter, u8 enable)
+{
+	u8 value8;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	value8 = HALMAC_REG_R8(REG_INIRTS_RATE_SEL);
+
+	if (enable == 1)
+		HALMAC_REG_W8(REG_INIRTS_RATE_SEL, value8 | BIT(5));
+	else
+		HALMAC_REG_W8(REG_INIRTS_RATE_SEL, value8 & ~(BIT(5)));
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.h
new file mode 100644
index 000000000000..b06ee29dd22c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_cfg_wmac_88xx.h
@@ -0,0 +1,122 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_CFG_WMAC_88XX_H_
+#define _HALMAC_CFG_WMAC_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+cfg_mac_addr_88xx(struct halmac_adapter *adapter, u8 port,
+		  union halmac_wlan_addr *addr);
+
+enum halmac_ret_status
+cfg_bssid_88xx(struct halmac_adapter *adapter, u8 port,
+	       union halmac_wlan_addr *addr);
+
+enum halmac_ret_status
+cfg_transmitter_addr_88xx(struct halmac_adapter *adapter, u8 port,
+			  union halmac_wlan_addr *addr);
+
+enum halmac_ret_status
+cfg_net_type_88xx(struct halmac_adapter *adapter, u8 port,
+		  enum halmac_network_type_select net_type);
+
+enum halmac_ret_status
+cfg_tsf_rst_88xx(struct halmac_adapter *adapter, u8 port);
+
+enum halmac_ret_status
+cfg_bcn_space_88xx(struct halmac_adapter *adapter, u8 port, u32 bcn_space);
+
+enum halmac_ret_status
+rw_bcn_ctrl_88xx(struct halmac_adapter *adapter, u8 port, u8 write_en,
+		 struct halmac_bcn_ctrl *ctrl);
+
+enum halmac_ret_status
+cfg_multicast_addr_88xx(struct halmac_adapter *adapter,
+			union halmac_wlan_addr *addr);
+
+enum halmac_ret_status
+cfg_operation_mode_88xx(struct halmac_adapter *adapter,
+			enum halmac_wireless_mode mode);
+
+enum halmac_ret_status
+cfg_ch_bw_88xx(struct halmac_adapter *adapter, u8 ch,
+	       enum halmac_pri_ch_idx idx, enum halmac_bw bw);
+
+enum halmac_ret_status
+cfg_ch_88xx(struct halmac_adapter *adapter, u8 ch);
+
+enum halmac_ret_status
+cfg_pri_ch_idx_88xx(struct halmac_adapter *adapter, enum halmac_pri_ch_idx idx);
+
+enum halmac_ret_status
+cfg_bw_88xx(struct halmac_adapter *adapter, enum halmac_bw bw);
+
+void
+enable_bb_rf_88xx(struct halmac_adapter *adapter, u8 enable);
+
+enum halmac_ret_status
+cfg_la_mode_88xx(struct halmac_adapter *adapter, enum halmac_la_mode mode);
+
+enum halmac_ret_status
+cfg_rxfifo_expand_mode_88xx(struct halmac_adapter *adapter,
+			    enum halmac_rx_fifo_expanding_mode mode);
+
+enum halmac_ret_status
+config_security_88xx(struct halmac_adapter *adapter,
+		     struct halmac_security_setting *setting);
+
+u8
+get_used_cam_entry_num_88xx(struct halmac_adapter *adapter,
+			    enum hal_security_type sec_type);
+
+enum halmac_ret_status
+write_cam_88xx(struct halmac_adapter *adapter, u32 idx,
+	       struct halmac_cam_entry_info *info);
+
+enum halmac_ret_status
+read_cam_entry_88xx(struct halmac_adapter *adapter, u32 idx,
+		    struct halmac_cam_entry_format *content);
+
+enum halmac_ret_status
+clear_cam_entry_88xx(struct halmac_adapter *adapter, u32 idx);
+
+void
+rx_shift_88xx(struct halmac_adapter *adapter, u8 enable);
+
+enum halmac_ret_status
+cfg_edca_para_88xx(struct halmac_adapter *adapter, enum halmac_acq_id acq_id,
+		   struct halmac_edca_para *param);
+
+void
+rx_clk_gate_88xx(struct halmac_adapter *adapter, u8 enable);
+
+enum halmac_ret_status
+rx_cut_amsdu_cfg_88xx(struct halmac_adapter *adapter,
+		      struct halmac_cut_amsdu_cfg *cfg);
+
+enum halmac_ret_status
+fast_edca_cfg_88xx(struct halmac_adapter *adapter,
+		   struct halmac_fast_edca_cfg *cfg);
+
+enum halmac_ret_status
+get_mac_addr_88xx(struct halmac_adapter *adapter, u8 port,
+		  union halmac_wlan_addr *addr);
+
+void
+rts_full_bw_88xx(struct halmac_adapter *adapter, u8 enable);
+
+#endif/* _HALMAC_CFG_WMAC_88XX_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.c
new file mode 100644
index 000000000000..e1b83c887bb9
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.c
@@ -0,0 +1,2931 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_common_88xx.h"
+#include "halmac_88xx_cfg.h"
+#include "halmac_init_88xx.h"
+#include "halmac_cfg_wmac_88xx.h"
+#include "halmac_efuse_88xx.h"
+#include "halmac_bb_rf_88xx.h"
+#include "halmac_usb_88xx.h"
+#include "halmac_sdio_88xx.h"
+#include "halmac_pcie_88xx.h"
+#include "halmac_mimo_88xx.h"
+
+#define CFG_PARAM_H2C_INFO_SIZE	12
+#define ORIGINAL_H2C_CMD_SIZE	8
+
+#define WLHDR_PROT_VER	0
+
+#define WLHDR_TYPE_MGMT		0
+#define WLHDR_TYPE_CTRL		1
+#define WLHDR_TYPE_DATA		2
+
+/* mgmt frame */
+#define WLHDR_SUB_TYPE_ASSOC_REQ	0
+#define WLHDR_SUB_TYPE_ASSOC_RSPNS	1
+#define WLHDR_SUB_TYPE_REASSOC_REQ	2
+#define WLHDR_SUB_TYPE_REASSOC_RSPNS	3
+#define WLHDR_SUB_TYPE_PROBE_REQ	4
+#define WLHDR_SUB_TYPE_PROBE_RSPNS	5
+#define WLHDR_SUB_TYPE_BCN		8
+#define WLHDR_SUB_TYPE_DISASSOC		10
+#define WLHDR_SUB_TYPE_AUTH		11
+#define WLHDR_SUB_TYPE_DEAUTH		12
+#define WLHDR_SUB_TYPE_ACTION		13
+#define WLHDR_SUB_TYPE_ACTION_NOACK	14
+
+/* ctrl frame */
+#define WLHDR_SUB_TYPE_BF_RPT_POLL	4
+#define WLHDR_SUB_TYPE_NDPA		5
+
+/* data frame */
+#define WLHDR_SUB_TYPE_DATA		0
+#define WLHDR_SUB_TYPE_NULL		4
+#define WLHDR_SUB_TYPE_QOS_DATA		8
+#define WLHDR_SUB_TYPE_QOS_NULL		12
+
+#define LTECOEX_ACCESS_CTRL REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1
+
+struct wlhdr_frame_ctrl {
+	u16 protocol:2;
+	u16 type:2;
+	u16 sub_type:4;
+	u16 to_ds:1;
+	u16 from_ds:1;
+	u16 more_frag:1;
+	u16 retry:1;
+	u16 pwr_mgmt:1;
+	u16 more_data:1;
+	u16 protect_frame:1;
+	u16 order:1;
+};
+
+static enum halmac_ret_status
+parse_c2h_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+static enum halmac_ret_status
+get_c2h_dbg_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+static enum halmac_ret_status
+get_h2c_ack_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+static enum halmac_ret_status
+get_scan_rpt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+static enum halmac_ret_status
+get_h2c_ack_cfg_param_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+static enum halmac_ret_status
+get_h2c_ack_update_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+static enum halmac_ret_status
+get_h2c_ack_update_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf,
+				u32 size);
+
+static enum halmac_ret_status
+get_h2c_ack_run_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+static enum halmac_ret_status
+get_h2c_ack_ch_switch_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+static enum halmac_ret_status
+malloc_cfg_param_buf_88xx(struct halmac_adapter *adapter, u8 full_fifo);
+
+static enum halmac_cmd_construct_state
+cfg_param_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+proc_cfg_param_88xx(struct halmac_adapter *adapter,
+		    struct halmac_phy_parameter_info *param, u8 full_fifo);
+
+static enum halmac_ret_status
+send_cfg_param_h2c_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+cnv_cfg_param_state_88xx(struct halmac_adapter *adapter,
+			 enum halmac_cmd_construct_state dest_state);
+
+static enum halmac_ret_status
+add_param_buf_88xx(struct halmac_adapter *adapter,
+		   struct halmac_phy_parameter_info *param, u8 *buf,
+		   u8 *end_cmd);
+
+static enum halmac_ret_status
+gen_cfg_param_h2c_88xx(struct halmac_adapter *adapter, u8 *buff);
+
+static enum halmac_ret_status
+send_h2c_update_packet_88xx(struct halmac_adapter *adapter,
+			    enum halmac_packet_id pkt_id, u8 *pkt, u32 size);
+
+static enum halmac_ret_status
+send_bt_coex_cmd_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+		      u8 ack);
+
+static enum halmac_ret_status
+read_buf_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+	      enum hal_fifo_sel sel, u8 *data);
+
+static enum halmac_cmd_construct_state
+scan_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+cnv_scan_state_88xx(struct halmac_adapter *adapter,
+		    enum halmac_cmd_construct_state dest_state);
+
+static enum halmac_ret_status
+proc_ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
+			 struct halmac_ch_switch_option *opt);
+
+static enum halmac_ret_status
+proc_p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info);
+
+static enum halmac_ret_status
+get_cfg_param_status_88xx(struct halmac_adapter *adapter,
+			  enum halmac_cmd_process_status *proc_status);
+
+static enum halmac_ret_status
+get_ch_switch_status_88xx(struct halmac_adapter *adapter,
+			  enum halmac_cmd_process_status *proc_status);
+
+static enum halmac_ret_status
+get_update_packet_status_88xx(struct halmac_adapter *adapter,
+			      enum halmac_cmd_process_status *proc_status);
+
+static enum halmac_ret_status
+pwr_sub_seq_parser_88xx(struct halmac_adapter *adapter, u8 cut, u8 intf,
+			struct halmac_wlan_pwr_cfg *cmd);
+
+static void
+pwr_state_88xx(struct halmac_adapter *adapter, enum halmac_mac_power *state);
+
+static enum halmac_ret_status
+pwr_cmd_polling_88xx(struct halmac_adapter *adapter,
+		     struct halmac_wlan_pwr_cfg *cmd);
+
+static void
+get_pq_mapping_88xx(struct halmac_adapter *adapter,
+		    struct halmac_rqpn_map *mapping);
+
+static void
+dump_reg_sdio_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+wlhdr_valid_88xx(struct halmac_adapter *adapter, u8 *buf);
+
+static u8
+wlhdr_mgmt_valid_88xx(struct halmac_adapter *adapter,
+		      struct wlhdr_frame_ctrl *wlhdr);
+
+static u8
+wlhdr_ctrl_valid_88xx(struct halmac_adapter *adapter,
+		      struct wlhdr_frame_ctrl *wlhdr);
+
+static u8
+wlhdr_data_valid_88xx(struct halmac_adapter *adapter,
+		      struct wlhdr_frame_ctrl *wlhdr);
+
+static void
+dump_reg_88xx(struct halmac_adapter *adapter);
+
+/**
+ * ofld_func_cfg_88xx() - config offload function
+ * @adapter : the adapter of halmac
+ * @info : offload function information
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+ofld_func_cfg_88xx(struct halmac_adapter *adapter,
+		   struct halmac_ofld_func_info *info)
+{
+	if (adapter->intf == HALMAC_INTERFACE_SDIO &&
+	    info->rsvd_pg_drv_buf_max_sz > SDIO_TX_MAX_SIZE_88XX)
+		return HALMAC_RET_FAIL;
+
+	adapter->pltfm_info.malloc_size = info->halmac_malloc_max_sz;
+	adapter->pltfm_info.rsvd_pg_size = info->rsvd_pg_drv_buf_max_sz;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * dl_drv_rsvd_page_88xx() - download packet to rsvd page
+ * @adapter : the adapter of halmac
+ * @pg_offset : page offset of driver's rsvd page
+ * @halmac_buf : data to be downloaded, tx_desc is not included
+ * @halmac_size : data size to be downloaded
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+dl_drv_rsvd_page_88xx(struct halmac_adapter *adapter, u8 pg_offset, u8 *buf,
+		      u32 size)
+{
+	enum halmac_ret_status status;
+	u32 pg_size;
+	u32 pg_num = 0;
+	u16 pg_addr = 0;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	pg_size = adapter->hw_cfg_info.page_size;
+	pg_num = size / pg_size + ((size & (pg_size - 1)) ? 1 : 0);
+	if (pg_offset + pg_num > adapter->txff_alloc.rsvd_drv_pg_num) {
+		pr_err("pkt overflow!!\n");
+		return HALMAC_RET_DRV_DL_ERR;
+	}
+
+	pg_addr = adapter->txff_alloc.rsvd_drv_addr + pg_offset;
+
+	status = dl_rsvd_page_88xx(adapter, pg_addr, buf, size);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("dl rsvd page fail!!\n");
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+dl_rsvd_page_88xx(struct halmac_adapter *adapter, u16 pg_addr, u8 *buf,
+		  u32 size)
+{
+	u8 restore[2];
+	u8 value8;
+	u16 rsvd_pg_head;
+	u32 cnt;
+	enum halmac_rsvd_pg_state *state = &adapter->halmac_state.rsvd_pg_state;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (size == 0) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "pkt size = 0\n");
+		return HALMAC_RET_ZERO_LEN_RSVD_PACKET;
+	}
+
+	if (*state == HALMAC_RSVD_PG_STATE_BUSY)
+		return HALMAC_RET_BUSY_STATE;
+
+	*state = HALMAC_RSVD_PG_STATE_BUSY;
+
+	pg_addr &= BIT_MASK_BCN_HEAD_1_V1;
+	HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, (u16)(pg_addr | BIT(15)));
+
+	value8 = HALMAC_REG_R8(REG_CR + 1);
+	restore[0] = value8;
+	value8 = (u8)(value8 | BIT(0));
+	HALMAC_REG_W8(REG_CR + 1, value8);
+
+	value8 = HALMAC_REG_R8(REG_FWHW_TXQ_CTRL + 2);
+	restore[1] = value8;
+	value8 = (u8)(value8 & ~(BIT(6)));
+	HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, value8);
+
+	if (PLTFM_SEND_RSVD_PAGE(buf, size) == 0) {
+		pr_err("send rvsd pg(pltfm)!!\n");
+		status = HALMAC_RET_DL_RSVD_PAGE_FAIL;
+		goto DL_RSVD_PG_END;
+	}
+
+	cnt = 1000;
+	while (!(HALMAC_REG_R8(REG_FIFOPAGE_CTRL_2 + 1) & BIT(7))) {
+		usleep_range(10, 20);
+		cnt--;
+		if (cnt == 0) {
+			pr_err("bcn valid!!\n");
+			status = HALMAC_RET_POLLING_BCN_VALID_FAIL;
+			break;
+		}
+	}
+DL_RSVD_PG_END:
+	rsvd_pg_head = adapter->txff_alloc.rsvd_boundary;
+	HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, rsvd_pg_head | BIT(15));
+	HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, restore[1]);
+	HALMAC_REG_W8(REG_CR + 1, restore[0]);
+
+	*state = HALMAC_RSVD_PG_STATE_IDLE;
+
+	return status;
+}
+
+enum halmac_ret_status
+get_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
+		  void *value)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	switch (hw_id) {
+	case HALMAC_HW_RQPN_MAPPING:
+		get_pq_mapping_88xx(adapter, (struct halmac_rqpn_map *)value);
+		break;
+	case HALMAC_HW_EFUSE_SIZE:
+		*(u32 *)value = adapter->hw_cfg_info.efuse_size;
+		break;
+	case HALMAC_HW_EEPROM_SIZE:
+		*(u32 *)value = adapter->hw_cfg_info.eeprom_size;
+		break;
+	case HALMAC_HW_BT_BANK_EFUSE_SIZE:
+		*(u32 *)value = adapter->hw_cfg_info.bt_efuse_size;
+		break;
+	case HALMAC_HW_BT_BANK1_EFUSE_SIZE:
+	case HALMAC_HW_BT_BANK2_EFUSE_SIZE:
+		*(u32 *)value = 0;
+		break;
+	case HALMAC_HW_TXFIFO_SIZE:
+		*(u32 *)value = adapter->hw_cfg_info.tx_fifo_size;
+		break;
+	case HALMAC_HW_RXFIFO_SIZE:
+		*(u32 *)value = adapter->hw_cfg_info.rx_fifo_size;
+		break;
+	case HALMAC_HW_RSVD_PG_BNDY:
+		*(u16 *)value = adapter->txff_alloc.rsvd_drv_addr;
+		break;
+	case HALMAC_HW_CAM_ENTRY_NUM:
+		*(u8 *)value = adapter->hw_cfg_info.cam_entry_num;
+		break;
+	case HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE:
+		get_efuse_available_size_88xx(adapter, (u32 *)value);
+		break;
+	case HALMAC_HW_IC_VERSION:
+		*(u8 *)value = adapter->chip_ver;
+		break;
+	case HALMAC_HW_PAGE_SIZE:
+		*(u32 *)value = adapter->hw_cfg_info.page_size;
+		break;
+	case HALMAC_HW_TX_AGG_ALIGN_SIZE:
+		*(u16 *)value = adapter->hw_cfg_info.tx_align_size;
+		break;
+	case HALMAC_HW_RX_AGG_ALIGN_SIZE:
+		*(u8 *)value = 8;
+		break;
+	case HALMAC_HW_DRV_INFO_SIZE:
+		*(u8 *)value = adapter->drv_info_size;
+		break;
+	case HALMAC_HW_TXFF_ALLOCATION:
+		memcpy(value, &adapter->txff_alloc,
+		       sizeof(struct halmac_txff_allocation));
+		break;
+	case HALMAC_HW_RSVD_EFUSE_SIZE:
+		*(u32 *)value = get_rsvd_efuse_size_88xx(adapter);
+		break;
+	case HALMAC_HW_FW_HDR_SIZE:
+		*(u32 *)value = WLAN_FW_HDR_SIZE;
+		break;
+	case HALMAC_HW_TX_DESC_SIZE:
+		*(u32 *)value = adapter->hw_cfg_info.txdesc_size;
+		break;
+	case HALMAC_HW_RX_DESC_SIZE:
+		*(u32 *)value = adapter->hw_cfg_info.rxdesc_size;
+		break;
+	case HALMAC_HW_ORI_H2C_SIZE:
+		*(u32 *)value = ORIGINAL_H2C_CMD_SIZE;
+		break;
+	case HALMAC_HW_RSVD_DRV_PGNUM:
+		*(u16 *)value = adapter->txff_alloc.rsvd_drv_pg_num;
+		break;
+	case HALMAC_HW_TX_PAGE_SIZE:
+		*(u16 *)value = TX_PAGE_SIZE_88XX;
+		break;
+	case HALMAC_HW_USB_TXAGG_DESC_NUM:
+		*(u8 *)value = adapter->hw_cfg_info.usb_txagg_num;
+		break;
+	case HALMAC_HW_AC_OQT_SIZE:
+		*(u8 *)value = adapter->hw_cfg_info.ac_oqt_size;
+		break;
+	case HALMAC_HW_NON_AC_OQT_SIZE:
+		*(u8 *)value = adapter->hw_cfg_info.non_ac_oqt_size;
+		break;
+	case HALMAC_HW_AC_QUEUE_NUM:
+		*(u8 *)value = adapter->hw_cfg_info.acq_num;
+		break;
+	case HALMAC_HW_PWR_STATE:
+		pwr_state_88xx(adapter, (enum halmac_mac_power *)value);
+		break;
+	default:
+		return HALMAC_RET_PARA_NOT_SUPPORT;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+get_pq_mapping_88xx(struct halmac_adapter *adapter,
+		    struct halmac_rqpn_map *mapping)
+{
+	mapping->dma_map_vo = adapter->pq_map[HALMAC_PQ_MAP_VO];
+	mapping->dma_map_vi = adapter->pq_map[HALMAC_PQ_MAP_VI];
+	mapping->dma_map_be = adapter->pq_map[HALMAC_PQ_MAP_BE];
+	mapping->dma_map_bk = adapter->pq_map[HALMAC_PQ_MAP_BK];
+	mapping->dma_map_mg = adapter->pq_map[HALMAC_PQ_MAP_MG];
+	mapping->dma_map_hi = adapter->pq_map[HALMAC_PQ_MAP_HI];
+}
+
+/**
+ * set_hw_value_88xx() -set hw config value
+ * @adapter : the adapter of halmac
+ * @hw_id : hw id for driver to config
+ * @value : hw value, reference table to get data type
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+set_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
+		  void *value)
+{
+	enum halmac_ret_status status;
+	struct halmac_tx_page_threshold_info *th_info;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (!value) {
+		pr_err("null ptr-set hw value\n");
+		return HALMAC_RET_NULL_POINTER;
+	}
+
+	switch (hw_id) {
+	case HALMAC_HW_USB_MODE:
+		status = set_usb_mode_88xx(adapter,
+					   *(enum halmac_usb_mode *)value);
+		if (status != HALMAC_RET_SUCCESS)
+			return status;
+		break;
+	case HALMAC_HW_BANDWIDTH:
+		cfg_bw_88xx(adapter, *(enum halmac_bw *)value);
+		break;
+	case HALMAC_HW_CHANNEL:
+		cfg_ch_88xx(adapter, *(u8 *)value);
+		break;
+	case HALMAC_HW_PRI_CHANNEL_IDX:
+		cfg_pri_ch_idx_88xx(adapter, *(enum halmac_pri_ch_idx *)value);
+		break;
+	case HALMAC_HW_EN_BB_RF:
+		enable_bb_rf_88xx(adapter, *(u8 *)value);
+		break;
+	case HALMAC_HW_SDIO_TX_PAGE_THRESHOLD:
+		if (adapter->intf == HALMAC_INTERFACE_SDIO) {
+			th_info = (struct halmac_tx_page_threshold_info *)value;
+			cfg_sdio_tx_page_threshold_88xx(adapter, th_info);
+		} else {
+			return HALMAC_RET_FAIL;
+		}
+		break;
+	case HALMAC_HW_RX_SHIFT:
+		rx_shift_88xx(adapter, *(u8 *)value);
+		break;
+	case HALMAC_HW_TXDESC_CHECKSUM:
+		tx_desc_chksum_88xx(adapter, *(u8 *)value);
+		break;
+	case HALMAC_HW_RX_CLK_GATE:
+		rx_clk_gate_88xx(adapter, *(u8 *)value);
+		break;
+	case HALMAC_HW_FAST_EDCA:
+		fast_edca_cfg_88xx(adapter,
+				   (struct halmac_fast_edca_cfg *)value);
+		break;
+	case HALMAC_HW_RTS_FULL_BW:
+		rts_full_bw_88xx(adapter, *(u8 *)value);
+		break;
+	case HALMAC_HW_FREE_CNT_EN:
+		HALMAC_REG_W8_SET(REG_MISC_CTRL, BIT_EN_FREECNT);
+		break;
+	default:
+		return HALMAC_RET_PARA_NOT_SUPPORT;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+set_h2c_pkt_hdr_88xx(struct halmac_adapter *adapter, u8 *hdr,
+		     struct halmac_h2c_header_info *info, u16 *seq_num)
+{
+	u16 total_size;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s!!\n",
+		 __func__);
+
+	total_size = H2C_PKT_HDR_SIZE_88XX + info->content_size;
+	FW_OFFLOAD_H2C_SET_TOTAL_LEN(hdr, total_size);
+	FW_OFFLOAD_H2C_SET_SUB_CMD_ID(hdr, info->sub_cmd_id);
+
+	FW_OFFLOAD_H2C_SET_CATEGORY(hdr, 0x01);
+	FW_OFFLOAD_H2C_SET_CMD_ID(hdr, 0xFF);
+
+	mutex_lock(&adapter->h2c_seq_mutex);
+	FW_OFFLOAD_H2C_SET_SEQ_NUM(hdr, adapter->h2c_info.seq_num);
+	*seq_num = adapter->h2c_info.seq_num;
+	(adapter->h2c_info.seq_num)++;
+	mutex_unlock(&adapter->h2c_seq_mutex);
+
+	if (info->ack == 1)
+		FW_OFFLOAD_H2C_SET_ACK(hdr, 1);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+send_h2c_pkt_88xx(struct halmac_adapter *adapter, u8 *pkt)
+{
+	u32 cnt = 100;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	while (adapter->h2c_info.buf_fs <= H2C_PKT_SIZE_88XX) {
+		get_h2c_buf_free_space_88xx(adapter);
+		cnt--;
+		if (cnt == 0) {
+			pr_err("h2c free space!!\n");
+			return HALMAC_RET_H2C_SPACE_FULL;
+		}
+	}
+
+	cnt = 100;
+	do {
+		if (PLTFM_SEND_H2C_PKT(pkt, H2C_PKT_SIZE_88XX) == 1)
+			break;
+		cnt--;
+		if (cnt == 0) {
+			pr_err("pltfm - sned h2c pkt!!\n");
+			return HALMAC_RET_SEND_H2C_FAIL;
+		}
+		udelay(5);
+
+	} while (1);
+
+	adapter->h2c_info.buf_fs -= H2C_PKT_SIZE_88XX;
+
+	return status;
+}
+
+enum halmac_ret_status
+get_h2c_buf_free_space_88xx(struct halmac_adapter *adapter)
+{
+	u32 hw_wptr;
+	u32 fw_rptr;
+	struct halmac_h2c_info *info = &adapter->h2c_info;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	hw_wptr = HALMAC_REG_R32(REG_H2C_PKT_WRITEADDR) & 0x3FFFF;
+	fw_rptr = HALMAC_REG_R32(REG_H2C_PKT_READADDR) & 0x3FFFF;
+
+	if (hw_wptr >= fw_rptr)
+		info->buf_fs = info->buf_size - (hw_wptr - fw_rptr);
+	else
+		info->buf_fs = fw_rptr - hw_wptr;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * get_c2h_info_88xx() - process halmac C2H packet
+ * @adapter : the adapter of halmac
+ * @buf : RX Packet pointer
+ * @size : RX Packet size
+ *
+ * Note : Don't use any IO or DELAY in this API
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ *
+ * Used to process c2h packet info from RX path. After receiving the packet,
+ * user need to call this api and pass the packet pointer.
+ *
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_c2h_info_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (GET_RX_DESC_C2H(buf) == 1) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Parse c2h pkt\n");
+
+		status = parse_c2h_pkt_88xx(adapter, buf, size);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("Parse c2h pkt\n");
+			return status;
+		}
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+parse_c2h_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 cmd_id;
+	u8 sub_cmd_id;
+	u8 *c2h_pkt = buf + adapter->hw_cfg_info.rxdesc_size;
+	u32 c2h_size = size - adapter->hw_cfg_info.rxdesc_size;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	cmd_id = (u8)C2H_HDR_GET_CMD_ID(c2h_pkt);
+
+	if (cmd_id != 0xFF) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Not 0xFF cmd!!\n");
+		return HALMAC_RET_C2H_NOT_HANDLED;
+	}
+
+	sub_cmd_id = (u8)C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_pkt);
+
+	switch (sub_cmd_id) {
+	case C2H_SUB_CMD_ID_C2H_DBG:
+		status = get_c2h_dbg_88xx(adapter, c2h_pkt, c2h_size);
+		break;
+	case C2H_SUB_CMD_ID_H2C_ACK_HDR:
+		status = get_h2c_ack_88xx(adapter, c2h_pkt, c2h_size);
+		break;
+	case C2H_SUB_CMD_ID_BT_COEX_INFO:
+		status = HALMAC_RET_C2H_NOT_HANDLED;
+		break;
+	case C2H_SUB_CMD_ID_SCAN_STATUS_RPT:
+		status = get_scan_rpt_88xx(adapter, c2h_pkt, c2h_size);
+		break;
+	case C2H_SUB_CMD_ID_PSD_DATA:
+		status = get_psd_data_88xx(adapter, c2h_pkt, c2h_size);
+		break;
+	case C2H_SUB_CMD_ID_EFUSE_DATA:
+		status = get_efuse_data_88xx(adapter, c2h_pkt, c2h_size);
+		break;
+	default:
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "Sub cmd id!!\n");
+		status = HALMAC_RET_C2H_NOT_HANDLED;
+		break;
+	}
+
+	return status;
+}
+
+static enum halmac_ret_status
+get_c2h_dbg_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 i;
+	u8 next_msg = 0;
+	u8 cur_msg = 0;
+	u8 msg_len = 0;
+	char *c2h_buf = (char *)NULL;
+	u8 content_len = 0;
+	u8 seq_num = 0;
+
+	content_len = (u8)C2H_HDR_GET_LEN((u8 *)buf);
+
+	if (content_len > C2H_DBG_CONTENT_MAX_LENGTH) {
+		pr_err("c2h size > max len!\n");
+		return HALMAC_RET_C2H_NOT_HANDLED;
+	}
+
+	for (i = 0; i < content_len; i++) {
+		if (*(buf + C2H_DBG_HDR_LEN + i) == '\n') {
+			if ((*(buf + C2H_DBG_HDR_LEN + i + 1) == '\0') ||
+			    (*(buf + C2H_DBG_HDR_LEN + i + 1) == 0xff)) {
+				next_msg = C2H_DBG_HDR_LEN + i + 1;
+				goto _ENDFOUND;
+			}
+		}
+	}
+
+_ENDFOUND:
+	msg_len = next_msg - C2H_DBG_HDR_LEN;
+
+	c2h_buf = kzalloc(msg_len, GFP_KERNEL);
+	if (!c2h_buf)
+		return HALMAC_RET_MALLOC_FAIL;
+
+	memcpy(c2h_buf, buf + C2H_DBG_HDR_LEN, msg_len);
+
+	seq_num = (u8)(*(c2h_buf));
+	*(c2h_buf + msg_len - 1) = '\0';
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "[RTKFW, SEQ=%d]: %s\n", seq_num, (char *)(c2h_buf + 1));
+	kfree(c2h_buf);
+
+	while (*(buf + next_msg) != '\0') {
+		cur_msg = next_msg;
+
+		msg_len = (u8)(*(buf + cur_msg + 3)) - 1;
+		next_msg += C2H_DBG_HDR_LEN + msg_len;
+
+		c2h_buf = kzalloc(msg_len, GFP_KERNEL);
+		if (!c2h_buf)
+			return HALMAC_RET_MALLOC_FAIL;
+
+		memcpy(c2h_buf, buf + cur_msg + C2H_DBG_HDR_LEN, msg_len);
+		*(c2h_buf + msg_len - 1) = '\0';
+		seq_num = (u8)(*(c2h_buf));
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "[RTKFW, SEQ=%d]: %s\n", seq_num,
+			 (char *)(c2h_buf + 1));
+		kfree(c2h_buf);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+get_h2c_ack_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 cmd_id;
+	u8 sub_cmd_id;
+	u8 fw_rc;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Ack for C2H!!\n");
+
+	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
+	if (HALMAC_H2C_RETURN_SUCCESS != (enum halmac_h2c_return_code)fw_rc)
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "fw rc = %d\n", fw_rc);
+
+	cmd_id = (u8)H2C_ACK_HDR_GET_H2C_CMD_ID(buf);
+
+	if (cmd_id != 0xFF) {
+		pr_err("h2c ack cmd id!!\n");
+		return HALMAC_RET_C2H_NOT_HANDLED;
+	}
+
+	sub_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(buf);
+
+	switch (sub_cmd_id) {
+	case H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK:
+		status = get_h2c_ack_phy_efuse_88xx(adapter, buf, size);
+		break;
+	case H2C_SUB_CMD_ID_CFG_PARAM_ACK:
+		status = get_h2c_ack_cfg_param_88xx(adapter, buf, size);
+		break;
+	case H2C_SUB_CMD_ID_UPDATE_PKT_ACK:
+		status = get_h2c_ack_update_pkt_88xx(adapter, buf, size);
+		break;
+	case H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK:
+		status = get_h2c_ack_update_datapkt_88xx(adapter, buf, size);
+		break;
+	case H2C_SUB_CMD_ID_RUN_DATAPACK_ACK:
+		status = get_h2c_ack_run_datapkt_88xx(adapter, buf, size);
+		break;
+	case H2C_SUB_CMD_ID_CH_SWITCH_ACK:
+		status = get_h2c_ack_ch_switch_88xx(adapter, buf, size);
+		break;
+	case H2C_SUB_CMD_ID_IQK_ACK:
+		status = get_h2c_ack_iqk_88xx(adapter, buf, size);
+		break;
+	case H2C_SUB_CMD_ID_PWR_TRK_ACK:
+		status = get_h2c_ack_pwr_trk_88xx(adapter, buf, size);
+		break;
+	case H2C_SUB_CMD_ID_PSD_ACK:
+		break;
+	case H2C_SUB_CMD_ID_FW_SNDING_ACK:
+		status = get_h2c_ack_fw_snding_88xx(adapter, buf, size);
+		break;
+	default:
+		status = HALMAC_RET_C2H_NOT_HANDLED;
+		break;
+	}
+
+	return status;
+}
+
+static enum halmac_ret_status
+get_scan_rpt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 fw_rc;
+	enum halmac_cmd_process_status proc_status;
+
+	fw_rc = (u8)SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(buf);
+	proc_status = (HALMAC_H2C_RETURN_SUCCESS ==
+		(enum halmac_h2c_return_code)fw_rc) ?
+		HALMAC_CMD_PROCESS_DONE : HALMAC_CMD_PROCESS_ERROR;
+
+	PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status, NULL, 0);
+
+	adapter->halmac_state.scan_state.proc_status = proc_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "scan : %X\n",
+		 proc_status);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+get_h2c_ack_cfg_param_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seq_num;
+	u8 fw_rc;
+	u32 offset_accum;
+	u32 value_accum;
+	struct halmac_cfg_param_state *state =
+		&adapter->halmac_state.cfg_param_state;
+	enum halmac_cmd_process_status proc_status =
+		HALMAC_CMD_PROCESS_UNDEFINE;
+
+	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Seq num : h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("Seq num mismatch : h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not cmd sending\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
+	state->fw_rc = fw_rc;
+	offset_accum = CFG_PARAM_ACK_GET_OFFSET_ACCUMULATION(buf);
+	value_accum = CFG_PARAM_ACK_GET_VALUE_ACCUMULATION(buf);
+
+	if (offset_accum != adapter->cfg_param_info.offset_accum ||
+	    value_accum != adapter->cfg_param_info.value_accum) {
+		pr_err("[C2H]offset_accu : %x, value_accu : %xn", offset_accum,
+		       value_accum);
+		pr_err("[Ada]offset_accu : %x, value_accu : %x\n",
+		       adapter->cfg_param_info.offset_accum,
+		       adapter->cfg_param_info.value_accum);
+		proc_status = HALMAC_CMD_PROCESS_ERROR;
+	}
+
+	if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS &&
+	    proc_status != HALMAC_CMD_PROCESS_ERROR) {
+		proc_status = HALMAC_CMD_PROCESS_DONE;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, proc_status, NULL, 0);
+	} else {
+		proc_status = HALMAC_CMD_PROCESS_ERROR;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, proc_status,
+				&fw_rc, 1);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+get_h2c_ack_update_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seq_num;
+	u8 fw_rc;
+	struct halmac_update_pkt_state *state =
+		&adapter->halmac_state.update_pkt_state;
+	enum halmac_cmd_process_status proc_status;
+
+	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Seq num : h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("Seq num mismatch : h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not cmd sending\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
+	state->fw_rc = fw_rc;
+
+	if (HALMAC_H2C_RETURN_SUCCESS == (enum halmac_h2c_return_code)fw_rc) {
+		proc_status = HALMAC_CMD_PROCESS_DONE;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_UPDATE_PACKET, proc_status,
+				NULL, 0);
+	} else {
+		proc_status = HALMAC_CMD_PROCESS_ERROR;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_UPDATE_PACKET, proc_status,
+				&state->fw_rc, 1);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+get_h2c_ack_update_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf,
+				u32 size)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+static enum halmac_ret_status
+get_h2c_ack_run_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+static enum halmac_ret_status
+get_h2c_ack_ch_switch_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seq_num;
+	u8 fw_rc;
+	struct halmac_scan_state *state = &adapter->halmac_state.scan_state;
+	enum halmac_cmd_process_status proc_status;
+
+	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Seq num : h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("Seq num mismatch : h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not cmd sending\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
+	state->fw_rc = fw_rc;
+
+	if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
+		proc_status = HALMAC_CMD_PROCESS_RCVD;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status,
+				NULL, 0);
+	} else {
+		proc_status = HALMAC_CMD_PROCESS_ERROR;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status,
+				&fw_rc, 1);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * mac_debug_88xx_v1() - read some registers for debug
+ * @adapter
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+mac_debug_88xx(struct halmac_adapter *adapter)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (adapter->intf == HALMAC_INTERFACE_SDIO)
+		dump_reg_sdio_88xx(adapter);
+	else
+		dump_reg_88xx(adapter);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+dump_reg_sdio_88xx(struct halmac_adapter *adapter)
+{
+	u8 tmp8;
+	u32 i;
+
+	/* Dump CCCR, it needs new platform api */
+
+	/*Dump SDIO Local Register, use CMD52*/
+	for (i = 0x10250000; i < 0x102500ff; i++) {
+		tmp8 = PLTFM_SDIO_CMD52_R(i);
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "dbg-sdio[%x]=%x\n", i, tmp8);
+	}
+
+	/*Dump MAC Register*/
+	for (i = 0x0000; i < 0x17ff; i++) {
+		tmp8 = PLTFM_SDIO_CMD52_R(i);
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "dbg-mac[%x]=%x\n", i, tmp8);
+	}
+
+	tmp8 = PLTFM_SDIO_CMD52_R(REG_SDIO_CRC_ERR_IDX);
+	if (tmp8)
+		pr_err("sdio crc=%x\n", tmp8);
+
+	/*Check RX Fifo status*/
+	i = REG_RXFF_PTR_V1;
+	tmp8 = PLTFM_SDIO_CMD52_R(i);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "dbg-mac[%x]=%x\n", i, tmp8);
+	i = REG_RXFF_WTR_V1;
+	tmp8 = PLTFM_SDIO_CMD52_R(i);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "dbg-mac[%x]=%x\n", i, tmp8);
+	i = REG_RXFF_PTR_V1;
+	tmp8 = PLTFM_SDIO_CMD52_R(i);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "dbg-mac[%x]=%x\n", i, tmp8);
+	i = REG_RXFF_WTR_V1;
+	tmp8 = PLTFM_SDIO_CMD52_R(i);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "dbg-mac[%x]=%x\n", i, tmp8);
+}
+
+static void
+dump_reg_88xx(struct halmac_adapter *adapter)
+{
+	u32 tmp32;
+	u32 i;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	/*Dump MAC Register*/
+	for (i = 0x0000; i < 0x17fc; i += 4) {
+		tmp32 = HALMAC_REG_R32(i);
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "dbg-mac[%x]=%x\n", i, tmp32);
+	}
+
+	/*Check RX Fifo status*/
+	i = REG_RXFF_PTR_V1;
+	tmp32 = HALMAC_REG_R32(i);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "dbg-mac[%x]=%x\n", i, tmp32);
+	i = REG_RXFF_WTR_V1;
+	tmp32 = HALMAC_REG_R32(i);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "dbg-mac[%x]=%x\n", i, tmp32);
+	i = REG_RXFF_PTR_V1;
+	tmp32 = HALMAC_REG_R32(i);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "dbg-mac[%x]=%x\n", i, tmp32);
+	i = REG_RXFF_WTR_V1;
+	tmp32 = HALMAC_REG_R32(i);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "dbg-mac[%x]=%x\n", i, tmp32);
+}
+
+/**
+ * cfg_parameter_88xx() - config parameter by FW
+ * @adapter : the adapter of halmac
+ * @info : cmd id, content
+ * @full_fifo : parameter information
+ *
+ * If msk_en = 1, the format of array is {reg_info, mask, value}.
+ * If msk_en =_FAUSE, the format of array is {reg_info, value}
+ * The format of reg_info is
+ * reg_info[31]=rf_reg, 0: MAC_BB reg, 1: RF reg
+ * reg_info[27:24]=rf_path, 0: path_A, 1: path_B
+ * if rf_reg=0(MAC_BB reg), rf_path is meaningless.
+ * ref_info[15:0]=offset
+ *
+ * Example: msk_en = 0
+ * {0x8100000a, 0x00001122}
+ * =>Set RF register, path_B, offset 0xA to 0x00001122
+ * {0x00000824, 0x11224433}
+ * =>Set MAC_BB register, offset 0x800 to 0x11224433
+ *
+ * Note : full fifo mode only for init flow
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_parameter_88xx(struct halmac_adapter *adapter,
+		   struct halmac_phy_parameter_info *info, u8 full_fifo)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+	enum halmac_cmd_construct_state cmd_state;
+
+	proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	if (adapter->fw_ver.h2c_version < 4)
+		return HALMAC_RET_FW_NO_SUPPORT;
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Wait event(para)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	cmd_state = cfg_param_cmd_cnstr_state_88xx(adapter);
+	if (cmd_state != HALMAC_CMD_CNSTR_IDLE &&
+	    cmd_state != HALMAC_CMD_CNSTR_CNSTR) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Not idle(para)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	*proc_status = HALMAC_CMD_PROCESS_IDLE;
+
+	status = proc_cfg_param_88xx(adapter, info, full_fifo);
+
+	if (status != HALMAC_RET_SUCCESS && status != HALMAC_RET_PARA_SENDING) {
+		pr_err("send param h2c\n");
+		return status;
+	}
+
+	return status;
+}
+
+static enum halmac_cmd_construct_state
+cfg_param_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
+{
+	return adapter->halmac_state.cfg_param_state.cmd_cnstr_state;
+}
+
+static enum halmac_ret_status
+proc_cfg_param_88xx(struct halmac_adapter *adapter,
+		    struct halmac_phy_parameter_info *param, u8 full_fifo)
+{
+	u8 end_cmd = 0;
+	u32 rsvd_size;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
+
+	status = malloc_cfg_param_buf_88xx(adapter, full_fifo);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	add_param_buf_88xx(adapter, param, info->buf_wptr, &end_cmd);
+	if (param->cmd_id != HALMAC_PARAMETER_CMD_END) {
+		info->num++;
+		info->buf_wptr += CFG_PARAM_H2C_INFO_SIZE;
+		info->avl_buf_size -= CFG_PARAM_H2C_INFO_SIZE;
+	}
+
+	rsvd_size = info->avl_buf_size - adapter->hw_cfg_info.txdesc_size;
+	if (rsvd_size > CFG_PARAM_H2C_INFO_SIZE && end_cmd == 0)
+		return HALMAC_RET_SUCCESS;
+
+	if (info->num == 0) {
+		kfree(info->buf);
+		info->buf = NULL;
+		info->buf_wptr = NULL;
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "param num = 0!!\n");
+
+		*proc_status = HALMAC_CMD_PROCESS_DONE;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, *proc_status, NULL, 0);
+
+		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CFG_PARA);
+
+		return HALMAC_RET_SUCCESS;
+	}
+
+	status = send_cfg_param_h2c_88xx(adapter);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+
+	if (end_cmd == 0) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "send h2c-buf full\n");
+		return HALMAC_RET_PARA_SENDING;
+	}
+
+	return status;
+}
+
+static enum halmac_ret_status
+send_cfg_param_h2c_88xx(struct halmac_adapter *adapter)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 pg_addr;
+	u16 seq_num = 0;
+	u32 info_size;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
+
+	if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	*proc_status = HALMAC_CMD_PROCESS_SENDING;
+
+	if (info->full_fifo_mode == 1)
+		pg_addr = 0;
+	else
+		pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
+
+	info_size = info->num * CFG_PARAM_H2C_INFO_SIZE;
+
+	status = dl_rsvd_page_88xx(adapter, pg_addr, info->buf, info_size);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("dl rsvd pg!!\n");
+		goto CFG_PARAM_H2C_FAIL;
+	}
+
+	gen_cfg_param_h2c_88xx(adapter, h2c_buf);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_CFG_PARAM;
+	hdr_info.content_size = 4;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	adapter->halmac_state.cfg_param_state.seq_num = seq_num;
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c!!\n");
+		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CFG_PARA);
+	}
+
+CFG_PARAM_H2C_FAIL:
+	kfree(info->buf);
+	info->buf = NULL;
+	info->buf_wptr = NULL;
+
+	if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	return status;
+}
+
+static enum halmac_ret_status
+cnv_cfg_param_state_88xx(struct halmac_adapter *adapter,
+			 enum halmac_cmd_construct_state dest_state)
+{
+	enum halmac_cmd_construct_state *state;
+
+	state = &adapter->halmac_state.cfg_param_state.cmd_cnstr_state;
+
+	if ((*state != HALMAC_CMD_CNSTR_IDLE) &&
+	    (*state != HALMAC_CMD_CNSTR_CNSTR) &&
+	    (*state != HALMAC_CMD_CNSTR_H2C_SENT))
+		return HALMAC_RET_ERROR_STATE;
+
+	if (dest_state == HALMAC_CMD_CNSTR_IDLE) {
+		if (*state == HALMAC_CMD_CNSTR_CNSTR)
+			return HALMAC_RET_ERROR_STATE;
+	} else if (dest_state == HALMAC_CMD_CNSTR_CNSTR) {
+		if (*state == HALMAC_CMD_CNSTR_H2C_SENT)
+			return HALMAC_RET_ERROR_STATE;
+	} else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
+		if ((*state == HALMAC_CMD_CNSTR_IDLE) ||
+		    (*state == HALMAC_CMD_CNSTR_H2C_SENT))
+			return HALMAC_RET_ERROR_STATE;
+	}
+
+	*state = dest_state;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+add_param_buf_88xx(struct halmac_adapter *adapter,
+		   struct halmac_phy_parameter_info *param, u8 *buf,
+		   u8 *end_cmd)
+{
+	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
+	union halmac_parameter_content *content = &param->content;
+
+	*end_cmd = 0;
+
+	PARAM_INFO_SET_LEN(buf, CFG_PARAM_H2C_INFO_SIZE);
+	PARAM_INFO_SET_IO_CMD(buf, param->cmd_id);
+
+	switch (param->cmd_id) {
+	case HALMAC_PARAMETER_CMD_BB_W8:
+	case HALMAC_PARAMETER_CMD_BB_W16:
+	case HALMAC_PARAMETER_CMD_BB_W32:
+	case HALMAC_PARAMETER_CMD_MAC_W8:
+	case HALMAC_PARAMETER_CMD_MAC_W16:
+	case HALMAC_PARAMETER_CMD_MAC_W32:
+		PARAM_INFO_SET_IO_ADDR(buf, content->MAC_REG_W.offset);
+		PARAM_INFO_SET_DATA(buf, content->MAC_REG_W.value);
+		PARAM_INFO_SET_MASK(buf, content->MAC_REG_W.msk);
+		PARAM_INFO_SET_MSK_EN(buf, content->MAC_REG_W.msk_en);
+		info->value_accum += content->MAC_REG_W.value;
+		info->offset_accum += content->MAC_REG_W.offset;
+		break;
+	case HALMAC_PARAMETER_CMD_RF_W:
+		/*In rf register, the address is only 1 byte*/
+		PARAM_INFO_SET_RF_ADDR(buf, content->RF_REG_W.offset);
+		PARAM_INFO_SET_RF_PATH(buf, content->RF_REG_W.rf_path);
+		PARAM_INFO_SET_DATA(buf, content->RF_REG_W.value);
+		PARAM_INFO_SET_MASK(buf, content->RF_REG_W.msk);
+		PARAM_INFO_SET_MSK_EN(buf, content->RF_REG_W.msk_en);
+		info->value_accum += content->RF_REG_W.value;
+		info->offset_accum += (content->RF_REG_W.offset +
+					(content->RF_REG_W.rf_path << 8));
+		break;
+	case HALMAC_PARAMETER_CMD_DELAY_US:
+	case HALMAC_PARAMETER_CMD_DELAY_MS:
+		PARAM_INFO_SET_DELAY_VAL(buf, content->DELAY_TIME.delay_time);
+		break;
+	case HALMAC_PARAMETER_CMD_END:
+		*end_cmd = 1;
+		break;
+	default:
+		pr_err("cmd id!!\n");
+		break;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+gen_cfg_param_h2c_88xx(struct halmac_adapter *adapter, u8 *buff)
+{
+	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
+	u16 h2c_info_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
+	u16 rsvd_pg_addr = adapter->txff_alloc.rsvd_boundary;
+
+	CFG_PARAM_SET_NUM(buff, info->num);
+
+	if (info->full_fifo_mode == 1) {
+		CFG_PARAM_SET_INIT_CASE(buff, 0x1);
+		CFG_PARAM_SET_LOC(buff, 0);
+	} else {
+		CFG_PARAM_SET_INIT_CASE(buff, 0x0);
+		CFG_PARAM_SET_LOC(buff, h2c_info_addr - rsvd_pg_addr);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+malloc_cfg_param_buf_88xx(struct halmac_adapter *adapter, u8 full_fifo)
+{
+	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
+	struct halmac_pltfm_cfg_info *pltfm_info = &adapter->pltfm_info;
+
+	if (info->buf)
+		return HALMAC_RET_SUCCESS;
+
+	if (full_fifo == 1)
+		info->buf_size = pltfm_info->malloc_size;
+	else
+		info->buf_size = CFG_PARAM_RSVDPG_SIZE;
+
+	if (info->buf_size > pltfm_info->rsvd_pg_size)
+		info->buf_size = pltfm_info->rsvd_pg_size;
+
+	info->buf = smart_malloc_88xx(adapter, info->buf_size, &info->buf_size);
+	if (info->buf) {
+		memset(info->buf, 0x00, info->buf_size);
+		info->full_fifo_mode = full_fifo;
+		info->buf_wptr = info->buf;
+		info->num = 0;
+		info->avl_buf_size = info->buf_size;
+		info->value_accum = 0;
+		info->offset_accum = 0;
+	} else {
+		return HALMAC_RET_MALLOC_FAIL;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * update_packet_88xx() - send specific packet to FW
+ * @adapter : the adapter of halmac
+ * @pkt_id : packet id, to know the purpose of this packet
+ * @pkt : packet
+ * @size : packet size
+ *
+ * Note : TX_DESC is not included in the pkt
+ *
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+update_packet_88xx(struct halmac_adapter *adapter, enum halmac_packet_id pkt_id,
+		   u8 *pkt, u32 size)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status =
+		&adapter->halmac_state.update_pkt_state.proc_status;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	if (adapter->fw_ver.h2c_version < 4)
+		return HALMAC_RET_FW_NO_SUPPORT;
+
+	if (size > UPDATE_PKT_RSVDPG_SIZE)
+		return HALMAC_RET_RSVD_PG_OVERFLOW_FAIL;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Wait event(upd)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	*proc_status = HALMAC_CMD_PROCESS_SENDING;
+
+	status = send_h2c_update_packet_88xx(adapter, pkt_id, pkt, size);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c!!\n");
+		pr_err("pkt id : %X!!\n", pkt_id);
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+send_h2c_update_packet_88xx(struct halmac_adapter *adapter,
+			    enum halmac_packet_id pkt_id, u8 *pkt, u32 size)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	u16 pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
+	u16 pg_offset;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	status = dl_rsvd_page_88xx(adapter, pg_addr, pkt, size);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("dl rsvd pg!!\n");
+		return status;
+	}
+
+	pg_offset = pg_addr - adapter->txff_alloc.rsvd_boundary;
+	UPDATE_PKT_SET_SIZE(h2c_buf, size + adapter->hw_cfg_info.txdesc_size);
+	UPDATE_PKT_SET_ID(h2c_buf, pkt_id);
+	UPDATE_PKT_SET_LOC(h2c_buf, pg_offset);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_UPDATE_PKT;
+	hdr_info.content_size = 8;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+	adapter->halmac_state.update_pkt_state.seq_num = seq_num;
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c!!\n");
+		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_UPDATE_PACKET);
+		return status;
+	}
+
+	return status;
+}
+
+enum halmac_ret_status
+bcn_ie_filter_88xx(struct halmac_adapter *adapter,
+		   struct halmac_bcn_ie_info *info)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+enum halmac_ret_status
+update_datapack_88xx(struct halmac_adapter *adapter,
+		     enum halmac_data_type data_type,
+		     struct halmac_phy_parameter_info *info)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+enum halmac_ret_status
+run_datapack_88xx(struct halmac_adapter *adapter,
+		  enum halmac_data_type data_type)
+{
+	return HALMAC_RET_NOT_SUPPORT;
+}
+
+enum halmac_ret_status
+send_bt_coex_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size, u8 ack)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	status = send_bt_coex_cmd_88xx(adapter, buf, size, ack);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("bt coex cmd!!\n");
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+send_bt_coex_cmd_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
+		      u8 ack)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	memcpy(h2c_buf + 8, buf, size);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_BT_COEX;
+	hdr_info.content_size = (u16)size;
+	hdr_info.ack = ack;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c!!\n");
+		return status;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * dump_fifo_88xx() - dump fifo data
+ * @adapter : the adapter of halmac
+ * @sel : FIFO selection
+ * @start_addr : start address of selected FIFO
+ * @size : dump size of selected FIFO
+ * @data : FIFO data
+ *
+ * Note : before dump fifo, user need to call halmac_get_fifo_size to
+ * get fifo size. Then input this size to halmac_dump_fifo.
+ *
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+dump_fifo_88xx(struct halmac_adapter *adapter, enum hal_fifo_sel sel,
+	       u32 start_addr, u32 size, u8 *data)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	u8 tmp8;
+	u8 enable;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (sel == HAL_FIFO_SEL_TX &&
+	    (start_addr + size) > adapter->hw_cfg_info.tx_fifo_size) {
+		pr_err("size overflow!!\n");
+		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
+	}
+
+	if (sel == HAL_FIFO_SEL_RX &&
+	    (start_addr + size) > adapter->hw_cfg_info.rx_fifo_size) {
+		pr_err("size overflow!!\n");
+		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
+	}
+
+	if ((size & (4 - 1)) != 0) {
+		pr_err("not 4byte alignment!!\n");
+		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
+	}
+
+	if (!data)
+		return HALMAC_RET_NULL_POINTER;
+
+	tmp8 = HALMAC_REG_R8(REG_RCR + 2);
+	enable = 0;
+	status = api->halmac_set_hw_value(adapter, HALMAC_HW_RX_CLK_GATE,
+					  &enable);
+	if (status != HALMAC_RET_SUCCESS)
+		return status;
+	status = read_buf_88xx(adapter, start_addr, size, sel, data);
+
+	HALMAC_REG_W8(REG_RCR + 2, tmp8);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("read buf!!\n");
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+read_buf_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
+	      enum hal_fifo_sel sel, u8 *data)
+{
+	u32 start_pg;
+	u32 value32;
+	u32 i;
+	u32 residue;
+	u32 cnt = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (sel == HAL_FIFO_SEL_RSVD_PAGE)
+		offset += (adapter->txff_alloc.rsvd_boundary <<
+			   TX_PAGE_SIZE_SHIFT_88XX);
+
+	start_pg = offset >> 12;
+	residue = offset & (4096 - 1);
+
+	if (sel == HAL_FIFO_SEL_TX || sel == HAL_FIFO_SEL_RSVD_PAGE)
+		start_pg += 0x780;
+	else if (sel == HAL_FIFO_SEL_RX)
+		start_pg += 0x700;
+	else if (sel == HAL_FIFO_SEL_REPORT)
+		start_pg += 0x660;
+	else if (sel == HAL_FIFO_SEL_LLT)
+		start_pg += 0x650;
+	else if (sel == HAL_FIFO_SEL_RXBUF_FW)
+		start_pg += 0x680;
+	else
+		return HALMAC_RET_NOT_SUPPORT;
+
+	value32 = HALMAC_REG_R16(REG_PKTBUF_DBG_CTRL) & 0xF000;
+
+	do {
+		HALMAC_REG_W16(REG_PKTBUF_DBG_CTRL, (u16)(start_pg | value32));
+
+		for (i = 0x8000 + residue; i <= 0x8FFF; i += 4) {
+			*(u32 *)(data + cnt) = HALMAC_REG_R32(i);
+			*(u32 *)(data + cnt) =
+				le32_to_cpu(*(u32 *)(data + cnt));
+			cnt += 4;
+			if (size == cnt)
+				goto HALMAC_BUF_READ_OK;
+		}
+
+		residue = 0;
+		start_pg++;
+	} while (1);
+
+HALMAC_BUF_READ_OK:
+	HALMAC_REG_W16(REG_PKTBUF_DBG_CTRL, (u16)value32);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * get_fifo_size_88xx() - get fifo size
+ * @adapter : the adapter of halmac
+ * @sel : FIFO selection
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : u32
+ * More details of status code can be found in prototype document
+ */
+u32
+get_fifo_size_88xx(struct halmac_adapter *adapter, enum hal_fifo_sel sel)
+{
+	u32 size = 0;
+
+	if (sel == HAL_FIFO_SEL_TX)
+		size = adapter->hw_cfg_info.tx_fifo_size;
+	else if (sel == HAL_FIFO_SEL_RX)
+		size = adapter->hw_cfg_info.rx_fifo_size;
+	else if (sel == HAL_FIFO_SEL_RSVD_PAGE)
+		size = adapter->hw_cfg_info.tx_fifo_size -
+		       (adapter->txff_alloc.rsvd_boundary <<
+			TX_PAGE_SIZE_SHIFT_88XX);
+	else if (sel == HAL_FIFO_SEL_REPORT)
+		size = 65536;
+	else if (sel == HAL_FIFO_SEL_LLT)
+		size = 65536;
+	else if (sel == HAL_FIFO_SEL_RXBUF_FW)
+		size = RX_BUF_FW_88XX;
+
+	return size;
+}
+
+enum halmac_ret_status
+set_h2c_header_88xx(struct halmac_adapter *adapter, u8 *hdr, u16 *seq, u8 ack)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s!!\n",
+		 __func__);
+
+	H2C_CMD_HEADER_SET_CATEGORY(hdr, 0x00);
+	H2C_CMD_HEADER_SET_TOTAL_LEN(hdr, 16);
+
+	mutex_lock(&adapter->h2c_seq_mutex);
+	H2C_CMD_HEADER_SET_SEQ_NUM(hdr, adapter->h2c_info.seq_num);
+	*seq = adapter->h2c_info.seq_num;
+	(adapter->h2c_info.seq_num)++;
+	mutex_unlock(&adapter->h2c_seq_mutex);
+
+	if (ack == 1)
+		H2C_CMD_HEADER_SET_ACK(hdr, 1);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * add_ch_info_88xx() -add channel information
+ * @adapter : the adapter of halmac
+ * @info : channel information
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+add_ch_info_88xx(struct halmac_adapter *adapter, struct halmac_ch_info *info)
+{
+	struct halmac_ch_sw_info *ch_sw_info = &adapter->ch_sw_info;
+	enum halmac_cmd_construct_state state;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT) {
+		pr_err("gen info\n");
+		return HALMAC_RET_GEN_INFO_NOT_SENT;
+	}
+
+	state = scan_cmd_cnstr_state_88xx(adapter);
+	if (state != HALMAC_CMD_CNSTR_BUF_CLR &&
+	    state != HALMAC_CMD_CNSTR_CNSTR) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "cmd state (scan)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	if (!ch_sw_info->buf) {
+		ch_sw_info->buf = kzalloc(SCAN_INFO_RSVDPG_SIZE, GFP_KERNEL);
+		if (!ch_sw_info->buf)
+			return HALMAC_RET_NULL_POINTER;
+		ch_sw_info->buf_wptr = ch_sw_info->buf;
+		ch_sw_info->buf_size = SCAN_INFO_RSVDPG_SIZE;
+		ch_sw_info->avl_buf_size = SCAN_INFO_RSVDPG_SIZE;
+		ch_sw_info->total_size = 0;
+		ch_sw_info->extra_info_en = 0;
+		ch_sw_info->ch_num = 0;
+	}
+
+	if (ch_sw_info->extra_info_en == 1) {
+		pr_err("extra info = 1!!\n");
+		return HALMAC_RET_CH_SW_SEQ_WRONG;
+	}
+
+	if (ch_sw_info->avl_buf_size < 4) {
+		pr_err("buf full!!\n");
+		return HALMAC_RET_CH_SW_NO_BUF;
+	}
+
+	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	CH_INFO_SET_CH(ch_sw_info->buf_wptr, info->channel);
+	CH_INFO_SET_PRI_CH_IDX(ch_sw_info->buf_wptr, info->pri_ch_idx);
+	CH_INFO_SET_BW(ch_sw_info->buf_wptr, info->bw);
+	CH_INFO_SET_TIMEOUT(ch_sw_info->buf_wptr, info->timeout);
+	CH_INFO_SET_ACTION_ID(ch_sw_info->buf_wptr, info->action_id);
+	CH_INFO_SET_EXTRA_INFO(ch_sw_info->buf_wptr, info->extra_info);
+
+	ch_sw_info->avl_buf_size = ch_sw_info->avl_buf_size - 4;
+	ch_sw_info->total_size = ch_sw_info->total_size + 4;
+	ch_sw_info->ch_num++;
+	ch_sw_info->extra_info_en = info->extra_info;
+	ch_sw_info->buf_wptr = ch_sw_info->buf_wptr + 4;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_cmd_construct_state
+scan_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
+{
+	return adapter->halmac_state.scan_state.cmd_cnstr_state;
+}
+
+static enum halmac_ret_status
+cnv_scan_state_88xx(struct halmac_adapter *adapter,
+		    enum halmac_cmd_construct_state dest_state)
+{
+	enum halmac_cmd_construct_state *state;
+
+	state = &adapter->halmac_state.scan_state.cmd_cnstr_state;
+
+	if (dest_state == HALMAC_CMD_CNSTR_IDLE) {
+		if ((*state == HALMAC_CMD_CNSTR_BUF_CLR) ||
+		    (*state == HALMAC_CMD_CNSTR_CNSTR))
+			return HALMAC_RET_ERROR_STATE;
+	} else if (dest_state == HALMAC_CMD_CNSTR_BUF_CLR) {
+		if (*state == HALMAC_CMD_CNSTR_H2C_SENT)
+			return HALMAC_RET_ERROR_STATE;
+	} else if (dest_state == HALMAC_CMD_CNSTR_CNSTR) {
+		if ((*state == HALMAC_CMD_CNSTR_IDLE) ||
+		    (*state == HALMAC_CMD_CNSTR_H2C_SENT))
+			return HALMAC_RET_ERROR_STATE;
+	} else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
+		if ((*state != HALMAC_CMD_CNSTR_CNSTR) &&
+		    (*state != HALMAC_CMD_CNSTR_BUF_CLR))
+			return HALMAC_RET_ERROR_STATE;
+	}
+
+	*state = dest_state;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * add_extra_ch_info_88xx() -add extra channel information
+ * @adapter : the adapter of halmac
+ * @info : extra channel information
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+add_extra_ch_info_88xx(struct halmac_adapter *adapter,
+		       struct halmac_ch_extra_info *info)
+{
+	struct halmac_ch_sw_info *ch_sw_info = &adapter->ch_sw_info;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (!ch_sw_info->buf) {
+		pr_err("buf = null!!\n");
+		return HALMAC_RET_CH_SW_SEQ_WRONG;
+	}
+
+	if (ch_sw_info->extra_info_en == 0) {
+		pr_err("extra info = 0!!\n");
+		return HALMAC_RET_CH_SW_SEQ_WRONG;
+	}
+
+	if (ch_sw_info->avl_buf_size < (u32)(info->extra_info_size + 2)) {
+		pr_err("no available buffer!!\n");
+		return HALMAC_RET_CH_SW_NO_BUF;
+	}
+
+	if (scan_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_CNSTR) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "cmd state (ex scan)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	CH_EXTRA_INFO_SET_ID(ch_sw_info->buf_wptr, info->extra_action_id);
+	CH_EXTRA_INFO_SET_INFO(ch_sw_info->buf_wptr, info->extra_info);
+	CH_EXTRA_INFO_SET_SIZE(ch_sw_info->buf_wptr, info->extra_info_size);
+	memcpy(ch_sw_info->buf_wptr + 2, info->extra_info_data,
+	       info->extra_info_size);
+
+	ch_sw_info->avl_buf_size -= (2 + info->extra_info_size);
+	ch_sw_info->total_size += (2 + info->extra_info_size);
+	ch_sw_info->extra_info_en = info->extra_info;
+	ch_sw_info->buf_wptr += (2 + info->extra_info_size);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * ctrl_ch_switch_88xx() -send channel switch cmd
+ * @adapter : the adapter of halmac
+ * @opt : channel switch config
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
+		    struct halmac_ch_switch_option *opt)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_construct_state state;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.scan_state.proc_status;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	if (adapter->fw_ver.h2c_version < 4)
+		return HALMAC_RET_FW_NO_SUPPORT;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (opt->switch_en == 0)
+		*proc_status = HALMAC_CMD_PROCESS_IDLE;
+
+	if ((*proc_status == HALMAC_CMD_PROCESS_SENDING) ||
+	    (*proc_status == HALMAC_CMD_PROCESS_RCVD)) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Wait event(scan)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	state = scan_cmd_cnstr_state_88xx(adapter);
+	if (opt->switch_en == 1) {
+		if (state != HALMAC_CMD_CNSTR_CNSTR) {
+			pr_err("state(en = 1)\n");
+			return HALMAC_RET_ERROR_STATE;
+		}
+	} else {
+		if (state != HALMAC_CMD_CNSTR_BUF_CLR) {
+			pr_err("state(en = 0)\n");
+			return HALMAC_RET_ERROR_STATE;
+		}
+	}
+
+	status = proc_ctrl_ch_switch_88xx(adapter, opt);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("ctrl ch sw!!\n");
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+proc_ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
+			 struct halmac_ch_switch_option *opt)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	u16 pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.scan_state.proc_status;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	*proc_status = HALMAC_CMD_PROCESS_SENDING;
+
+	if (opt->switch_en != 0) {
+		status = dl_rsvd_page_88xx(adapter, pg_addr,
+					   adapter->ch_sw_info.buf,
+					   adapter->ch_sw_info.total_size);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("dl rsvd pg!!\n");
+			return status;
+		}
+	}
+
+	CH_SWITCH_SET_START(h2c_buf, opt->switch_en);
+	CH_SWITCH_SET_CH_NUM(h2c_buf, adapter->ch_sw_info.ch_num);
+	CH_SWITCH_SET_INFO_LOC(h2c_buf,
+			       pg_addr - adapter->txff_alloc.rsvd_boundary);
+	CH_SWITCH_SET_DEST_CH_EN(h2c_buf, opt->dest_ch_en);
+	CH_SWITCH_SET_DEST_CH(h2c_buf, opt->dest_ch);
+	CH_SWITCH_SET_PRI_CH_IDX(h2c_buf, opt->dest_pri_ch_idx);
+	CH_SWITCH_SET_ABSOLUTE_TIME(h2c_buf, opt->absolute_time_en);
+	CH_SWITCH_SET_TSF_LOW(h2c_buf, opt->tsf_low);
+	CH_SWITCH_SET_PERIODIC_OPT(h2c_buf, opt->periodic_option);
+	CH_SWITCH_SET_NORMAL_CYCLE(h2c_buf, opt->normal_cycle);
+	CH_SWITCH_SET_NORMAL_PERIOD(h2c_buf, opt->normal_period);
+	CH_SWITCH_SET_SLOW_PERIOD(h2c_buf, opt->phase_2_period);
+	CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_buf, opt->normal_period_sel);
+	CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_buf, opt->phase_2_period_sel);
+	CH_SWITCH_SET_INFO_SIZE(h2c_buf, adapter->ch_sw_info.total_size);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_CH_SWITCH;
+	hdr_info.content_size = 20;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+	adapter->halmac_state.scan_state.seq_num = seq_num;
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c!!\n");
+		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CHANNEL_SWITCH);
+	}
+	kfree(adapter->ch_sw_info.buf);
+	adapter->ch_sw_info.buf = NULL;
+	adapter->ch_sw_info.buf_wptr = NULL;
+	adapter->ch_sw_info.extra_info_en = 0;
+	adapter->ch_sw_info.buf_size = 0;
+	adapter->ch_sw_info.avl_buf_size = 0;
+	adapter->ch_sw_info.total_size = 0;
+	adapter->ch_sw_info.ch_num = 0;
+
+	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	return status;
+}
+
+/**
+ * clear_ch_info_88xx() -clear channel information
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+clear_ch_info_88xx(struct halmac_adapter *adapter)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (scan_cmd_cnstr_state_88xx(adapter) == HALMAC_CMD_CNSTR_H2C_SENT) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_WARNING,
+			 "state(clear)\n");
+		return HALMAC_RET_ERROR_STATE;
+	}
+
+	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_BUF_CLR) !=
+	    HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	kfree(adapter->ch_sw_info.buf);
+	adapter->ch_sw_info.buf = NULL;
+	adapter->ch_sw_info.buf_wptr = NULL;
+	adapter->ch_sw_info.extra_info_en = 0;
+	adapter->ch_sw_info.buf_size = 0;
+	adapter->ch_sw_info.avl_buf_size = 0;
+	adapter->ch_sw_info.total_size = 0;
+	adapter->ch_sw_info.ch_num = 0;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * chk_txdesc_88xx() -check if the tx packet format is incorrect
+ * @adapter : the adapter of halmac
+ * @buf : tx Packet buffer, tx desc is included
+ * @size : tx packet size
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+chk_txdesc_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u32 mac_clk = 0;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (GET_TX_DESC_BMC(buf) == 1 && GET_TX_DESC_AGG_EN(buf) == 1)
+		pr_err("txdesc - agg + bmc\n");
+
+	if (size < (GET_TX_DESC_TXPKTSIZE(buf) +
+		    adapter->hw_cfg_info.txdesc_size +
+		    (GET_TX_DESC_PKT_OFFSET(buf) << 3))) {
+		pr_err("txdesc - total size\n");
+		status = HALMAC_RET_TXDESC_SET_FAIL;
+	}
+
+	if (wlhdr_valid_88xx(adapter, buf) != HALMAC_RET_SUCCESS) {
+		pr_err("wlhdr\n");
+		status = HALMAC_RET_WLHDR_FAIL;
+	}
+
+	if (GET_TX_DESC_AMSDU_PAD_EN(buf) != 0) {
+		pr_err("txdesc - amsdu_pad\n");
+		status = HALMAC_RET_TXDESC_SET_FAIL;
+	}
+
+	switch (BIT_GET_MAC_CLK_SEL(HALMAC_REG_R32(REG_AFE_CTRL1))) {
+	case 0x0:
+		mac_clk = 80;
+		break;
+	case 0x1:
+		mac_clk = 40;
+		break;
+	case 0x2:
+		mac_clk = 20;
+		break;
+	case 0x3:
+		mac_clk = 10;
+		break;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "MAC clock : 0x%XM\n", mac_clk);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "mac agg en : 0x%X\n", GET_TX_DESC_AGG_EN(buf));
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "mac agg num : 0x%X\n", GET_TX_DESC_MAX_AGG_NUM(buf));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return status;
+}
+
+static enum halmac_ret_status
+wlhdr_valid_88xx(struct halmac_adapter *adapter, u8 *buf)
+{
+	u32 txdesc_size = adapter->hw_cfg_info.txdesc_size +
+						GET_TX_DESC_PKT_OFFSET(buf);
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct wlhdr_frame_ctrl *wlhdr;
+
+	wlhdr = (struct wlhdr_frame_ctrl *)(buf + txdesc_size);
+
+	if (wlhdr->protocol != WLHDR_PROT_VER) {
+		pr_err("prot ver!!\n");
+		return HALMAC_RET_WLHDR_FAIL;
+	}
+
+	switch (wlhdr->type) {
+	case WLHDR_TYPE_MGMT:
+		if (wlhdr_mgmt_valid_88xx(adapter, wlhdr) != 1)
+			status = HALMAC_RET_WLHDR_FAIL;
+		break;
+	case WLHDR_TYPE_CTRL:
+		if (wlhdr_ctrl_valid_88xx(adapter, wlhdr) != 1)
+			status = HALMAC_RET_WLHDR_FAIL;
+		break;
+	case WLHDR_TYPE_DATA:
+		if (wlhdr_data_valid_88xx(adapter, wlhdr) != 1)
+			status = HALMAC_RET_WLHDR_FAIL;
+		break;
+	default:
+		pr_err("undefined type!!\n");
+		status = HALMAC_RET_WLHDR_FAIL;
+		break;
+	}
+
+	return status;
+}
+
+static u8
+wlhdr_mgmt_valid_88xx(struct halmac_adapter *adapter,
+		      struct wlhdr_frame_ctrl *wlhdr)
+{
+	u8 state;
+
+	switch (wlhdr->sub_type) {
+	case WLHDR_SUB_TYPE_ASSOC_REQ:
+	case WLHDR_SUB_TYPE_ASSOC_RSPNS:
+	case WLHDR_SUB_TYPE_REASSOC_REQ:
+	case WLHDR_SUB_TYPE_REASSOC_RSPNS:
+	case WLHDR_SUB_TYPE_PROBE_REQ:
+	case WLHDR_SUB_TYPE_PROBE_RSPNS:
+	case WLHDR_SUB_TYPE_BCN:
+	case WLHDR_SUB_TYPE_DISASSOC:
+	case WLHDR_SUB_TYPE_AUTH:
+	case WLHDR_SUB_TYPE_DEAUTH:
+	case WLHDR_SUB_TYPE_ACTION:
+	case WLHDR_SUB_TYPE_ACTION_NOACK:
+		state = 1;
+		break;
+	default:
+		pr_err("mgmt invalid!!\n");
+		state = 0;
+		break;
+	}
+
+	return state;
+}
+
+static u8
+wlhdr_ctrl_valid_88xx(struct halmac_adapter *adapter,
+		      struct wlhdr_frame_ctrl *wlhdr)
+{
+	u8 state;
+
+	switch (wlhdr->sub_type) {
+	case WLHDR_SUB_TYPE_BF_RPT_POLL:
+	case WLHDR_SUB_TYPE_NDPA:
+		state = 1;
+		break;
+	default:
+		pr_err("ctrl invalid!!\n");
+		state = 0;
+		break;
+	}
+
+	return state;
+}
+
+static u8
+wlhdr_data_valid_88xx(struct halmac_adapter *adapter,
+		      struct wlhdr_frame_ctrl *wlhdr)
+{
+	u8 state;
+
+	switch (wlhdr->sub_type) {
+	case WLHDR_SUB_TYPE_DATA:
+	case WLHDR_SUB_TYPE_NULL:
+	case WLHDR_SUB_TYPE_QOS_DATA:
+	case WLHDR_SUB_TYPE_QOS_NULL:
+		state = 1;
+		break;
+	default:
+		pr_err("data invalid!!\n");
+		state = 0;
+		break;
+	}
+
+	return state;
+}
+
+/**
+ * get_version_88xx() - get HALMAC version
+ * @ver : return version of major, prototype and minor information
+ * Author : KaiYuan Chang / Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+get_version_88xx(struct halmac_adapter *adapter, struct halmac_ver *ver)
+{
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	ver->major_ver = (u8)HALMAC_MAJOR_VER;
+	ver->prototype_ver = (u8)HALMAC_PROTOTYPE_VER;
+	ver->minor_ver = (u8)HALMAC_MINOR_VER;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	if (adapter->fw_ver.h2c_version < 6)
+		return HALMAC_RET_FW_NO_SUPPORT;
+
+	status = proc_p2pps_88xx(adapter, info);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("p2pps!!\n");
+		return status;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+proc_p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	P2PPS_SET_OFFLOAD_EN(h2c_buf, info->offload_en);
+	P2PPS_SET_ROLE(h2c_buf, info->role);
+	P2PPS_SET_CTWINDOW_EN(h2c_buf, info->ctwindow_en);
+	P2PPS_SET_NOA_EN(h2c_buf, info->noa_en);
+	P2PPS_SET_NOA_SEL(h2c_buf, info->noa_sel);
+	P2PPS_SET_ALLSTASLEEP(h2c_buf, info->all_sta_sleep);
+	P2PPS_SET_DISCOVERY(h2c_buf, info->discovery);
+	P2PPS_SET_DISABLE_CLOSERF(h2c_buf, info->disable_close_rf);
+	P2PPS_SET_P2P_PORT_ID(h2c_buf, info->p2p_port_id);
+	P2PPS_SET_P2P_GROUP(h2c_buf, info->p2p_group);
+	P2PPS_SET_P2P_MACID(h2c_buf, info->p2p_macid);
+
+	P2PPS_SET_CTWINDOW_LENGTH(h2c_buf, info->ctwindow_length);
+
+	P2PPS_SET_NOA_DURATION_PARA(h2c_buf, info->noa_duration_para);
+	P2PPS_SET_NOA_INTERVAL_PARA(h2c_buf, info->noa_interval_para);
+	P2PPS_SET_NOA_START_TIME_PARA(h2c_buf, info->noa_start_time_para);
+	P2PPS_SET_NOA_COUNT_PARA(h2c_buf, info->noa_count_para);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_P2PPS;
+	hdr_info.content_size = 24;
+	hdr_info.ack = 0;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS)
+		pr_err("send h2c!!\n");
+
+	return status;
+}
+
+/**
+ * query_status_88xx() -query the offload feature status
+ * @adapter : the adapter of halmac
+ * @feature_id : feature_id
+ * @proc_status : feature_status
+ * @data : data buffer
+ * @size : data size
+ *
+ * Note :
+ * If user wants to know the data size, user can allocate zero
+ * size buffer first. If this size less than the data size, halmac
+ * will return  HALMAC_RET_BUFFER_TOO_SMALL. User need to
+ * re-allocate data buffer with correct data size.
+ *
+ * Author : Ivan Lin/KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+query_status_88xx(struct halmac_adapter *adapter,
+		  enum halmac_feature_id feature_id,
+		  enum halmac_cmd_process_status *proc_status, u8 *data,
+		  u32 *size)
+{
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+
+	if (!proc_status)
+		return HALMAC_RET_NULL_POINTER;
+
+	switch (feature_id) {
+	case HALMAC_FEATURE_CFG_PARA:
+		status = get_cfg_param_status_88xx(adapter, proc_status);
+		break;
+	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
+		status = get_dump_phy_efuse_status_88xx(adapter, proc_status,
+							data, size);
+		break;
+	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
+		status = get_dump_log_efuse_status_88xx(adapter, proc_status,
+							data, size);
+		break;
+	case HALMAC_FEATURE_CHANNEL_SWITCH:
+		status = get_ch_switch_status_88xx(adapter, proc_status);
+		break;
+	case HALMAC_FEATURE_UPDATE_PACKET:
+		status = get_update_packet_status_88xx(adapter, proc_status);
+		break;
+	case HALMAC_FEATURE_IQK:
+		status = get_iqk_status_88xx(adapter, proc_status);
+		break;
+	case HALMAC_FEATURE_POWER_TRACKING:
+		status = get_pwr_trk_status_88xx(adapter, proc_status);
+		break;
+	case HALMAC_FEATURE_PSD:
+		status = get_psd_status_88xx(adapter, proc_status, data, size);
+		break;
+	case HALMAC_FEATURE_FW_SNDING:
+		status = get_fw_snding_status_88xx(adapter, proc_status);
+		break;
+	default:
+		return HALMAC_RET_INVALID_FEATURE_ID;
+	}
+
+	return status;
+}
+
+static enum halmac_ret_status
+get_cfg_param_status_88xx(struct halmac_adapter *adapter,
+			  enum halmac_cmd_process_status *proc_status)
+{
+	*proc_status = adapter->halmac_state.cfg_param_state.proc_status;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+get_ch_switch_status_88xx(struct halmac_adapter *adapter,
+			  enum halmac_cmd_process_status *proc_status)
+{
+	*proc_status = adapter->halmac_state.scan_state.proc_status;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+get_update_packet_status_88xx(struct halmac_adapter *adapter,
+			      enum halmac_cmd_process_status *proc_status)
+{
+	*proc_status = adapter->halmac_state.update_pkt_state.proc_status;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_drv_rsvd_pg_num_88xx() -config reserved page number for driver
+ * @adapter : the adapter of halmac
+ * @pg_num : page number
+ * Author : KaiYuan Chang
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *adapter,
+			 enum halmac_drv_rsvd_pg_num pg_num)
+{
+	if (adapter->api_registry.cfg_drv_rsvd_pg_en == 0)
+		return HALMAC_RET_NOT_SUPPORT;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "pg_num = %d\n",
+		 pg_num);
+
+	switch (pg_num) {
+	case HALMAC_RSVD_PG_NUM8:
+		adapter->txff_alloc.rsvd_drv_pg_num = 8;
+		break;
+	case HALMAC_RSVD_PG_NUM16:
+		adapter->txff_alloc.rsvd_drv_pg_num = 16;
+		break;
+	case HALMAC_RSVD_PG_NUM24:
+		adapter->txff_alloc.rsvd_drv_pg_num = 24;
+		break;
+	case HALMAC_RSVD_PG_NUM32:
+		adapter->txff_alloc.rsvd_drv_pg_num = 32;
+		break;
+	case HALMAC_RSVD_PG_NUM64:
+		adapter->txff_alloc.rsvd_drv_pg_num = 64;
+		break;
+	case HALMAC_RSVD_PG_NUM128:
+		adapter->txff_alloc.rsvd_drv_pg_num = 128;
+		break;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * (debug API)h2c_lb_88xx() - send h2c loopback packet
+ * @adapter : the adapter of halmac
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+h2c_lb_88xx(struct halmac_adapter *adapter)
+{
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+pwr_seq_parser_88xx(struct halmac_adapter *adapter,
+		    struct halmac_wlan_pwr_cfg **cmd_seq)
+{
+	u8 cut;
+	u8 intf;
+	u32 idx = 0;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_wlan_pwr_cfg *cmd;
+
+	switch (adapter->chip_ver) {
+	case HALMAC_CHIP_VER_A_CUT:
+		cut = HALMAC_PWR_CUT_A_MSK;
+		break;
+	case HALMAC_CHIP_VER_B_CUT:
+		cut = HALMAC_PWR_CUT_B_MSK;
+		break;
+	case HALMAC_CHIP_VER_C_CUT:
+		cut = HALMAC_PWR_CUT_C_MSK;
+		break;
+	case HALMAC_CHIP_VER_D_CUT:
+		cut = HALMAC_PWR_CUT_D_MSK;
+		break;
+	case HALMAC_CHIP_VER_E_CUT:
+		cut = HALMAC_PWR_CUT_E_MSK;
+		break;
+	case HALMAC_CHIP_VER_F_CUT:
+		cut = HALMAC_PWR_CUT_F_MSK;
+		break;
+	case HALMAC_CHIP_VER_TEST:
+		cut = HALMAC_PWR_CUT_TESTCHIP_MSK;
+		break;
+	default:
+		pr_err("cut version!!\n");
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	switch (adapter->intf) {
+	case HALMAC_INTERFACE_PCIE:
+	case HALMAC_INTERFACE_AXI:
+		intf = HALMAC_PWR_INTF_PCI_MSK;
+		break;
+	case HALMAC_INTERFACE_USB:
+		intf = HALMAC_PWR_INTF_USB_MSK;
+		break;
+	case HALMAC_INTERFACE_SDIO:
+		intf = HALMAC_PWR_INTF_SDIO_MSK;
+		break;
+	default:
+		pr_err("interface!!\n");
+		return HALMAC_RET_SWITCH_CASE_ERROR;
+	}
+
+	do {
+		cmd = cmd_seq[idx];
+
+		if (!cmd)
+			break;
+
+		status = pwr_sub_seq_parser_88xx(adapter, cut, intf, cmd);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("pwr sub seq!!\n");
+			return status;
+		}
+
+		idx++;
+	} while (1);
+
+	return status;
+}
+
+static enum halmac_ret_status
+pwr_sub_seq_parser_88xx(struct halmac_adapter *adapter, u8 cut, u8 intf,
+			struct halmac_wlan_pwr_cfg *cmd)
+{
+	u8 value;
+	u32 offset;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	do {
+		if ((cmd->interface_msk & intf) && (cmd->cut_msk & cut)) {
+			switch (cmd->cmd) {
+			case HALMAC_PWR_CMD_WRITE:
+				offset = cmd->offset;
+
+				if (cmd->base == HALMAC_PWR_ADDR_SDIO)
+					offset |= SDIO_LOCAL_OFFSET;
+
+				value = HALMAC_REG_R8(offset);
+				value = (u8)(value & (u8)(~(cmd->msk)));
+				value = (u8)(value | (cmd->value & cmd->msk));
+
+				HALMAC_REG_W8(offset, value);
+				break;
+			case HALMAC_PWR_CMD_POLLING:
+				if (pwr_cmd_polling_88xx(adapter, cmd) !=
+				    HALMAC_RET_SUCCESS)
+					return HALMAC_RET_PWRSEQ_POLLING_FAIL;
+				break;
+			case HALMAC_PWR_CMD_DELAY:
+				if (cmd->value == HALMAC_PWR_DELAY_US)
+					udelay(cmd->offset);
+				else
+					udelay(1000 * cmd->offset);
+				break;
+			case HALMAC_PWR_CMD_READ:
+				break;
+			case HALMAC_PWR_CMD_END:
+				return HALMAC_RET_SUCCESS;
+			default:
+				return HALMAC_RET_PWRSEQ_CMD_INCORRECT;
+			}
+		}
+		cmd++;
+	} while (1);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+pwr_cmd_polling_88xx(struct halmac_adapter *adapter,
+		     struct halmac_wlan_pwr_cfg *cmd)
+{
+	u8 value;
+	u8 flg;
+	u8 poll_bit;
+	u32 offset;
+	u32 cnt;
+	static u32 stats;
+	enum halmac_interface intf;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	poll_bit = 0;
+	cnt = HALMAC_PWR_POLLING_CNT;
+	flg = 0;
+	intf = adapter->intf;
+
+	if (cmd->base == HALMAC_PWR_ADDR_SDIO)
+		offset = cmd->offset | SDIO_LOCAL_OFFSET;
+	else
+		offset = cmd->offset;
+
+	do {
+		cnt--;
+		value = HALMAC_REG_R8(offset);
+		value = (u8)(value & cmd->msk);
+
+		if (value == (cmd->value & cmd->msk)) {
+			poll_bit = 1;
+		} else {
+			if (cnt == 0) {
+				if (intf == HALMAC_INTERFACE_PCIE && flg == 0) {
+					/* PCIE + USB package */
+					/* power bit polling timeout issue */
+					stats++;
+					RT_TRACE(adapter->drv_adapter,
+						 COMP_HALMAC, DBG_WARNING,
+						 "PCIE stats:%d\n", stats);
+					value = HALMAC_REG_R8(REG_SYS_PW_CTRL);
+					value |= BIT(3);
+					HALMAC_REG_W8(REG_SYS_PW_CTRL, value);
+					value &= ~BIT(3);
+					HALMAC_REG_W8(REG_SYS_PW_CTRL, value);
+					poll_bit = 0;
+					cnt = HALMAC_PWR_POLLING_CNT;
+					flg = 1;
+				} else {
+					pr_err("polling to!!\n");
+					pr_err("cmd offset:%X\n", cmd->offset);
+					pr_err("cmd value:%X\n", cmd->value);
+					pr_err("cmd msk:%X\n", cmd->msk);
+					pr_err("offset = %X\n", offset);
+					pr_err("value = %X\n", value);
+					return HALMAC_RET_PWRSEQ_POLLING_FAIL;
+				}
+			} else {
+				usleep_range(50, 60);
+			}
+		}
+	} while (!poll_bit);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+parse_intf_phy_88xx(struct halmac_adapter *adapter,
+		    struct halmac_intf_phy_para *param,
+		    enum halmac_intf_phy_platform pltfm,
+		    enum hal_intf_phy intf_phy)
+{
+	u16 value;
+	u16 cur_cut;
+	u16 offset;
+	u16 ip_sel;
+	struct halmac_intf_phy_para *cur_param;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u8 result = HALMAC_RET_SUCCESS;
+
+	switch (adapter->chip_ver) {
+	case HALMAC_CHIP_VER_A_CUT:
+		cur_cut = (u16)HALMAC_INTF_PHY_CUT_A;
+		break;
+	case HALMAC_CHIP_VER_B_CUT:
+		cur_cut = (u16)HALMAC_INTF_PHY_CUT_B;
+		break;
+	case HALMAC_CHIP_VER_C_CUT:
+		cur_cut = (u16)HALMAC_INTF_PHY_CUT_C;
+		break;
+	case HALMAC_CHIP_VER_D_CUT:
+		cur_cut = (u16)HALMAC_INTF_PHY_CUT_D;
+		break;
+	case HALMAC_CHIP_VER_E_CUT:
+		cur_cut = (u16)HALMAC_INTF_PHY_CUT_E;
+		break;
+	case HALMAC_CHIP_VER_F_CUT:
+		cur_cut = (u16)HALMAC_INTF_PHY_CUT_F;
+		break;
+	case HALMAC_CHIP_VER_TEST:
+		cur_cut = (u16)HALMAC_INTF_PHY_CUT_TESTCHIP;
+		break;
+	default:
+		return HALMAC_RET_FAIL;
+	}
+
+	cur_param = param;
+
+	do {
+		if ((cur_param->cut & cur_cut) &&
+		    (cur_param->plaform & (u16)pltfm)) {
+			offset =  cur_param->offset;
+			value = cur_param->value;
+			ip_sel = cur_param->ip_sel;
+
+			if (offset == 0xFFFF)
+				break;
+
+			if (ip_sel == HALMAC_IP_SEL_MAC) {
+				HALMAC_REG_W8((u32)offset, (u8)value);
+			} else if (intf_phy == HAL_INTF_PHY_USB2 ||
+				   intf_phy == HAL_INTF_PHY_USB3) {
+				result = usbphy_write_88xx(adapter, (u8)offset,
+							   value, intf_phy);
+				if (result != HALMAC_RET_SUCCESS)
+					pr_err("usb phy!!\n");
+
+			} else if (intf_phy == HAL_INTF_PHY_PCIE_GEN1 ||
+				   intf_phy == HAL_INTF_PHY_PCIE_GEN2) {
+				if (ip_sel == HALMAC_IP_INTF_PHY)
+					result = mdio_write_88xx(adapter,
+								 (u8)offset,
+								 value,
+								 intf_phy);
+				else
+					result = dbi_w8_88xx(adapter, offset,
+							     (u8)value);
+				if (result != HALMAC_RET_SUCCESS)
+					pr_err("mdio/dbi!!\n");
+
+			} else {
+				pr_err("intf phy sel!!\n");
+			}
+		}
+		cur_param++;
+	} while (1);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * txfifo_is_empty_88xx() -check if txfifo is empty
+ * @adapter : the adapter of halmac
+ * @chk_num : check number
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+txfifo_is_empty_88xx(struct halmac_adapter *adapter, u32 chk_num)
+{
+	u32 cnt;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	cnt = (chk_num <= 10) ? 10 : chk_num;
+	do {
+		if (HALMAC_REG_R8(REG_TXPKT_EMPTY) != 0xFF)
+			return HALMAC_RET_TXFIFO_NO_EMPTY;
+
+		if ((HALMAC_REG_R8(REG_TXPKT_EMPTY + 1) & 0x06) != 0x06)
+			return HALMAC_RET_TXFIFO_NO_EMPTY;
+		cnt--;
+
+	} while (cnt != 0);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * (internal use)
+ * smart_malloc_88xx() - adapt malloc size
+ * @adapter : the adapter of halmac
+ * @size : expected malloc size
+ * @pNew_size : real malloc size
+ * Author : Ivan Lin
+ * Return : address pointer
+ */
+u8*
+smart_malloc_88xx(struct halmac_adapter *adapter, u32 size, u32 *new_size)
+{
+	u8 retry_num;
+	u8 *malloc_buf = NULL;
+
+	for (retry_num = 0; retry_num < 5; retry_num++) {
+		malloc_buf = kzalloc(size, GFP_KERNEL);
+
+		if (malloc_buf) {
+			*new_size = size;
+			return malloc_buf;
+		}
+
+		size = size >> 1;
+
+		if (size == 0)
+			break;
+	}
+
+	pr_err("adptive malloc!!\n");
+
+	return NULL;
+}
+
+/**
+ * (internal use)
+ * ltecoex_reg_read_88xx() - read ltecoex register
+ * @adapter : the adapter of halmac
+ * @offset : offset
+ * @pValue : value
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+ltecoex_reg_read_88xx(struct halmac_adapter *adapter, u16 offset, u32 *value)
+{
+	u32 cnt;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	cnt = 10000;
+	while ((HALMAC_REG_R8(LTECOEX_ACCESS_CTRL + 3) & BIT(5)) == 0) {
+		if (cnt == 0) {
+			pr_err("lte ready(R)\n");
+			return HALMAC_RET_LTECOEX_READY_FAIL;
+		}
+		cnt--;
+		usleep_range(50, 60);
+	}
+
+	HALMAC_REG_W32(LTECOEX_ACCESS_CTRL, 0x800F0000 | offset);
+	*value = HALMAC_REG_R32(REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * (internal use)
+ * ltecoex_reg_write_88xx() - write ltecoex register
+ * @adapter : the adapter of halmac
+ * @offset : offset
+ * @value : value
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ */
+enum halmac_ret_status
+ltecoex_reg_write_88xx(struct halmac_adapter *adapter, u16 offset, u32 value)
+{
+	u32 cnt;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	cnt = 10000;
+	while ((HALMAC_REG_R8(LTECOEX_ACCESS_CTRL + 3) & BIT(5)) == 0) {
+		if (cnt == 0) {
+			pr_err("lte ready(W)\n");
+			return HALMAC_RET_LTECOEX_READY_FAIL;
+		}
+		cnt--;
+		usleep_range(50, 60);
+	}
+
+	HALMAC_REG_W32(REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1, value);
+	HALMAC_REG_W32(LTECOEX_ACCESS_CTRL, 0xC00F0000 | offset);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+pwr_state_88xx(struct halmac_adapter *adapter, enum halmac_mac_power *state)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if ((HALMAC_REG_R8(REG_SYS_FUNC_EN + 1) & BIT(3)) == 0)
+		*state = HALMAC_MAC_POWER_OFF;
+	else
+		*state = HALMAC_MAC_POWER_ON;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.h
new file mode 100644
index 000000000000..c912e0e4a8f0
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_common_88xx.h
@@ -0,0 +1,151 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_COMMON_88XX_H_
+#define _HALMAC_COMMON_88XX_H_
+
+#include "../halmac_api.h"
+#include "../halmac_pwr_seq_cmd.h"
+#include "../halmac_gpio_cmd.h"
+
+enum halmac_ret_status
+ofld_func_cfg_88xx(struct halmac_adapter *adapter,
+		   struct halmac_ofld_func_info *info);
+
+enum halmac_ret_status
+dl_drv_rsvd_page_88xx(struct halmac_adapter *adapter, u8 pg_offset, u8 *buf,
+		      u32 size);
+
+enum halmac_ret_status
+dl_rsvd_page_88xx(struct halmac_adapter *adapter, u16 pg_addr, u8 *buf,
+		  u32 size);
+
+enum halmac_ret_status
+get_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
+		  void *value);
+
+enum halmac_ret_status
+set_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
+		  void *value);
+
+enum halmac_ret_status
+set_h2c_pkt_hdr_88xx(struct halmac_adapter *adapter, u8 *hdr,
+		     struct halmac_h2c_header_info *info, u16 *seq_num);
+
+enum halmac_ret_status
+send_h2c_pkt_88xx(struct halmac_adapter *adapter, u8 *pkt);
+
+enum halmac_ret_status
+get_h2c_buf_free_space_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+get_c2h_info_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+enum halmac_ret_status
+mac_debug_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+cfg_parameter_88xx(struct halmac_adapter *adapter,
+		   struct halmac_phy_parameter_info *info, u8 full_fifo);
+
+enum halmac_ret_status
+update_packet_88xx(struct halmac_adapter *adapter, enum halmac_packet_id pkt_id,
+		   u8 *pkt, u32 size);
+
+enum halmac_ret_status
+bcn_ie_filter_88xx(struct halmac_adapter *adapter,
+		   struct halmac_bcn_ie_info *info);
+
+enum halmac_ret_status
+update_datapack_88xx(struct halmac_adapter *adapter,
+		     enum halmac_data_type data_type,
+		     struct halmac_phy_parameter_info *info);
+
+enum halmac_ret_status
+run_datapack_88xx(struct halmac_adapter *adapter,
+		  enum halmac_data_type data_type);
+
+enum halmac_ret_status
+send_bt_coex_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size, u8 ack);
+
+enum halmac_ret_status
+dump_fifo_88xx(struct halmac_adapter *adapter, enum hal_fifo_sel sel,
+	       u32 start_addr, u32 size, u8 *data);
+
+u32
+get_fifo_size_88xx(struct halmac_adapter *adapter, enum hal_fifo_sel sel);
+
+enum halmac_ret_status
+set_h2c_header_88xx(struct halmac_adapter *adapter, u8 *hdr, u16 *seq, u8 ack);
+
+enum halmac_ret_status
+add_ch_info_88xx(struct halmac_adapter *adapter, struct halmac_ch_info *info);
+
+enum halmac_ret_status
+add_extra_ch_info_88xx(struct halmac_adapter *adapter,
+		       struct halmac_ch_extra_info *info);
+
+enum halmac_ret_status
+ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
+		    struct halmac_ch_switch_option *opt);
+
+enum halmac_ret_status
+clear_ch_info_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+chk_txdesc_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+enum halmac_ret_status
+get_version_88xx(struct halmac_adapter *adapter, struct halmac_ver *ver);
+
+enum halmac_ret_status
+p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info);
+
+enum halmac_ret_status
+query_status_88xx(struct halmac_adapter *adapter,
+		  enum halmac_feature_id feature_id,
+		  enum halmac_cmd_process_status *proc_status, u8 *data,
+		  u32 *size);
+
+enum halmac_ret_status
+cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *adapter,
+			 enum halmac_drv_rsvd_pg_num pg_num);
+
+enum halmac_ret_status
+h2c_lb_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+pwr_seq_parser_88xx(struct halmac_adapter *adapter,
+		    struct halmac_wlan_pwr_cfg **cmd_seq);
+
+enum halmac_ret_status
+parse_intf_phy_88xx(struct halmac_adapter *adapter,
+		    struct halmac_intf_phy_para *param,
+		    enum halmac_intf_phy_platform pltfm,
+		    enum hal_intf_phy intf_phy);
+
+enum halmac_ret_status
+txfifo_is_empty_88xx(struct halmac_adapter *adapter, u32 chk_num);
+
+u8*
+smart_malloc_88xx(struct halmac_adapter *adapter, u32 size, u32 *new_size);
+
+enum halmac_ret_status
+ltecoex_reg_read_88xx(struct halmac_adapter *adapter, u16 offset, u32 *value);
+
+enum halmac_ret_status
+ltecoex_reg_write_88xx(struct halmac_adapter *adapter, u16 offset, u32 value);
+
+#endif/* _HALMAC_COMMON_88XX_H_ */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 16/17] rtlwifi: halmac: add to support BB and RF functions
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (13 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 15/17] rtlwifi: halmac: add to control WiFi mac functions and registers pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-03  7:53 ` [PATCH v2 17/17] rtlwifi: add halmac to Makefile and Kconfig pkshih
  2018-04-24 17:12 ` [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac Kalle Valo
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

Some BB and RF functions collaborate with firmware or MAC. For instances,
the IQK and PSD functions are implemented in firmware, so use a H2C command
to trigger. For MIMO function, use the helper functions to control related
MAC registers.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 .../rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.c | 397 ++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.h |  53 ++
 .../rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.c  | 869 +++++++++++++++++++++
 .../rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.h  |  79 ++
 4 files changed, 1398 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.h
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.c
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.h

diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.c
new file mode 100644
index 000000000000..06990ee78ebd
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.c
@@ -0,0 +1,397 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_bb_rf_88xx.h"
+#include "halmac_88xx_cfg.h"
+#include "halmac_common_88xx.h"
+#include "halmac_init_88xx.h"
+
+/**
+ * start_iqk_88xx() -trigger FW IQK
+ * @adapter : the adapter of halmac
+ * @param : IQK parameter
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+start_iqk_88xx(struct halmac_adapter *adapter, struct halmac_iqk_para *param)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.iqk_state.proc_status;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Wait event(iqk)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	*proc_status = HALMAC_CMD_PROCESS_SENDING;
+
+	IQK_SET_CLEAR(h2c_buf, param->clear);
+	IQK_SET_SEGMENT_IQK(h2c_buf, param->segment_iqk);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_IQK;
+	hdr_info.content_size = 1;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	adapter->halmac_state.iqk_state.seq_num = seq_num;
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c pkt fail!!\n");
+		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_IQK);
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * ctrl_pwr_tracking_88xx() -trigger FW power tracking
+ * @adapter : the adapter of halmac
+ * @opt : power tracking option
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+ctrl_pwr_tracking_88xx(struct halmac_adapter *adapter,
+		       struct halmac_pwr_tracking_option *opt)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_h2c_header_info hdr_info;
+	struct halmac_pwr_tracking_para *param;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.pwr_trk_state.proc_status;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Wait event(pwr tracking)...\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	*proc_status = HALMAC_CMD_PROCESS_SENDING;
+
+	PWR_TRK_SET_TYPE(h2c_buf, opt->type);
+	PWR_TRK_SET_BBSWING_INDEX(h2c_buf, opt->bbswing_index);
+
+	param = &opt->pwr_tracking_para[HALMAC_RF_PATH_A];
+	PWR_TRK_SET_ENABLE_A(h2c_buf, param->enable);
+	PWR_TRK_SET_TX_PWR_INDEX_A(h2c_buf, param->tx_pwr_index);
+	PWR_TRK_SET_TSSI_VALUE_A(h2c_buf, param->tssi_value);
+	PWR_TRK_SET_OFFSET_VALUE_A(h2c_buf, param->pwr_tracking_offset_value);
+
+	param = &opt->pwr_tracking_para[HALMAC_RF_PATH_B];
+	PWR_TRK_SET_ENABLE_B(h2c_buf, param->enable);
+	PWR_TRK_SET_TX_PWR_INDEX_B(h2c_buf, param->tx_pwr_index);
+	PWR_TRK_SET_TSSI_VALUE_B(h2c_buf, param->tssi_value);
+	PWR_TRK_SET_OFFSET_VALUE_B(h2c_buf, param->pwr_tracking_offset_value);
+
+	param = &opt->pwr_tracking_para[HALMAC_RF_PATH_C];
+	PWR_TRK_SET_ENABLE_C(h2c_buf, param->enable);
+	PWR_TRK_SET_TX_PWR_INDEX_C(h2c_buf, param->tx_pwr_index);
+	PWR_TRK_SET_TSSI_VALUE_C(h2c_buf, param->tssi_value);
+	PWR_TRK_SET_OFFSET_VALUE_C(h2c_buf, param->pwr_tracking_offset_value);
+
+	param = &opt->pwr_tracking_para[HALMAC_RF_PATH_D];
+	PWR_TRK_SET_ENABLE_D(h2c_buf, param->enable);
+	PWR_TRK_SET_TX_PWR_INDEX_D(h2c_buf, param->tx_pwr_index);
+	PWR_TRK_SET_TSSI_VALUE_D(h2c_buf, param->tssi_value);
+	PWR_TRK_SET_OFFSET_VALUE_D(h2c_buf, param->pwr_tracking_offset_value);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_PWR_TRK;
+	hdr_info.content_size = 20;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	adapter->halmac_state.pwr_trk_state.seq_num = seq_num;
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c pkt fail!!\n");
+		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_POWER_TRACKING);
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_iqk_status_88xx(struct halmac_adapter *adapter,
+		    enum halmac_cmd_process_status *proc_status)
+{
+	*proc_status = adapter->halmac_state.iqk_state.proc_status;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_pwr_trk_status_88xx(struct halmac_adapter *adapter,
+			enum halmac_cmd_process_status *proc_status)
+{
+	*proc_status = adapter->halmac_state.pwr_trk_state.proc_status;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_psd_status_88xx(struct halmac_adapter *adapter,
+		    enum halmac_cmd_process_status *proc_status, u8 *data,
+		    u32 *size)
+{
+	struct halmac_psd_state *state = &adapter->halmac_state.psd_state;
+
+	*proc_status = state->proc_status;
+
+	if (!data)
+		return HALMAC_RET_NULL_POINTER;
+
+	if (!size)
+		return HALMAC_RET_NULL_POINTER;
+
+	if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
+		if (*size < state->data_size) {
+			*size = state->data_size;
+			return HALMAC_RET_BUFFER_TOO_SMALL;
+		}
+
+		*size = state->data_size;
+		memcpy(data, state->data, *size);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * psd_88xx() - trigger fw psd
+ * @adapter : the adapter of halmac
+ * @start_psd : start PSD
+ * @end_psd : end PSD
+ * Author : KaiYuan Chang/Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+psd_88xx(struct halmac_adapter *adapter, u16 start_psd, u16 end_psd)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num = 0;
+	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_cmd_process_status *proc_status;
+
+	proc_status = &adapter->halmac_state.psd_state.proc_status;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Wait event(psd)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	kfree(adapter->halmac_state.psd_state.data);
+	adapter->halmac_state.psd_state.data = (u8 *)NULL;
+
+	adapter->halmac_state.psd_state.data_size = 0;
+	adapter->halmac_state.psd_state.seg_size = 0;
+
+	*proc_status = HALMAC_CMD_PROCESS_SENDING;
+
+	PSD_SET_START_PSD(h2c_buf, start_psd);
+	PSD_SET_END_PSD(h2c_buf, end_psd);
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_PSD;
+	hdr_info.content_size = 4;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c pkt fail!!\n");
+		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_PSD);
+		return status;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_h2c_ack_iqk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seq_num;
+	u8 fw_rc;
+	struct halmac_iqk_state *state = &adapter->halmac_state.iqk_state;
+	enum halmac_cmd_process_status proc_status;
+
+	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Seq num : h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("Seq num mismatch : h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not cmd sending\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
+	state->fw_rc = fw_rc;
+
+	if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
+		proc_status = HALMAC_CMD_PROCESS_DONE;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_IQK, proc_status, NULL, 0);
+	} else {
+		proc_status = HALMAC_CMD_PROCESS_ERROR;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_IQK, proc_status, &fw_rc, 1);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_h2c_ack_pwr_trk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seq_num;
+	u8 fw_rc;
+	struct halmac_pwr_tracking_state *state;
+	enum halmac_cmd_process_status proc_status;
+
+	state = &adapter->halmac_state.pwr_trk_state;
+
+	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Seq num : h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("Seq num mismatch : h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not cmd sending\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
+	state->fw_rc = fw_rc;
+
+	if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
+		proc_status = HALMAC_CMD_PROCESS_DONE;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_POWER_TRACKING, proc_status,
+				NULL, 0);
+	} else {
+		proc_status = HALMAC_CMD_PROCESS_ERROR;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_POWER_TRACKING, proc_status,
+				&fw_rc, 1);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_psd_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seg_id;
+	u8 seg_size;
+	u8 seq_num;
+	u16 total_size;
+	enum halmac_cmd_process_status proc_status;
+	struct halmac_psd_state *state = &adapter->halmac_state.psd_state;
+
+	seq_num = (u8)PSD_DATA_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "seq num : h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("seq num mismatch : h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not cmd sending\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	total_size = (u16)PSD_DATA_GET_TOTAL_SIZE(buf);
+	seg_id = (u8)PSD_DATA_GET_SEGMENT_ID(buf);
+	seg_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(buf);
+	state->data_size = total_size;
+
+	if (!state->data)
+		state->data = kzalloc(state->data_size, GFP_KERNEL);
+
+	if (seg_id == 0)
+		state->seg_size = seg_size;
+
+	memcpy(state->data + seg_id * state->seg_size,
+	       buf + C2H_DATA_OFFSET_88XX, seg_size);
+
+	if (PSD_DATA_GET_END_SEGMENT(buf) == 0)
+		return HALMAC_RET_SUCCESS;
+
+	proc_status = HALMAC_CMD_PROCESS_DONE;
+	state->proc_status = proc_status;
+
+	PLTFM_EVENT_SIG(HALMAC_FEATURE_PSD, proc_status, state->data,
+			state->data_size);
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.h
new file mode 100644
index 000000000000..4c9dbada56d7
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_bb_rf_88xx.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_BB_RF_88XX_H_
+#define _HALMAC_BB_RF_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+start_iqk_88xx(struct halmac_adapter *adapter, struct halmac_iqk_para *param);
+
+enum halmac_ret_status
+ctrl_pwr_tracking_88xx(struct halmac_adapter *adapter,
+		       struct halmac_pwr_tracking_option *opt);
+
+enum halmac_ret_status
+get_iqk_status_88xx(struct halmac_adapter *adapter,
+		    enum halmac_cmd_process_status *proc_status);
+
+enum halmac_ret_status
+get_pwr_trk_status_88xx(struct halmac_adapter *adapter,
+			enum halmac_cmd_process_status *proc_status);
+
+enum halmac_ret_status
+get_psd_status_88xx(struct halmac_adapter *adapter,
+		    enum halmac_cmd_process_status *proc_status, u8 *data,
+		    u32 *size);
+
+enum halmac_ret_status
+psd_88xx(struct halmac_adapter *adapter, u16 start_psd, u16 end_psd);
+
+enum halmac_ret_status
+get_h2c_ack_iqk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+enum halmac_ret_status
+get_h2c_ack_pwr_trk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+enum halmac_ret_status
+get_psd_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+#endif/* _HALMAC_BB_RF_88XX_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.c b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.c
new file mode 100644
index 000000000000..4482be6b45f1
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.c
@@ -0,0 +1,869 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#include "halmac_mimo_88xx.h"
+#include "halmac_88xx_cfg.h"
+#include "halmac_common_88xx.h"
+#include "halmac_init_88xx.h"
+
+#define TXBF_CTRL_CFG	(BIT_R_ENABLE_NDPA | BIT_USE_NDPA_PARAMETER | \
+			 BIT_R_EN_NDPA_INT | BIT_DIS_NDP_BFEN)
+
+static void
+cfg_mu_bfee_88xx(struct halmac_adapter *adapter,
+		 struct halmac_cfg_mumimo_para *param);
+
+static void
+cfg_mu_bfer_88xx(struct halmac_adapter *adapter,
+		 struct halmac_cfg_mumimo_para *param);
+
+static enum halmac_cmd_construct_state
+fw_snding_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
+
+static enum halmac_ret_status
+cnv_fw_snding_state_88xx(struct halmac_adapter *adapter,
+			 enum halmac_cmd_construct_state dest_state);
+
+static u8
+snding_pkt_chk_88xx(struct halmac_adapter *adapter, u8 *pkt);
+
+/**
+ * cfg_txbf_88xx() - enable/disable specific user's txbf
+ * @adapter : the adapter of halmac
+ * @userid : su bfee userid = 0 or 1 to apply TXBF
+ * @bw : the sounding bandwidth
+ * @txbf_en : 0: disable TXBF, 1: enable TXBF
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_txbf_88xx(struct halmac_adapter *adapter, u8 userid, enum halmac_bw bw,
+	      u8 txbf_en)
+{
+	u16 tmp42c = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (txbf_en) {
+		switch (bw) {
+		case HALMAC_BW_80:
+			tmp42c |= BIT_R_TXBF0_80M;
+		case HALMAC_BW_40:
+			tmp42c |= BIT_R_TXBF0_40M;
+		case HALMAC_BW_20:
+			tmp42c |= BIT_R_TXBF0_20M;
+			break;
+		default:
+			return HALMAC_RET_INVALID_SOUNDING_SETTING;
+		}
+	}
+
+	switch (userid) {
+	case 0:
+		tmp42c |= HALMAC_REG_R16(REG_TXBF_CTRL) &
+			~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+		HALMAC_REG_W16(REG_TXBF_CTRL, tmp42c);
+		break;
+	case 1:
+		tmp42c |= HALMAC_REG_R16(REG_TXBF_CTRL + 2) &
+			~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+		HALMAC_REG_W16(REG_TXBF_CTRL + 2, tmp42c);
+		break;
+	default:
+		return HALMAC_RET_INVALID_SOUNDING_SETTING;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_mumimo_88xx() -config mumimo
+ * @adapter : the adapter of halmac
+ * @param : parameters to configure MU PPDU Tx/Rx
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_mumimo_88xx(struct halmac_adapter *adapter,
+		struct halmac_cfg_mumimo_para *param)
+{
+	if (param->role == HAL_BFEE)
+		cfg_mu_bfee_88xx(adapter, param);
+	else
+		cfg_mu_bfer_88xx(adapter, param);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static void
+cfg_mu_bfee_88xx(struct halmac_adapter *adapter,
+		 struct halmac_cfg_mumimo_para *param)
+{
+	u8 mu_tbl_sel;
+	u8 tmp14c0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	tmp14c0 = HALMAC_REG_R8(REG_MU_TX_CTL) & ~BIT_MASK_R_MU_TABLE_VALID;
+	HALMAC_REG_W8(REG_MU_TX_CTL, (tmp14c0 | BIT(0) | BIT(1)) & ~(BIT(7)));
+
+	/*config GID valid table and user position table*/
+	mu_tbl_sel = HALMAC_REG_R8(REG_MU_TX_CTL + 1) & 0xF8;
+
+	HALMAC_REG_W8(REG_MU_TX_CTL + 1, mu_tbl_sel);
+	HALMAC_REG_W32(REG_MU_STA_GID_VLD, param->given_gid_tab[0]);
+	HALMAC_REG_W32(REG_MU_STA_USER_POS_INFO, param->given_user_pos[0]);
+	HALMAC_REG_W32(REG_MU_STA_USER_POS_INFO + 4, param->given_user_pos[1]);
+
+	HALMAC_REG_W8(REG_MU_TX_CTL + 1, mu_tbl_sel | 1);
+	HALMAC_REG_W32(REG_MU_STA_GID_VLD, param->given_gid_tab[1]);
+	HALMAC_REG_W32(REG_MU_STA_USER_POS_INFO, param->given_user_pos[2]);
+	HALMAC_REG_W32(REG_MU_STA_USER_POS_INFO + 4, param->given_user_pos[3]);
+}
+
+static void
+cfg_mu_bfer_88xx(struct halmac_adapter *adapter,
+		 struct halmac_cfg_mumimo_para *param)
+{
+	u8 i;
+	u8 idx;
+	u8 id0;
+	u8 id1;
+	u8 gid;
+	u8 mu_tbl_sel;
+	u8 mu_tbl_valid = 0;
+	u32 gid_valid[6] = {0};
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	if (param->mu_tx_en == 0) {
+		HALMAC_REG_W8(REG_MU_TX_CTL,
+			      HALMAC_REG_R8(REG_MU_TX_CTL) & ~(BIT(7)));
+		return;
+	}
+
+	for (idx = 0; idx < 15; idx++) {
+		if (idx < 5) {
+			/*grouping_bitmap bit0~4, MU_STA0 with MUSTA1~5*/
+			id0 = 0;
+			id1 = (u8)(idx + 1);
+		} else if (idx < 9) {
+			/*grouping_bitmap bit5~8, MU_STA1 with MUSTA2~5*/
+			id0 = 1;
+			id1 = (u8)(idx - 3);
+		} else if (idx < 12) {
+			/*grouping_bitmap bit9~11, MU_STA2 with MUSTA3~5*/
+			id0 = 2;
+			id1 = (u8)(idx - 6);
+		} else if (idx < 14) {
+			/*grouping_bitmap bit12~13, MU_STA3 with MUSTA4~5*/
+			id0 = 3;
+			id1 = (u8)(idx - 8);
+		} else {
+			/*grouping_bitmap bit14, MU_STA4 with MUSTA5*/
+			id0 = 4;
+			id1 = (u8)(idx - 9);
+		}
+		if (param->grouping_bitmap & BIT(idx)) {
+			/*Pair 1*/
+			gid = (idx << 1) + 1;
+			gid_valid[id0] |= (BIT(gid));
+			gid_valid[id1] |= (BIT(gid));
+			/*Pair 2*/
+			gid += 1;
+			gid_valid[id0] |= (BIT(gid));
+			gid_valid[id1] |= (BIT(gid));
+		} else {
+			/*Pair 1*/
+			gid = (idx << 1) + 1;
+			gid_valid[id0] &= ~(BIT(gid));
+			gid_valid[id1] &= ~(BIT(gid));
+			/*Pair 2*/
+			gid += 1;
+			gid_valid[id0] &= ~(BIT(gid));
+			gid_valid[id1] &= ~(BIT(gid));
+		}
+	}
+
+	/*set MU STA GID valid TABLE*/
+	mu_tbl_sel = HALMAC_REG_R8(REG_MU_TX_CTL + 1) & 0xF8;
+	for (idx = 0; idx < 6; idx++) {
+		HALMAC_REG_W8(REG_MU_TX_CTL + 1, idx | mu_tbl_sel);
+		HALMAC_REG_W32(REG_MU_STA_GID_VLD, gid_valid[idx]);
+	}
+
+	/*To validate the sounding successful MU STA and enable MU TX*/
+	for (i = 0; i < 6; i++) {
+		if (param->sounding_sts[i] == 1)
+			mu_tbl_valid |= BIT(i);
+	}
+	HALMAC_REG_W8(REG_MU_TX_CTL, mu_tbl_valid | BIT(7));
+}
+
+/**
+ * cfg_sounding_88xx() - configure general sounding
+ * @adapter : the adapter of halmac
+ * @role : driver's role, BFer or BFee
+ * @rate : set ndpa tx rate if driver is BFer,
+ * or set csi response rate if driver is BFee
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_sounding_88xx(struct halmac_adapter *adapter, enum halmac_snd_role role,
+		  enum halmac_data_rate rate)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+	u32 tmp6dc = 0;
+	u8 csi_rsc = 0x1;
+
+	/*use ndpa rx rate to decide csi rate*/
+	tmp6dc = HALMAC_REG_R32(REG_BBPSF_CTRL) | BIT_WMAC_USE_NDPARATE
+							| (csi_rsc << 13);
+
+	switch (role) {
+	case HAL_BFER:
+		HALMAC_REG_W32_SET(REG_TXBF_CTRL, TXBF_CTRL_CFG);
+		HALMAC_REG_W8(REG_NDPA_RATE, rate);
+		HALMAC_REG_W8_CLR(REG_NDPA_OPT_CTRL, BIT(0) | BIT(1));
+		HALMAC_REG_W8(REG_SND_PTCL_CTRL + 1, 0x2 | BIT(7));
+		HALMAC_REG_W8(REG_SND_PTCL_CTRL + 2, 0x2);
+		break;
+	case HAL_BFEE:
+		HALMAC_REG_W8(REG_SND_PTCL_CTRL, 0xDB);
+		HALMAC_REG_W8(REG_SND_PTCL_CTRL + 3, 0x26);
+		HALMAC_REG_W8_CLR(REG_RXFLTMAP1, BIT(4));
+		HALMAC_REG_W8_CLR(REG_RXFLTMAP4, BIT(4));
+		break;
+	default:
+		return HALMAC_RET_INVALID_SOUNDING_SETTING;
+	}
+
+	/*AP mode set tx gid to 63*/
+	/*STA mode set tx gid to 0*/
+	if (BIT_GET_NETYPE0(HALMAC_REG_R32(REG_CR)) == 0x3)
+		HALMAC_REG_W32(REG_BBPSF_CTRL, tmp6dc | BIT(12));
+	else
+		HALMAC_REG_W32(REG_BBPSF_CTRL, tmp6dc & ~(BIT(12)));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * del_sounding_88xx() - reset general sounding
+ * @adapter : the adapter of halmac
+ * @role : driver's role, BFer or BFee
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+del_sounding_88xx(struct halmac_adapter *adapter, enum halmac_snd_role role)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	switch (role) {
+	case HAL_BFER:
+		HALMAC_REG_W8(REG_TXBF_CTRL + 3, 0);
+		break;
+	case HAL_BFEE:
+		HALMAC_REG_W8(REG_SND_PTCL_CTRL, 0);
+		break;
+	default:
+		return HALMAC_RET_INVALID_SOUNDING_SETTING;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * su_bfee_entry_init_88xx() - config SU beamformee's registers
+ * @adapter : the adapter of halmac
+ * @userid : SU bfee userid = 0 or 1 to be added
+ * @paid : partial AID of this bfee
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+su_bfee_entry_init_88xx(struct halmac_adapter *adapter, u8 userid, u16 paid)
+{
+	u16 tmp42c = 0;
+	u16 tmp168x = 0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	switch (userid) {
+	case 0:
+		tmp42c = HALMAC_REG_R16(REG_TXBF_CTRL) &
+				~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
+				BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+		HALMAC_REG_W16(REG_TXBF_CTRL, tmp42c | paid);
+		HALMAC_REG_W16(REG_ASSOCIATED_BFMEE_SEL, paid);
+		break;
+	case 1:
+		tmp42c = HALMAC_REG_R16(REG_TXBF_CTRL + 2) &
+				~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
+				BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+		HALMAC_REG_W16(REG_TXBF_CTRL + 2, tmp42c | paid);
+		HALMAC_REG_W16(REG_ASSOCIATED_BFMEE_SEL + 2, paid | BIT(9));
+		break;
+	case 2:
+		tmp168x = HALMAC_REG_R16(REG_WMAC_ASSOCIATED_MU_BFMEE2);
+		tmp168x = BIT_CLEAR_WMAC_MU_BFEE2_AID(tmp168x);
+		tmp168x |= (paid | BIT(9));
+		HALMAC_REG_W16(REG_WMAC_ASSOCIATED_MU_BFMEE2, tmp168x);
+		break;
+	case 3:
+		tmp168x = HALMAC_REG_R16(REG_WMAC_ASSOCIATED_MU_BFMEE3);
+		tmp168x = BIT_CLEAR_WMAC_MU_BFEE3_AID(tmp168x);
+		tmp168x |= (paid | BIT(9));
+		HALMAC_REG_W16(REG_WMAC_ASSOCIATED_MU_BFMEE3, tmp168x);
+		break;
+	case 4:
+		tmp168x = HALMAC_REG_R16(REG_WMAC_ASSOCIATED_MU_BFMEE4);
+		tmp168x = BIT_CLEAR_WMAC_MU_BFEE4_AID(tmp168x);
+		tmp168x |= (paid | BIT(9));
+		HALMAC_REG_W16(REG_WMAC_ASSOCIATED_MU_BFMEE4, tmp168x);
+		break;
+	case 5:
+		tmp168x = HALMAC_REG_R16(REG_WMAC_ASSOCIATED_MU_BFMEE5);
+		tmp168x = BIT_CLEAR_WMAC_MU_BFEE5_AID(tmp168x);
+		tmp168x |= (paid | BIT(9));
+		HALMAC_REG_W16(REG_WMAC_ASSOCIATED_MU_BFMEE5, tmp168x);
+		break;
+	default:
+		return HALMAC_RET_INVALID_SOUNDING_SETTING;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * su_bfee_entry_init_88xx() - config SU beamformer's registers
+ * @adapter : the adapter of halmac
+ * @param : parameters to configure SU BFER entry
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+su_bfer_entry_init_88xx(struct halmac_adapter *adapter,
+			struct halmac_su_bfer_init_para *param)
+{
+	u16 mac_addr_h;
+	u32 mac_addr_l;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	mac_addr_l = le32_to_cpu(param->bfer_address.addr_l_h.low);
+	mac_addr_h = le16_to_cpu(param->bfer_address.addr_l_h.high);
+
+	switch (param->userid) {
+	case 0:
+		HALMAC_REG_W32(REG_ASSOCIATED_BFMER0_INFO, mac_addr_l);
+		HALMAC_REG_W16(REG_ASSOCIATED_BFMER0_INFO + 4, mac_addr_h);
+		HALMAC_REG_W16(REG_ASSOCIATED_BFMER0_INFO + 6, param->paid);
+		HALMAC_REG_W16(REG_TX_CSI_RPT_PARAM_BW20, param->csi_para);
+		break;
+	case 1:
+		HALMAC_REG_W32(REG_ASSOCIATED_BFMER1_INFO, mac_addr_l);
+		HALMAC_REG_W16(REG_ASSOCIATED_BFMER1_INFO + 4, mac_addr_h);
+		HALMAC_REG_W16(REG_ASSOCIATED_BFMER1_INFO + 6, param->paid);
+		HALMAC_REG_W16(REG_TX_CSI_RPT_PARAM_BW20 + 2, param->csi_para);
+		break;
+	default:
+		return HALMAC_RET_INVALID_SOUNDING_SETTING;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * mu_bfee_entry_init_88xx() - config MU beamformee's registers
+ * @adapter : the adapter of halmac
+ * @param : parameters to configure MU BFEE entry
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+mu_bfee_entry_init_88xx(struct halmac_adapter *adapter,
+			struct halmac_mu_bfee_init_para *param)
+{
+	u16 tmp168x = 0;
+	u16 tmp14c0;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	tmp168x |= param->paid | BIT(9);
+	HALMAC_REG_W16((0x1680 + param->userid * 2), tmp168x);
+
+	tmp14c0 = HALMAC_REG_R16(REG_MU_TX_CTL) & ~(BIT(8) | BIT(9) | BIT(10));
+	HALMAC_REG_W16(REG_MU_TX_CTL, tmp14c0 | ((param->userid - 2) << 8));
+	HALMAC_REG_W32(REG_MU_STA_GID_VLD, 0);
+	HALMAC_REG_W32(REG_MU_STA_USER_POS_INFO, param->user_position_l);
+	HALMAC_REG_W32(REG_MU_STA_USER_POS_INFO + 4, param->user_position_h);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * mu_bfer_entry_init_88xx() - config MU beamformer's registers
+ * @adapter : the adapter of halmac
+ * @param : parameters to configure MU BFER entry
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+mu_bfer_entry_init_88xx(struct halmac_adapter *adapter,
+			struct halmac_mu_bfer_init_para *param)
+{
+	u16 tmp1680 = 0;
+	u16 mac_addr_h;
+	u32 mac_addr_l;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	mac_addr_l = le32_to_cpu(param->bfer_address.addr_l_h.low);
+	mac_addr_h = le16_to_cpu(param->bfer_address.addr_l_h.high);
+
+	HALMAC_REG_W32(REG_ASSOCIATED_BFMER0_INFO, mac_addr_l);
+	HALMAC_REG_W16(REG_ASSOCIATED_BFMER0_INFO + 4, mac_addr_h);
+	HALMAC_REG_W16(REG_ASSOCIATED_BFMER0_INFO + 6, param->paid);
+	HALMAC_REG_W16(REG_TX_CSI_RPT_PARAM_BW20, param->csi_para);
+
+	tmp1680 = HALMAC_REG_R16(0x1680) & 0xC000;
+	tmp1680 |= param->my_aid | (param->csi_length_sel << 12);
+	HALMAC_REG_W16(0x1680, tmp1680);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * su_bfee_entry_del_88xx() - reset SU beamformee's registers
+ * @adapter : the adapter of halmac
+ * @userid : the SU BFee userid to be deleted
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+su_bfee_entry_del_88xx(struct halmac_adapter *adapter, u8 userid)
+{
+	u16 value16;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	switch (userid) {
+	case 0:
+		value16 = HALMAC_REG_R16(REG_TXBF_CTRL);
+		value16 &= ~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
+					BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+		HALMAC_REG_W16(REG_TXBF_CTRL, value16);
+		HALMAC_REG_W16(REG_ASSOCIATED_BFMEE_SEL, 0);
+		break;
+	case 1:
+		value16 = HALMAC_REG_R16(REG_TXBF_CTRL + 2);
+		value16 &= ~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
+					BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
+		HALMAC_REG_W16(REG_TXBF_CTRL + 2, value16);
+		HALMAC_REG_W16(REG_ASSOCIATED_BFMEE_SEL + 2, 0);
+		break;
+	case 2:
+		HALMAC_REG_W16(REG_WMAC_ASSOCIATED_MU_BFMEE2, 0);
+		break;
+	case 3:
+		HALMAC_REG_W16(REG_WMAC_ASSOCIATED_MU_BFMEE3, 0);
+		break;
+	case 4:
+		HALMAC_REG_W16(REG_WMAC_ASSOCIATED_MU_BFMEE4, 0);
+		break;
+	case 5:
+		HALMAC_REG_W16(REG_WMAC_ASSOCIATED_MU_BFMEE5, 0);
+		break;
+	default:
+		return HALMAC_RET_INVALID_SOUNDING_SETTING;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * su_bfee_entry_del_88xx() - reset SU beamformer's registers
+ * @adapter : the adapter of halmac
+ * @userid : the SU BFer userid to be deleted
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+su_bfer_entry_del_88xx(struct halmac_adapter *adapter, u8 userid)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	switch (userid) {
+	case 0:
+		HALMAC_REG_W32(REG_ASSOCIATED_BFMER0_INFO, 0);
+		HALMAC_REG_W32(REG_ASSOCIATED_BFMER0_INFO + 4, 0);
+		break;
+	case 1:
+		HALMAC_REG_W32(REG_ASSOCIATED_BFMER1_INFO, 0);
+		HALMAC_REG_W32(REG_ASSOCIATED_BFMER1_INFO + 4, 0);
+		break;
+	default:
+		return HALMAC_RET_INVALID_SOUNDING_SETTING;
+	}
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * mu_bfee_entry_del_88xx() - reset MU beamformee's registers
+ * @adapter : the adapter of halmac
+ * @userid : the MU STA userid to be deleted
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+mu_bfee_entry_del_88xx(struct halmac_adapter *adapter, u8 userid)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	HALMAC_REG_W16(0x1680 + userid * 2, 0);
+	HALMAC_REG_W8_CLR(REG_MU_TX_CTL, BIT(userid - 2));
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * mu_bfer_entry_del_88xx() -reset MU beamformer's registers
+ * @adapter : the adapter of halmac
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+mu_bfer_entry_del_88xx(struct halmac_adapter *adapter)
+{
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	HALMAC_REG_W32(REG_ASSOCIATED_BFMER0_INFO, 0);
+	HALMAC_REG_W32(REG_ASSOCIATED_BFMER0_INFO + 4, 0);
+	HALMAC_REG_W16(0x1680, 0);
+	HALMAC_REG_W8(REG_MU_TX_CTL, 0);
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s <===\n",
+		 __func__);
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * cfg_csi_rate_88xx() - config CSI frame Tx rate
+ * @adapter : the adapter of halmac
+ * @rssi : rssi in decimal value
+ * @cur_rate : current CSI frame rate
+ * @fixrate_en : enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate
+ * @new_rate : API returns the final CSI frame rate
+ * Author : chunchu
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+cfg_csi_rate_88xx(struct halmac_adapter *adapter, u8 rssi, u8 cur_rate,
+		  u8 fixrate_en, u8 *new_rate)
+{
+	u32 csi_cfg;
+	u16 cur_rrsr;
+	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
+
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG, "%s ===>\n",
+		 __func__);
+
+	csi_cfg = HALMAC_REG_R32(REG_BBPSF_CTRL) & ~BITS_WMAC_CSI_RATE;
+
+	cur_rrsr = HALMAC_REG_R16(REG_RRSR);
+
+	if (rssi >= 40) {
+		if (cur_rate != HALMAC_OFDM54) {
+			cur_rrsr |= BIT(HALMAC_OFDM54);
+			csi_cfg |= BIT_WMAC_CSI_RATE(HALMAC_OFDM54);
+			HALMAC_REG_W16(REG_RRSR, cur_rrsr);
+			HALMAC_REG_W32(REG_BBPSF_CTRL, csi_cfg);
+		}
+		*new_rate = HALMAC_OFDM54;
+	} else {
+		if (cur_rate != HALMAC_OFDM24) {
+			cur_rrsr &= ~(BIT(HALMAC_OFDM54));
+			csi_cfg |= BIT_WMAC_CSI_RATE(HALMAC_OFDM24);
+			HALMAC_REG_W16(REG_RRSR, cur_rrsr);
+			HALMAC_REG_W32(REG_BBPSF_CTRL, csi_cfg);
+		}
+		*new_rate = HALMAC_OFDM24;
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+/**
+ * fw_snding_88xx() - fw sounding control
+ * @adapter : the adapter of halmac
+ * @su_info :
+ *	su0_en : enable/disable fw sounding
+ *	su0_ndpa_pkt : ndpa pkt, shall include txdesc
+ *	su0_pkt_sz : ndpa pkt size, shall include txdesc
+ * @mu_info : currently not in use, input NULL is acceptable
+ * @period : sounding period, unit is 5ms
+ * Author : Ivan Lin
+ * Return : enum halmac_ret_status
+ * More details of status code can be found in prototype document
+ */
+enum halmac_ret_status
+fw_snding_88xx(struct halmac_adapter *adapter,
+	       struct halmac_su_snding_info *su_info,
+	       struct halmac_mu_snding_info *mu_info, u8 period)
+{
+	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
+	u16 seq_num;
+	u16 snding_info_addr;
+	struct halmac_h2c_header_info hdr_info;
+	enum halmac_cmd_process_status *proc_status;
+	enum halmac_ret_status status;
+
+	proc_status = &adapter->halmac_state.fw_snding_state.proc_status;
+
+	if (adapter->chip_id == HALMAC_CHIP_ID_8821C)
+		return HALMAC_RET_NOT_SUPPORT;
+
+	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_NO_DLFW;
+
+	if (adapter->fw_ver.h2c_version < 9)
+		return HALMAC_RET_FW_NO_SUPPORT;
+
+	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
+		RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+			 "Wait event(snd)\n");
+		return HALMAC_RET_BUSY_STATE;
+	}
+
+	if (su_info->su0_en == 1) {
+		if (!su_info->su0_ndpa_pkt)
+			return HALMAC_RET_NULL_POINTER;
+
+		if (su_info->su0_pkt_sz > (u32)SU0_SNDING_PKT_RSVDPG_SIZE -
+		    adapter->hw_cfg_info.txdesc_size)
+			return HALMAC_RET_DATA_SIZE_INCORRECT;
+
+		if (!snding_pkt_chk_88xx(adapter, su_info->su0_ndpa_pkt))
+			return HALMAC_RET_TXDESC_SET_FAIL;
+
+		if (fw_snding_cmd_cnstr_state_88xx(adapter) !=
+		    HALMAC_CMD_CNSTR_IDLE) {
+			pr_err("Not idle(snd)\n");
+			return HALMAC_RET_ERROR_STATE;
+		}
+
+		snding_info_addr = adapter->txff_alloc.rsvd_h2c_sta_info_addr +
+				   SU0_SNDING_PKT_OFFSET;
+		status = dl_rsvd_page_88xx(adapter, snding_info_addr,
+					   su_info->su0_ndpa_pkt,
+					   su_info->su0_pkt_sz);
+		if (status != HALMAC_RET_SUCCESS) {
+			pr_err("dl rsvd page\n");
+			return status;
+		}
+
+		FW_SNDING_SET_SU0(h2c_buf, 1);
+		FW_SNDING_SET_PERIOD(h2c_buf, period);
+		FW_SNDING_SET_NDPA0_HEAD_PG(h2c_buf, snding_info_addr -
+					    adapter->txff_alloc.rsvd_boundary);
+	} else {
+		if (fw_snding_cmd_cnstr_state_88xx(adapter) !=
+		    HALMAC_CMD_CNSTR_BUSY) {
+			pr_err("Not snd(snd)\n");
+			return HALMAC_RET_ERROR_STATE;
+		}
+		FW_SNDING_SET_SU0(h2c_buf, 0);
+	}
+
+	*proc_status = HALMAC_CMD_PROCESS_SENDING;
+
+	hdr_info.sub_cmd_id = SUB_CMD_ID_FW_SNDING;
+	hdr_info.content_size = 8;
+	hdr_info.ack = 1;
+	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
+	adapter->halmac_state.fw_snding_state.seq_num = seq_num;
+
+	status = send_h2c_pkt_88xx(adapter, h2c_buf);
+	if (status != HALMAC_RET_SUCCESS) {
+		pr_err("send h2c\n");
+		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_FW_SNDING);
+		return status;
+	}
+
+	if (cnv_fw_snding_state_88xx(adapter, su_info->su0_en == 1 ?
+				     HALMAC_CMD_CNSTR_BUSY :
+				     HALMAC_CMD_CNSTR_IDLE)
+				     != HALMAC_RET_SUCCESS)
+		return HALMAC_RET_ERROR_STATE;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static u8
+snding_pkt_chk_88xx(struct halmac_adapter *adapter, u8 *pkt)
+{
+	u8 data_rate;
+
+	if (GET_TX_DESC_NDPA(pkt) == 0) {
+		pr_err("txdesc ndpa = 0\n");
+		return 0;
+	}
+
+	data_rate = (u8)GET_TX_DESC_DATARATE(pkt);
+	if (!(data_rate >= HALMAC_VHT_NSS2_MCS0 &&
+	      data_rate <= HALMAC_VHT_NSS2_MCS9)) {
+		if (!(data_rate >= HALMAC_MCS8 && data_rate <= HALMAC_MCS15)) {
+			pr_err("txdesc rate\n");
+			return 0;
+		}
+	}
+
+	if (GET_TX_DESC_NAVUSEHDR(pkt) == 0) {
+		pr_err("txdesc navusehdr = 0\n");
+		return 0;
+	}
+
+	if (GET_TX_DESC_USE_RATE(pkt) == 0) {
+		pr_err("txdesc userate = 0\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+static enum halmac_cmd_construct_state
+fw_snding_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
+{
+	return adapter->halmac_state.fw_snding_state.cmd_cnstr_state;
+}
+
+enum halmac_ret_status
+get_h2c_ack_fw_snding_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
+{
+	u8 seq_num = 0;
+	u8 fw_rc;
+	struct halmac_fw_snding_state *state;
+	enum halmac_cmd_process_status proc_status;
+
+	state = &adapter->halmac_state.fw_snding_state;
+
+	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
+	RT_TRACE(adapter->drv_adapter, COMP_HALMAC, DBG_DMESG,
+		 "Seq num:h2c->%d c2h->%d\n", state->seq_num, seq_num);
+	if (seq_num != state->seq_num) {
+		pr_err("Seq num mismatch:h2c->%d c2h->%d\n", state->seq_num,
+		       seq_num);
+		return HALMAC_RET_SUCCESS;
+	}
+
+	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
+		pr_err("not sending(snd)\n");
+		return HALMAC_RET_SUCCESS;
+	}
+
+	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
+	state->fw_rc = fw_rc;
+
+	if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
+		proc_status = HALMAC_CMD_PROCESS_DONE;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_FW_SNDING, proc_status,
+				NULL, 0);
+	} else {
+		proc_status = HALMAC_CMD_PROCESS_ERROR;
+		state->proc_status = proc_status;
+		PLTFM_EVENT_SIG(HALMAC_FEATURE_FW_SNDING, proc_status,
+				&fw_rc, 1);
+	}
+
+	return HALMAC_RET_SUCCESS;
+}
+
+enum halmac_ret_status
+get_fw_snding_status_88xx(struct halmac_adapter *adapter,
+			  enum halmac_cmd_process_status *proc_status)
+{
+	*proc_status = adapter->halmac_state.fw_snding_state.proc_status;
+
+	return HALMAC_RET_SUCCESS;
+}
+
+static enum halmac_ret_status
+cnv_fw_snding_state_88xx(struct halmac_adapter *adapter,
+			 enum halmac_cmd_construct_state dest_state)
+{
+	struct halmac_fw_snding_state *state;
+
+	state = &adapter->halmac_state.fw_snding_state;
+
+	if (state->cmd_cnstr_state != HALMAC_CMD_CNSTR_IDLE &&
+	    state->cmd_cnstr_state != HALMAC_CMD_CNSTR_BUSY)
+		return HALMAC_RET_ERROR_STATE;
+
+	if (dest_state == HALMAC_CMD_CNSTR_IDLE) {
+		if (state->cmd_cnstr_state == HALMAC_CMD_CNSTR_IDLE)
+			return HALMAC_RET_ERROR_STATE;
+	} else if (dest_state == HALMAC_CMD_CNSTR_BUSY) {
+		if (state->cmd_cnstr_state == HALMAC_CMD_CNSTR_BUSY)
+			return HALMAC_RET_ERROR_STATE;
+	}
+
+	state->cmd_cnstr_state = dest_state;
+
+	return HALMAC_RET_SUCCESS;
+}
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.h b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.h
new file mode 100644
index 000000000000..7fb8e2547186
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/halmac_88xx/halmac_mimo_88xx.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ ******************************************************************************/
+
+#ifndef _HALMAC_MIMO_88XX_H_
+#define _HALMAC_MIMO_88XX_H_
+
+#include "../halmac_api.h"
+
+enum halmac_ret_status
+cfg_txbf_88xx(struct halmac_adapter *adapter, u8 userid, enum halmac_bw bw,
+	      u8 txbf_en);
+
+enum halmac_ret_status
+cfg_mumimo_88xx(struct halmac_adapter *adapter,
+		struct halmac_cfg_mumimo_para *param);
+
+enum halmac_ret_status
+cfg_sounding_88xx(struct halmac_adapter *adapter, enum halmac_snd_role role,
+		  enum halmac_data_rate rate);
+
+enum halmac_ret_status
+del_sounding_88xx(struct halmac_adapter *adapter, enum halmac_snd_role role);
+
+enum halmac_ret_status
+su_bfee_entry_init_88xx(struct halmac_adapter *adapter, u8 userid, u16 paid);
+
+enum halmac_ret_status
+su_bfer_entry_init_88xx(struct halmac_adapter *adapter,
+			struct halmac_su_bfer_init_para *param);
+
+enum halmac_ret_status
+mu_bfee_entry_init_88xx(struct halmac_adapter *adapter,
+			struct halmac_mu_bfee_init_para *param);
+
+enum halmac_ret_status
+mu_bfer_entry_init_88xx(struct halmac_adapter *adapter,
+			struct halmac_mu_bfer_init_para *param);
+
+enum halmac_ret_status
+su_bfee_entry_del_88xx(struct halmac_adapter *adapter, u8 userid);
+
+enum halmac_ret_status
+su_bfer_entry_del_88xx(struct halmac_adapter *adapter, u8 userid);
+
+enum halmac_ret_status
+mu_bfee_entry_del_88xx(struct halmac_adapter *adapter, u8 userid);
+
+enum halmac_ret_status
+mu_bfer_entry_del_88xx(struct halmac_adapter *adapter);
+
+enum halmac_ret_status
+cfg_csi_rate_88xx(struct halmac_adapter *adapter, u8 rssi, u8 cur_rate,
+		  u8 fixrate_en, u8 *new_rate);
+
+enum halmac_ret_status
+fw_snding_88xx(struct halmac_adapter *adapter,
+	       struct halmac_su_snding_info *su_info,
+	       struct halmac_mu_snding_info *mu_info, u8 period);
+
+enum halmac_ret_status
+get_h2c_ack_fw_snding_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
+
+enum halmac_ret_status
+get_fw_snding_status_88xx(struct halmac_adapter *adapter,
+			  enum halmac_cmd_process_status *proc_status);
+
+#endif/* _HALMAC_MIMO_88XX_H_ */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 17/17] rtlwifi: add halmac to Makefile and Kconfig
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (14 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 16/17] rtlwifi: halmac: add to support BB and RF functions pkshih
@ 2018-04-03  7:53 ` pkshih
  2018-04-24 17:12 ` [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac Kalle Valo
  16 siblings, 0 replies; 19+ messages in thread
From: pkshih @ 2018-04-03  7:53 UTC (permalink / raw)
  To: kvalo; +Cc: Larry.Finger, linux-wireless

From: Ping-Ke Shih <pkshih@realtek.com>

Add halmac to Makefile and Kconfig, so we can build this module if 8822BE
is selected.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtlwifi/Kconfig       |  5 ++++
 drivers/net/wireless/realtek/rtlwifi/Makefile      |  1 +
 .../net/wireless/realtek/rtlwifi/halmac/Makefile   | 29 ++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtlwifi/halmac/Makefile

diff --git a/drivers/net/wireless/realtek/rtlwifi/Kconfig b/drivers/net/wireless/realtek/rtlwifi/Kconfig
index 73067cac289c..d9aba8fed151 100644
--- a/drivers/net/wireless/realtek/rtlwifi/Kconfig
+++ b/drivers/net/wireless/realtek/rtlwifi/Kconfig
@@ -151,4 +151,9 @@ config RTLBTCOEXIST
 	depends on RTL8723AE || RTL8723BE || RTL8821AE || RTL8192EE
 	default y
 
+config RTLHALMAC
+	tristate
+	depends on RTL8822BE
+	default y
+
 endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/Makefile b/drivers/net/wireless/realtek/rtlwifi/Makefile
index 09c30e428375..a30a73c351d8 100644
--- a/drivers/net/wireless/realtek/rtlwifi/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_RTL8723AE)		+= rtl8723ae/
 obj-$(CONFIG_RTL8723BE)		+= rtl8723be/
 obj-$(CONFIG_RTL8188EE)		+= rtl8188ee/
 obj-$(CONFIG_RTLBTCOEXIST)	+= btcoexist/
+obj-$(CONFIG_RTLHALMAC)		+= halmac/
 obj-$(CONFIG_RTL8723_COMMON)	+= rtl8723com/
 obj-$(CONFIG_RTL8821AE)		+= rtl8821ae/
 obj-$(CONFIG_RTL8192EE)		+= rtl8192ee/
diff --git a/drivers/net/wireless/realtek/rtlwifi/halmac/Makefile b/drivers/net/wireless/realtek/rtlwifi/halmac/Makefile
new file mode 100644
index 000000000000..41c1ae7e5e53
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtlwifi/halmac/Makefile
@@ -0,0 +1,29 @@
+
+
+halmac-objs := \
+	halmac_api.o	\
+	halmac_88xx/halmac_bb_rf_88xx.o	\
+	halmac_88xx/halmac_efuse_88xx.o	\
+	halmac_88xx/halmac_gpio_88xx.o	\
+	halmac_88xx/halmac_pcie_88xx.o	\
+	halmac_88xx/halmac_sdio_88xx.o	\
+	halmac_88xx/halmac_usb_88xx.o	\
+	halmac_88xx/halmac_cfg_wmac_88xx.o	\
+	halmac_88xx/halmac_flash_88xx.o	\
+	halmac_88xx/halmac_init_88xx.o	\
+	halmac_88xx/halmac_common_88xx.o	\
+	halmac_88xx/halmac_fw_88xx.o	\
+	halmac_88xx/halmac_mimo_88xx.o	\
+	halmac_88xx/halmac_8822b/halmac_gpio_8822b.o	\
+	halmac_88xx/halmac_8822b/halmac_pcie_8822b.o	\
+	halmac_88xx/halmac_8822b/halmac_sdio_8822b.o	\
+	halmac_88xx/halmac_8822b/halmac_usb_8822b.o	\
+	halmac_88xx/halmac_8822b/halmac_pwr_seq_8822b.o	\
+	halmac_88xx/halmac_8822b/halmac_common_8822b.o	\
+	halmac_88xx/halmac_8822b/halmac_cfg_wmac_8822b.o	\
+	halmac_88xx/halmac_8822b/halmac_phy_8822b.o	\
+	halmac_88xx/halmac_8822b/halmac_init_8822b.o	\
+	rtl_halmac.o
+
+
+obj-m = halmac.o
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac
  2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
                   ` (15 preceding siblings ...)
  2018-04-03  7:53 ` [PATCH v2 17/17] rtlwifi: add halmac to Makefile and Kconfig pkshih
@ 2018-04-24 17:12 ` Kalle Valo
  2018-04-25  2:26   ` Pkshih
  16 siblings, 1 reply; 19+ messages in thread
From: Kalle Valo @ 2018-04-24 17:12 UTC (permalink / raw)
  To: pkshih; +Cc: Larry.Finger, linux-wireless

<pkshih@realtek.com> writes:

> From: Ping-Ke Shih <pkshih@realtek.com>
>
> v2: remove indirection to get halmac ops
>     Only patches 1/17 and 11/17 are changed.
>
> Patches 1/17-3/17 are added structure to support this module.
> Patches 4/17-16/17 add new files.
> Patch 17/17 add this module to Makefile and Kconfig.
>
> Ping-Ke Shih (17):
>   rtlwifi: add halmac structure to wifi.h
>   rtlwifi: add debug ID COMP_HALMAC
>   rtlwifi: add dmdef.h to share with driver and other modules
>   rtlwifi: halmac: add main definition used by halmac
>   rtlwifi: halmac: describe number and size of chip functions
>   rtlwifi: halmac: add definitions of registers and bit fields
>   rtlwifi: halmac: add definition of TX/RX descriptor
>   rtlwifi: halmac: add GPIO pin/pinmux definitions
>   rtlwifi: halmac: add power sequence to turn on/off wifi card
>   rtlwifi: halmac: access efuse through halmac helper functions
>   rtlwifi: halmac: add files to implement halmac ops
>   rtlwifi: halmac: add halmac init/deinit functions
>   rtlwifi: halmac: add firmware related functions and definitions
>   rtlwifi: halmac: add bus interface commands
>   rtlwifi: halmac: add to control WiFi mac functions and registers
>   rtlwifi: halmac: add to support BB and RF functions
>   rtlwifi: add halmac to Makefile and Kconfig

BTW, I don't see patch 6 in patchwork. Did it get lost?

      [v2,01/17] rtlwifi: add halmac structure to wifi.h           2018-04-03 Ping-Ke Shih New
      [v2,02/17] rtlwifi: add debug ID COMP_HALMAC                 2018-04-03 Ping-Ke Shih New
      [v2,03/17] rtlwifi: add dmdef.h to share with driver and.... 2018-04-03 Ping-Ke Shih New
      [v2,04/17] rtlwifi: halmac: add main definition used by h... 2018-04-03 Ping-Ke Shih New
      [v2,05/17] rtlwifi: halmac: describe number and size of c... 2018-04-03 Ping-Ke Shih New
      [v2,07/17] rtlwifi: halmac: add definition of TX/RX descr... 2018-04-03 Ping-Ke Shih New
      [v2,08/17] rtlwifi: halmac: add GPIO pin/pinmux definitions  2018-04-03 Ping-Ke Shih New
      [v2,09/17] rtlwifi: halmac: add power sequence to turn on... 2018-04-03 Ping-Ke Shih New
      [v2,10/17] rtlwifi: halmac: access efuse through halmac h... 2018-04-03 Ping-Ke Shih New
      [v2,11/17] rtlwifi: halmac: add files to implement halmac... 2018-04-03 Ping-Ke Shih New
      [v2,12/17] rtlwifi: halmac: add halmac init/deinit functions 2018-04-03 Ping-Ke Shih New
      [v2,13/17] rtlwifi: halmac: add firmware related function... 2018-04-03 Ping-Ke Shih New
      [v2,14/17] rtlwifi: halmac: add bus interface commands       2018-04-03 Ping-Ke Shih New
      [v2,15/17] rtlwifi: halmac: add to control WiFi mac funct... 2018-04-03 Ping-Ke Shih New
      [v2,16/17] rtlwifi: halmac: add to support BB and RF func... 2018-04-03 Ping-Ke Shih New
      [v2,17/17] rtlwifi: add halmac to Makefile and Kconfig       2018-04-03 Ping-Ke Shih New

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac
  2018-04-24 17:12 ` [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac Kalle Valo
@ 2018-04-25  2:26   ` Pkshih
  0 siblings, 0 replies; 19+ messages in thread
From: Pkshih @ 2018-04-25  2:26 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry.Finger

T24gVHVlLCAyMDE4LTA0LTI0IGF0IDE3OjEyICswMDAwLCBLYWxsZSBWYWxvIHdyb3RlOg0KPiA8
cGtzaGloQHJlYWx0ZWsuY29tPiB3cml0ZXM6DQo+wqANCj4gPiBGcm9tOiBQaW5nLUtlIFNoaWgg
PHBrc2hpaEByZWFsdGVrLmNvbT4NCj4gPg0KPiA+IHYyOiByZW1vdmUgaW5kaXJlY3Rpb24gdG8g
Z2V0IGhhbG1hYyBvcHMNCj4gPsKgwqDCoMKgwqBPbmx5IHBhdGNoZXMgMS8xNyBhbmQgMTEvMTcg
YXJlIGNoYW5nZWQuDQo+ID4NCj4gPiBQYXRjaGVzIDEvMTctMy8xNyBhcmUgYWRkZWQgc3RydWN0
dXJlIHRvIHN1cHBvcnQgdGhpcyBtb2R1bGUuDQo+ID4gUGF0Y2hlcyA0LzE3LTE2LzE3IGFkZCBu
ZXcgZmlsZXMuDQo+ID4gUGF0Y2ggMTcvMTcgYWRkIHRoaXMgbW9kdWxlIHRvIE1ha2VmaWxlIGFu
ZCBLY29uZmlnLg0KPiA+DQo+ID4gUGluZy1LZSBTaGloICgxNyk6DQo+ID7CoMKgwqBydGx3aWZp
OiBhZGQgaGFsbWFjIHN0cnVjdHVyZSB0byB3aWZpLmgNCj4gPsKgwqDCoHJ0bHdpZmk6IGFkZCBk
ZWJ1ZyBJRCBDT01QX0hBTE1BQw0KPiA+wqDCoMKgcnRsd2lmaTogYWRkIGRtZGVmLmggdG8gc2hh
cmUgd2l0aCBkcml2ZXIgYW5kIG90aGVyIG1vZHVsZXMNCj4gPsKgwqDCoHJ0bHdpZmk6IGhhbG1h
YzogYWRkIG1haW4gZGVmaW5pdGlvbiB1c2VkIGJ5IGhhbG1hYw0KPiA+wqDCoMKgcnRsd2lmaTog
aGFsbWFjOiBkZXNjcmliZSBudW1iZXIgYW5kIHNpemUgb2YgY2hpcCBmdW5jdGlvbnMNCj4gPsKg
wqDCoHJ0bHdpZmk6IGhhbG1hYzogYWRkIGRlZmluaXRpb25zIG9mIHJlZ2lzdGVycyBhbmQgYml0
IGZpZWxkcw0KPiA+wqDCoMKgcnRsd2lmaTogaGFsbWFjOiBhZGQgZGVmaW5pdGlvbiBvZiBUWC9S
WCBkZXNjcmlwdG9yDQo+ID7CoMKgwqBydGx3aWZpOiBoYWxtYWM6IGFkZCBHUElPIHBpbi9waW5t
dXggZGVmaW5pdGlvbnMNCj4gPsKgwqDCoHJ0bHdpZmk6IGhhbG1hYzogYWRkIHBvd2VyIHNlcXVl
bmNlIHRvIHR1cm4gb24vb2ZmIHdpZmkgY2FyZA0KPiA+wqDCoMKgcnRsd2lmaTogaGFsbWFjOiBh
Y2Nlc3MgZWZ1c2UgdGhyb3VnaCBoYWxtYWMgaGVscGVyIGZ1bmN0aW9ucw0KPiA+wqDCoMKgcnRs
d2lmaTogaGFsbWFjOiBhZGQgZmlsZXMgdG8gaW1wbGVtZW50IGhhbG1hYyBvcHMNCj4gPsKgwqDC
oHJ0bHdpZmk6IGhhbG1hYzogYWRkIGhhbG1hYyBpbml0L2RlaW5pdCBmdW5jdGlvbnMNCj4gPsKg
wqDCoHJ0bHdpZmk6IGhhbG1hYzogYWRkIGZpcm13YXJlIHJlbGF0ZWQgZnVuY3Rpb25zIGFuZCBk
ZWZpbml0aW9ucw0KPiA+wqDCoMKgcnRsd2lmaTogaGFsbWFjOiBhZGQgYnVzIGludGVyZmFjZSBj
b21tYW5kcw0KPiA+wqDCoMKgcnRsd2lmaTogaGFsbWFjOiBhZGQgdG8gY29udHJvbCBXaUZpIG1h
YyBmdW5jdGlvbnMgYW5kIHJlZ2lzdGVycw0KPiA+wqDCoMKgcnRsd2lmaTogaGFsbWFjOiBhZGQg
dG8gc3VwcG9ydCBCQiBhbmQgUkYgZnVuY3Rpb25zDQo+ID7CoMKgwqBydGx3aWZpOiBhZGQgaGFs
bWFjIHRvIE1ha2VmaWxlIGFuZCBLY29uZmlnDQo+wqANCj4gQlRXLCBJIGRvbid0IHNlZSBwYXRj
aCA2IGluIHBhdGNod29yay4gRGlkIGl0IGdldCBsb3N0Pw0KPsKgDQo+wqDCoMKgwqDCoMKgwqBb
djIsMDEvMTddIHJ0bHdpZmk6IGFkZCBoYWxtYWMgc3RydWN0dXJlIHRvIHdpZmkuaMKgwqDCoMKg
wqDCoMKgwqDCoMKgwqAyMDE4LTA0LTAzIFBpbmctS2UgU2hpaCBOZXcNCj7CoMKgwqDCoMKgwqDC
oFt2MiwwMi8xN10gcnRsd2lmaTogYWRkIGRlYnVnIElEIENPTVBfSEFMTUFDwqDCoMKgwqDCoMKg
wqDCoMKgwqDCoMKgwqDCoMKgwqDCoDIwMTgtMDQtMDMgUGluZy1LZSBTaGloIE5ldw0KPsKgwqDC
oMKgwqDCoMKgW3YyLDAzLzE3XSBydGx3aWZpOiBhZGQgZG1kZWYuaCB0byBzaGFyZSB3aXRoIGRy
aXZlciBhbmQuLi4uIDIwMTgtMDQtMDMgUGluZy1LZSBTaGloIE5ldw0KPsKgwqDCoMKgwqDCoMKg
W3YyLDA0LzE3XSBydGx3aWZpOiBoYWxtYWM6IGFkZCBtYWluIGRlZmluaXRpb24gdXNlZCBieSBo
Li4uIDIwMTgtMDQtMDMgUGluZy1LZSBTaGloIE5ldw0KPsKgwqDCoMKgwqDCoMKgW3YyLDA1LzE3
XSBydGx3aWZpOiBoYWxtYWM6IGRlc2NyaWJlIG51bWJlciBhbmQgc2l6ZSBvZiBjLi4uIDIwMTgt
MDQtMDMgUGluZy1LZSBTaGloIE5ldw0KPsKgwqDCoMKgwqDCoMKgW3YyLDA3LzE3XSBydGx3aWZp
OiBoYWxtYWM6IGFkZCBkZWZpbml0aW9uIG9mIFRYL1JYIGRlc2NyLi4uIDIwMTgtMDQtMDMgUGlu
Zy1LZSBTaGloIE5ldw0KPsKgwqDCoMKgwqDCoMKgW3YyLDA4LzE3XSBydGx3aWZpOiBoYWxtYWM6
IGFkZCBHUElPIHBpbi9waW5tdXggZGVmaW5pdGlvbnPCoMKgMjAxOC0wNC0wMyBQaW5nLUtlIFNo
aWggTmV3DQo+wqDCoMKgwqDCoMKgwqBbdjIsMDkvMTddIHJ0bHdpZmk6IGhhbG1hYzogYWRkIHBv
d2VyIHNlcXVlbmNlIHRvIHR1cm4gb24uLi4gMjAxOC0wNC0wMyBQaW5nLUtlIFNoaWggTmV3DQo+
wqDCoMKgwqDCoMKgwqBbdjIsMTAvMTddIHJ0bHdpZmk6IGhhbG1hYzogYWNjZXNzIGVmdXNlIHRo
cm91Z2ggaGFsbWFjIGguLi4gMjAxOC0wNC0wMyBQaW5nLUtlIFNoaWggTmV3DQo+wqDCoMKgwqDC
oMKgwqBbdjIsMTEvMTddIHJ0bHdpZmk6IGhhbG1hYzogYWRkIGZpbGVzIHRvIGltcGxlbWVudCBo
YWxtYWMuLi4gMjAxOC0wNC0wMyBQaW5nLUtlIFNoaWggTmV3DQo+wqDCoMKgwqDCoMKgwqBbdjIs
MTIvMTddIHJ0bHdpZmk6IGhhbG1hYzogYWRkIGhhbG1hYyBpbml0L2RlaW5pdCBmdW5jdGlvbnMg
MjAxOC0wNC0wMyBQaW5nLUtlIFNoaWggTmV3DQo+wqDCoMKgwqDCoMKgwqBbdjIsMTMvMTddIHJ0
bHdpZmk6IGhhbG1hYzogYWRkIGZpcm13YXJlIHJlbGF0ZWQgZnVuY3Rpb24uLi4gMjAxOC0wNC0w
MyBQaW5nLUtlIFNoaWggTmV3DQo+wqDCoMKgwqDCoMKgwqBbdjIsMTQvMTddIHJ0bHdpZmk6IGhh
bG1hYzogYWRkIGJ1cyBpbnRlcmZhY2UgY29tbWFuZHPCoMKgwqDCoMKgwqDCoDIwMTgtMDQtMDMg
UGluZy1LZSBTaGloIE5ldw0KPsKgwqDCoMKgwqDCoMKgW3YyLDE1LzE3XSBydGx3aWZpOiBoYWxt
YWM6IGFkZCB0byBjb250cm9sIFdpRmkgbWFjIGZ1bmN0Li4uIDIwMTgtMDQtMDMgUGluZy1LZSBT
aGloIE5ldw0KPsKgwqDCoMKgwqDCoMKgW3YyLDE2LzE3XSBydGx3aWZpOiBoYWxtYWM6IGFkZCB0
byBzdXBwb3J0IEJCIGFuZCBSRiBmdW5jLi4uIDIwMTgtMDQtMDMgUGluZy1LZSBTaGloIE5ldw0K
PsKgwqDCoMKgwqDCoMKgW3YyLDE3LzE3XSBydGx3aWZpOiBhZGQgaGFsbWFjIHRvIE1ha2VmaWxl
IGFuZCBLY29uZmlnwqDCoMKgwqDCoMKgwqAyMDE4LTA0LTAzIFBpbmctS2UgU2hpaCBOZXcNCj7C
oA0KDQpQYXRjaCAwNi8xNyBpbiB2MiBpcyB0b28gYmlnLCBzbyBtYWlsIHNlcnZlciBibG9ja3Mg
aXQuDQpJIHNwbGl0IHRoZSBwYXRjaCBpbnRvIHRocmVlIHBhdGNoZXMsIGFuZCByZXNlbmQgdjMu
DQoNClRoYW5rcw0KUEsNCg==

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2018-04-25  2:26 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-03  7:53 [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac pkshih
2018-04-03  7:53 ` [PATCH v2 01/17] rtlwifi: add halmac structure to wifi.h pkshih
2018-04-03  7:53 ` [PATCH v2 02/17] rtlwifi: add debug ID COMP_HALMAC pkshih
2018-04-03  7:53 ` [PATCH v2 03/17] rtlwifi: add dmdef.h to share with driver and other modules pkshih
2018-04-03  7:53 ` [PATCH v2 04/17] rtlwifi: halmac: add main definition used by halmac pkshih
2018-04-03  7:53 ` [PATCH v2 05/17] rtlwifi: halmac: describe number and size of chip functions pkshih
2018-04-03  7:53 ` [PATCH v2 07/17] rtlwifi: halmac: add definition of TX/RX descriptor pkshih
2018-04-03  7:53 ` [PATCH v2 08/17] rtlwifi: halmac: add GPIO pin/pinmux definitions pkshih
2018-04-03  7:53 ` [PATCH v2 09/17] rtlwifi: halmac: add power sequence to turn on/off wifi card pkshih
2018-04-03  7:53 ` [PATCH v2 10/17] rtlwifi: halmac: access efuse through halmac helper functions pkshih
2018-04-03  7:53 ` [PATCH v2 11/17] rtlwifi: halmac: add files to implement halmac ops pkshih
2018-04-03  7:53 ` [PATCH v2 12/17] rtlwifi: halmac: add halmac init/deinit functions pkshih
2018-04-03  7:53 ` [PATCH v2 13/17] rtlwifi: halmac: add firmware related functions and definitions pkshih
2018-04-03  7:53 ` [PATCH v2 14/17] rtlwifi: halmac: add bus interface commands pkshih
2018-04-03  7:53 ` [PATCH v2 15/17] rtlwifi: halmac: add to control WiFi mac functions and registers pkshih
2018-04-03  7:53 ` [PATCH v2 16/17] rtlwifi: halmac: add to support BB and RF functions pkshih
2018-04-03  7:53 ` [PATCH v2 17/17] rtlwifi: add halmac to Makefile and Kconfig pkshih
2018-04-24 17:12 ` [PATCH v2 00/17] rtlwifi: halmac: Add new module halmac Kalle Valo
2018-04-25  2:26   ` Pkshih

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.