@@ -12,4 +12,5 @@ void rtl_set_mac_mcu_8126a_3(struct rtl_hw *hw);
void rtl_set_phy_mcu_8126a_1(struct rtl_hw *hw);
void rtl_set_phy_mcu_8126a_2(struct rtl_hw *hw);
void rtl_set_phy_mcu_8126a_3(struct rtl_hw *hw);
+
#endif
@@ -266,7 +266,11 @@ enum RTL_registers {
Q_NUM_CTRL_8125 = 0x4800,
RSS_KEY_8125 = 0x4600,
RSS_INDIRECTION_TBL_8125_V2 = 0x4700,
- EEE_TXIDLE_TIMER_8125 = 0x6048,
+ EEE_TXIDLE_TIMER_8125 = 0x6048,
+ IB2SOC_SET = 0x0010,
+ IB2SOC_DATA = 0x0014,
+ IB2SOC_CMD = 0x0018,
+ IB2SOC_IMR = 0x001C,
};
enum RTL_register_content {
@@ -24,14 +24,14 @@ rtl_is_allow_access_dash_ocp(struct rtl_hw *hw)
allow_access = true;
switch (hw->mcfg) {
- case CFG_METHOD_2:
- case CFG_METHOD_3:
+ case CFG_METHOD_48:
+ case CFG_METHOD_49:
mac_ocp_data = rtl_mac_ocp_read(hw, 0xd460);
if (mac_ocp_data == 0xffff || !(mac_ocp_data & BIT_0))
allow_access = false;
break;
- case CFG_METHOD_8:
- case CFG_METHOD_9:
+ case CFG_METHOD_54:
+ case CFG_METHOD_55:
mac_ocp_data = rtl_mac_ocp_read(hw, 0xd4c0);
if (mac_ocp_data == 0xffff || (mac_ocp_data & BIT_3))
allow_access = false;
@@ -84,3 +84,144 @@ rtl_check_dash(struct rtl_hw *hw)
return 0;
}
+
+static void
+rtl8125_dash2_disable_tx(struct rtl_hw *hw)
+{
+ u16 wait_cnt = 0;
+ u8 tmp_uchar;
+
+ if (!HW_DASH_SUPPORT_CMAC(hw))
+ return;
+
+ if (!hw->DASH)
+ return;
+
+ /* Disable oob Tx */
+ RTL_CMAC_W8(hw, CMAC_IBCR2, RTL_CMAC_R8(hw, CMAC_IBCR2) & ~BIT_0);
+
+ /* Wait oob Tx disable */
+ do {
+ tmp_uchar = RTL_CMAC_R8(hw, CMAC_IBISR0);
+ if (tmp_uchar & ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE)
+ break;
+
+ rte_delay_us(50);
+ wait_cnt++;
+ } while (wait_cnt < 2000);
+
+ /* Clear ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE */
+ RTL_CMAC_W8(hw, CMAC_IBISR0, RTL_CMAC_R8(hw, CMAC_IBISR0) |
+ ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE);
+}
+
+static void
+rtl8125_dash2_disable_rx(struct rtl_hw *hw)
+{
+ if (!HW_DASH_SUPPORT_CMAC(hw))
+ return;
+
+ if (!hw->DASH)
+ return;
+
+ RTL_CMAC_W8(hw, CMAC_IBCR0, RTL_CMAC_R8(hw, CMAC_IBCR0) & ~BIT_0);
+}
+
+void
+rtl8125_dash2_disable_txrx(struct rtl_hw *hw)
+{
+ if (!HW_DASH_SUPPORT_CMAC(hw))
+ return;
+
+ rtl8125_dash2_disable_tx(hw);
+ rtl8125_dash2_disable_rx(hw);
+}
+
+static void
+rtl8125_notify_dash_oob_cmac(struct rtl_hw *hw, u32 cmd)
+{
+ u32 tmp_value;
+
+ if (!HW_DASH_SUPPORT_CMAC(hw))
+ return;
+
+ rtl_ocp_write(hw, 0x180, 4, cmd);
+ tmp_value = rtl_ocp_read(hw, 0x30, 4);
+ tmp_value |= BIT_0;
+ rtl_ocp_write(hw, 0x30, 4, tmp_value);
+}
+
+static void
+rtl8125_notify_dash_oob_ipc2(struct rtl_hw *hw, u32 cmd)
+{
+ if (HW_DASH_SUPPORT_TYPE_4(hw) == FALSE)
+ return;
+
+ rtl_ocp_write(hw, IB2SOC_DATA, 4, cmd);
+ rtl_ocp_write(hw, IB2SOC_CMD, 4, 0x00);
+ rtl_ocp_write(hw, IB2SOC_SET, 4, 0x01);
+}
+
+static void
+rtl8125_notify_dash_oob(struct rtl_hw *hw, u32 cmd)
+{
+ switch (hw->HwSuppDashVer) {
+ case 2:
+ case 3:
+ rtl8125_notify_dash_oob_cmac(hw, cmd);
+ break;
+ case 4:
+ rtl8125_notify_dash_oob_ipc2(hw, cmd);
+ break;
+ default:
+ break;
+ }
+}
+
+static int
+rtl8125_wait_dash_fw_ready(struct rtl_hw *hw)
+{
+ int rc = -1;
+ int timeout;
+
+ if (!hw->DASH)
+ goto out;
+
+ for (timeout = 0; timeout < 10; timeout++) {
+ rte_delay_ms(10);
+ if (rtl_ocp_read(hw, 0x124, 1) & BIT_0) {
+ rc = 1;
+ goto out;
+ }
+ }
+
+ rc = 0;
+
+out:
+ return rc;
+}
+
+void
+rtl8125_driver_start(struct rtl_hw *hw)
+{
+ if (!hw->AllowAccessDashOcp)
+ return;
+
+ rtl8125_notify_dash_oob(hw, OOB_CMD_DRIVER_START);
+
+ rtl8125_wait_dash_fw_ready(hw);
+}
+
+void
+rtl8125_driver_stop(struct rtl_hw *hw)
+{
+ if (!hw->AllowAccessDashOcp)
+ return;
+
+ if (HW_DASH_SUPPORT_CMAC(hw))
+ rtl8125_dash2_disable_txrx(hw);
+
+ rtl8125_notify_dash_oob(hw, OOB_CMD_DRIVER_STOP);
+
+ rtl8125_wait_dash_fw_ready(hw);
+}
@@ -19,15 +19,39 @@
#define HW_DASH_SUPPORT_TYPE_2(_M) ((_M)->HwSuppDashVer == 2)
#define HW_DASH_SUPPORT_TYPE_3(_M) ((_M)->HwSuppDashVer == 3)
#define HW_DASH_SUPPORT_TYPE_4(_M) ((_M)->HwSuppDashVer == 4)
-
+#define HW_DASH_SUPPORT_CMAC(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || HW_DASH_SUPPORT_TYPE_3(_M))
#define HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || \
HW_DASH_SUPPORT_TYPE_3(_M) || \
HW_DASH_SUPPORT_TYPE_4(_M))
+#define OOB_CMD_DRIVER_START 0x05
+#define OOB_CMD_DRIVER_STOP 0x06
+
#define OCP_REG_FIRMWARE_MAJOR_VERSION 0x120
+#define ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE BIT_5
+
+/* CMAC write/read MMIO register */
+#define RTL_CMAC_REG_ADDR(hw, reg) ((u8 *)(hw)->cmac_ioaddr + (reg))
+#define RTL_CMAC_R32(hw, reg) rtl_read32(RTL_CMAC_REG_ADDR(hw, reg))
+#define RTL_CMAC_R16(hw, reg) rtl_read16(RTL_CMAC_REG_ADDR(hw, reg))
+#define RTL_CMAC_R8(hw, reg) rte_read8(RTL_CMAC_REG_ADDR(hw, reg))
+
+#define RTL_CMAC_W32(hw, reg, val) \
+ rte_write32((rte_cpu_to_le_32(val)), RTL_CMAC_REG_ADDR(hw, reg))
+
+#define RTL_CMAC_W16(hw, reg, val) \
+ rte_write16((rte_cpu_to_le_16(val)), RTL_CMAC_REG_ADDR(hw, reg))
+
+#define RTL_CMAC_W8(hw, reg, val) \
+ rte_write8((val), RTL_CMAC_REG_ADDR(hw, reg))
+
bool rtl_is_allow_access_dash_ocp(struct rtl_hw *hw);
int rtl_check_dash(struct rtl_hw *hw);
+void rtl8125_driver_start(struct rtl_hw *hw);
+void rtl8125_driver_stop(struct rtl_hw *hw);
+void rtl8125_dash2_disable_txrx(struct rtl_hw *hw);
+
#endif
@@ -24,6 +24,7 @@
#include "r8169_compat.h"
#include "r8169_logs.h"
#include "r8169_hw.h"
+#include "r8169_dash.h"
static int rtl_dev_configure(struct rte_eth_dev *dev);
static int rtl_dev_start(struct rte_eth_dev *dev);
@@ -582,6 +583,9 @@ rtl_dev_close(struct rte_eth_dev *dev)
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
+ if (HW_DASH_SUPPORT_DASH(hw))
+ rtl8125_driver_stop(hw);
+
ret_stp = rtl_dev_stop(dev);
rtl_free_queues(dev);
@@ -1286,6 +1286,11 @@ rtl_exit_oob(struct rtl_hw *hw)
rtl_disable_rx_packet_filter(hw);
+ if (HW_DASH_SUPPORT_DASH(hw)) {
+ rtl8125_driver_start(hw);
+ rtl8125_dash2_disable_txrx(hw);
+ }
+
rtl_exit_realwow(hw);
rtl_nic_reset(hw);