new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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},
+};
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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, ®_cfg);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+ status = cnv_to_sdio_bus_offset_88xx(adapter, ®_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, ®_cfg);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+ status = cnv_to_sdio_bus_offset_88xx(adapter, ®_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, ®_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, ®_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, ®_cfg);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+ status = cnv_to_sdio_bus_offset_88xx(adapter, ®_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, ®_cfg);
+ if (status != HALMAC_RET_SUCCESS)
+ return status;
+ status = cnv_to_sdio_bus_offset_88xx(adapter, ®_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;
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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
new file mode 100644
@@ -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__ */
new file mode 100644
@@ -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__ */
new file mode 100644
@@ -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__ */