From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6976B45A25; Wed, 25 Sep 2024 09:54:28 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 39EF84025D; Wed, 25 Sep 2024 09:54:28 +0200 (CEST) Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by mails.dpdk.org (Postfix) with ESMTP id 19A80400EF for ; Wed, 25 Sep 2024 09:54:25 +0200 (CEST) X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 48P7sL7t9045553, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=realsil.com.cn; s=dkim; t=1727250861; bh=Z1c2Td4ecMGXMpw/io9HJJlz5U0Q1h9aDimJqDVkQqA=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version: Content-Transfer-Encoding:Content-Type; b=thtBuaeWgnfLm6aDr831WXMEYZINVNggWRKeEbcRCyAzea6WVulaquo+7ejflj43s 2bUlfo5SNl92vfet7fqQbWIBSgClspdfQ2ELHla+S6oDNJOr3j/JAHK2KjUo8OsJfh l4YLY24dcIrloY7GkpziqQaSIm78i/p5TWYZUdWsIQaXvzkubQIAG1yw4/rN5oYNZZ gL0/c0jFCbqBhX69FCZROt3X8TuIVky+VRcK18COeXx8JVL7vG9Zx8uzhnju+p000G t2NyiTFf0YciTUyqpeeu5ECNjOKd0ifvP1IJkCm0DUOUOEe8QvmjV2fbUvDMpV1+/L TCK4MKWKVFogA== Received: from RSEXMBS03.realsil.com.cn ([172.29.17.197]) by rtits2.realtek.com.tw (8.15.2/3.05/5.92) with ESMTPS id 48P7sL7t9045553 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Wed, 25 Sep 2024 15:54:21 +0800 Received: from RSEXH36502.realsil.com.cn (172.29.17.3) by RSEXMBS03.realsil.com.cn (172.29.17.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Wed, 25 Sep 2024 15:54:22 +0800 Received: from 172.29.32.27 (172.29.32.27) by RSEXH36502.realsil.com.cn (172.29.17.3) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Wed, 25 Sep 2024 15:54:22 +0800 From: Howard Wang To: CC: , Howard Wang Subject: [PATCH] net/r8169: add support for hw initialization Date: Wed, 25 Sep 2024 15:54:21 +0800 Message-ID: <20240925075421.38142-1-howard_wang@realsil.com.cn> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Signed-off-by: Howard Wang --- drivers/net/r8169/meson.build | 1 + drivers/net/r8169/r8169_base.h | 43 +++ drivers/net/r8169/r8169_dash.c | 87 +++++ drivers/net/r8169/r8169_dash.h | 35 ++ drivers/net/r8169/r8169_ethdev.c | 57 ++- drivers/net/r8169/r8169_ethdev.h | 30 +- drivers/net/r8169/r8169_hw.c | 588 +++++++++++++++++++++++++++++++ drivers/net/r8169/r8169_hw.h | 42 +++ drivers/net/r8169/r8169_phy.h | 16 +- 9 files changed, 889 insertions(+), 10 deletions(-) create mode 100644 drivers/net/r8169/r8169_dash.c create mode 100644 drivers/net/r8169/r8169_dash.h diff --git a/drivers/net/r8169/meson.build b/drivers/net/r8169/meson.build index 08995453c7..8235e8ca43 100644 --- a/drivers/net/r8169/meson.build +++ b/drivers/net/r8169/meson.build @@ -6,6 +6,7 @@ sources = files( 'r8169_hw.c', 'r8169_rxtx.c', 'r8169_phy.c', + 'r8169_dash.c', 'base/rtl8125a.c', 'base/rtl8125a_mcu.c', 'base/rtl8125b.c', diff --git a/drivers/net/r8169/r8169_base.h b/drivers/net/r8169/r8169_base.h index e01b1e3470..2ee6fc6782 100644 --- a/drivers/net/r8169/r8169_base.h +++ b/drivers/net/r8169/r8169_base.h @@ -237,6 +237,10 @@ enum RTL_registers { IMR_V4_L2_CLEAR_REG_8125 = 0x0D10, IMR_V4_L2_SET_REG_8125 = 0x0D18, ISR_V4_L2_8125 = 0x0D14, + SW_TAIL_PTR0_8125BP = 0x0D30, + SW_TAIL_PTR1_8125BP = 0x0D38, + HW_CLO_PTR0_8125BP = 0x0D34, + HW_CLO_PTR1_8125BP = 0x0D3C, DOUBLE_VLAN_CONFIG = 0x1000, TX_NEW_CTRL = 0x203E, TNPDS_Q1_LOW_8125 = 0x2100, @@ -482,6 +486,16 @@ enum RTL_register_content { ISRIMR_V2_LINKCHG = (1 << 21), }; +enum RTL_chipset_name { + RTL8125A = 0, + RTL8125B, + RTL8168KB, + RTL8125BP, + RTL8125D, + RTL8126A, + UNKNOWN +}; + #define PCI_VENDOR_ID_REALTEK 0x10EC #define RTL_PCI_REG_ADDR(hw, reg) ((u8 *)(hw)->mmio_addr + (reg)) @@ -522,6 +536,35 @@ enum RTL_register_content { #define ETH_HLEN 14 +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 +#define SPEED_2500 2500 +#define SPEED_5000 5000 + +#define DUPLEX_HALF 1 +#define DUPLEX_FULL 2 + +#define AUTONEG_ENABLE 1 +#define AUTONEG_DISABLE 0 + +#define ADVERTISE_10_HALF 0x0001 +#define ADVERTISE_10_FULL 0x0002 +#define ADVERTISE_100_HALF 0x0004 +#define ADVERTISE_100_FULL 0x0008 +#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ +#define ADVERTISE_1000_FULL 0x0020 +#define ADVERTISE_2500_HALF 0x0040 /* NOT used, just FYI */ +#define ADVERTISE_2500_FULL 0x0080 +#define ADVERTISE_5000_HALF 0x0100 /* NOT used, just FYI */ +#define ADVERTISE_5000_FULL 0x0200 + +#define RTL8126_ALL_SPEED_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \ + ADVERTISE_100_HALF | ADVERTISE_100_FULL | ADVERTISE_1000_FULL | \ + ADVERTISE_2500_FULL | ADVERTISE_5000_FULL) + +#define MAC_ADDR_LEN RTE_ETHER_ADDR_LEN + static inline u32 rtl_read32(volatile void *addr) { diff --git a/drivers/net/r8169/r8169_dash.c b/drivers/net/r8169/r8169_dash.c new file mode 100644 index 0000000000..9422f10402 --- /dev/null +++ b/drivers/net/r8169/r8169_dash.c @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 Realtek Corporation. All rights reserved + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "r8169_base.h" +#include "r8169_dash.h" +#include "r8169_hw.h" + +bool +rtl_is_allow_access_dash_ocp(struct rtl_hw *hw) +{ + bool allow_access = false; + u16 mac_ocp_data; + + if (!HW_DASH_SUPPORT_DASH(hw)) + goto exit; + + allow_access = true; + switch (hw->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + 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: + mac_ocp_data = rtl_mac_ocp_read(hw, 0xd4c0); + if (mac_ocp_data == 0xffff || (mac_ocp_data & BIT_3)) + allow_access = false; + break; + default: + goto exit; + } +exit: + return allow_access; +} + +static u32 +rtl_get_dash_fw_ver(struct rtl_hw *hw) +{ + u32 ver = 0xffffffff; + + if (FALSE == HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(hw)) + goto exit; + + ver = rtl_ocp_read(hw, OCP_REG_FIRMWARE_MAJOR_VERSION, 4); + +exit: + return ver; +} + +static int +_rtl_check_dash(struct rtl_hw *hw) +{ + if (!hw->AllowAccessDashOcp) + return 0; + + if (HW_DASH_SUPPORT_TYPE_2(hw) || HW_DASH_SUPPORT_TYPE_4(hw)) { + if (rtl_ocp_read(hw, 0x128, 1) & BIT_0) + return 1; + } + + return 0; +} + +int +rtl_check_dash(struct rtl_hw *hw) +{ + if (_rtl_check_dash(hw)) { + u32 ver = rtl_get_dash_fw_ver(hw); + if (!(ver == 0 || ver == 0xffffffff)) + return 1; + } + + return 0; +} + diff --git a/drivers/net/r8169/r8169_dash.h b/drivers/net/r8169/r8169_dash.h new file mode 100644 index 0000000000..d89b2e2d3b --- /dev/null +++ b/drivers/net/r8169/r8169_dash.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 Realtek Corporation. All rights reserved + */ + +#ifndef _R8169_DASH_H_ +#define _R8169_DASH_H_ + +#include +#include + +#include +#include + +#include "r8169_base.h" +#include "r8169_hw.h" + +#define HW_DASH_SUPPORT_DASH(_M) ((_M)->HwSuppDashVer > 0) +#define HW_DASH_SUPPORT_TYPE_1(_M) ((_M)->HwSuppDashVer == 1) +#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_GET_FIRMWARE_VERSION(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || \ + HW_DASH_SUPPORT_TYPE_3(_M) || \ + HW_DASH_SUPPORT_TYPE_4(_M)) + +#define OCP_REG_FIRMWARE_MAJOR_VERSION 0x120 + +bool rtl_is_allow_access_dash_ocp(struct rtl_hw *hw); + +int rtl_check_dash(struct rtl_hw *hw); + + +#endif + diff --git a/drivers/net/r8169/r8169_ethdev.c b/drivers/net/r8169/r8169_ethdev.c index b24d39450e..e1b04bc08f 100644 --- a/drivers/net/r8169/r8169_ethdev.c +++ b/drivers/net/r8169/r8169_ethdev.c @@ -112,6 +112,15 @@ rtl_dev_stop(struct rte_eth_dev *dev) if (hw->adapter_stopped) return 0; + rtl_nic_reset(hw); + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + rtl_mac_ocp_write(hw, 0xE00A, hw->mcu_pme_setting); + break; + } + rtl_powerdown_pll(hw); hw->adapter_stopped = 1; @@ -126,13 +135,23 @@ rtl_dev_stop(struct rte_eth_dev *dev) static int rtl_dev_close(struct rte_eth_dev *dev) { + //struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + //struct rte_intr_handle *intr_handle = pci_dev->intr_handle; + struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); + struct rtl_hw *hw = &adapter->hw; int ret_stp; if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; + //if (HW_DASH_SUPPORT_DASH(hw)) + // rtl_driver_stop(hw); + ret_stp = rtl_dev_stop(dev); + /* Reprogram the RAR[0] in case user changed it. */ + rtl_rar_set(hw, hw->mac_addr); + return ret_stp; } @@ -140,9 +159,10 @@ static int rtl_dev_init(struct rte_eth_dev *dev) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); - struct rte_intr_handle *intr_handle = pci_dev->intr_handle; + //struct rte_intr_handle *intr_handle = pci_dev->intr_handle; struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); struct rtl_hw *hw = &adapter->hw; + struct rte_ether_addr *perm_addr = (struct rte_ether_addr *)hw->mac_addr; dev->dev_ops = &rtl_eth_dev_ops; dev->tx_pkt_burst = &rtl_xmit_pkts; @@ -154,9 +174,44 @@ rtl_dev_init(struct rte_eth_dev *dev) rte_eth_copy_pci_info(dev, pci_dev); + hw->mmio_addr = (u8 *)pci_dev->mem_resource[2].addr; /* RTL8169 uses BAR2 */ + + rtl_get_mac_version(hw, pci_dev); + if (rtl_set_hw_ops(hw)) return -ENOTSUP; + rtl_hw_initialize(hw); + + /* Read the permanent MAC address out of ROM */ + rtl_get_mac_address(hw, perm_addr); + + if (!rte_is_valid_assigned_ether_addr(perm_addr)) { + rte_eth_random_addr(&perm_addr->addr_bytes[0]); + + PMD_INIT_LOG(NOTICE, "r8169: Assign randomly generated MAC address " + "%02x:%02x:%02x:%02x:%02x:%02x", + perm_addr->addr_bytes[0], + perm_addr->addr_bytes[1], + perm_addr->addr_bytes[2], + perm_addr->addr_bytes[3], + perm_addr->addr_bytes[4], + perm_addr->addr_bytes[5]); + } + + /* Allocate memory for storing MAC addresses */ + dev->data->mac_addrs = rte_zmalloc("r8169", RTE_ETHER_ADDR_LEN, 0); + + if (dev->data->mac_addrs == NULL) { + PMD_INIT_LOG(ERR, "MAC Malloc failed"); + return -ENOMEM; + } + + /* Copy the permanent MAC address */ + rte_ether_addr_copy(perm_addr, &dev->data->mac_addrs[0]); + + rtl_rar_set(hw, &perm_addr->addr_bytes[0]); + return 0; } diff --git a/drivers/net/r8169/r8169_ethdev.h b/drivers/net/r8169/r8169_ethdev.h index a0da173685..de90b33289 100644 --- a/drivers/net/r8169/r8169_ethdev.h +++ b/drivers/net/r8169/r8169_ethdev.h @@ -23,14 +23,28 @@ struct rtl_hw_ops { void (*hw_phy_mcu_config)(struct rtl_hw *hw); }; +/* Flow control settings */ +enum rtl_fc_mode { + rtl_fc_none = 0, + rtl_fc_rx_pause, + rtl_fc_tx_pause, + rtl_fc_full, + rtl_fc_default +}; + struct rtl_hw { struct rtl_hw_ops hw_ops; u8 adapter_stopped; u8 *mmio_addr; + u8 *cmac_ioaddr; /* cmac memory map physical address */ + u8 chipset_name; + u8 efuse_ver; + u8 HwIcVerUnknown; u32 mcfg; u32 mtu; u8 HwSuppIntMitiVer; u16 cur_page; + u8 mac_addr[MAC_ADDR_LEN]; u8 RequirePhyMdiSwapPatch; u8 NotWrMcuPatchCode; @@ -44,10 +58,24 @@ struct rtl_hw { u16 sw_ram_code_ver; u16 hw_ram_code_ver; + u8 autoneg; + u8 duplex; + u32 speed; + u32 advertising; + enum rtl_fc_mode fcpause; + u32 HwSuppMaxPhyLinkSpeed; + u8 HwSuppNowIsOobVer; + + u16 mcu_pme_setting; + /* Enable Tx No Close */ - u8 EnableTxNoClose; + u8 HwSuppTxNoCloseVer; + u8 EnableTxNoClose; + u16 hw_clo_ptr_reg; + u16 sw_tail_ptr_reg; + u32 MaxTxDescPtrMask; /* Dash */ u8 HwSuppDashVer; diff --git a/drivers/net/r8169/r8169_hw.c b/drivers/net/r8169/r8169_hw.c index 42690e8698..231013e8e3 100644 --- a/drivers/net/r8169/r8169_hw.c +++ b/drivers/net/r8169/r8169_hw.c @@ -13,6 +13,7 @@ #include "r8169_hw.h" #include "r8169_logs.h" +#include "r8169_dash.h" static u32 rtl_eri_read_with_oob_base_address(struct rtl_hw *hw, int addr, int len, @@ -909,3 +910,590 @@ rtl_write_mac_mcu_ram_code(struct rtl_hw *hw, const u16 *entry, u16 entry_cnt) _rtl_write_mac_mcu_ram_code(hw, entry, entry_cnt); } +bool +rtl_is_speed_mode_valid(u32 speed) +{ + switch (speed) { + case SPEED_5000: + case SPEED_2500: + case SPEED_1000: + case SPEED_100: + case SPEED_10: + return true; + default: + return false; + } +} + +static bool +rtl_is_duplex_mode_valid(u8 duplex) +{ + switch (duplex) { + case DUPLEX_FULL: + case DUPLEX_HALF: + return true; + default: + return false; + } +} + +static bool +rtl_is_autoneg_mode_valid(u32 autoneg) +{ + switch (autoneg) { + case AUTONEG_ENABLE: + case AUTONEG_DISABLE: + return true; + default: + return false; + } +} + +static void +rtl_set_link_option(struct rtl_hw *hw, u8 autoneg, u32 speed, u8 duplex, + enum rtl_fc_mode fc) +{ + u64 adv; + + if (!rtl_is_speed_mode_valid(speed)) + speed = SPEED_5000; + + if (!rtl_is_duplex_mode_valid(duplex)) + duplex = DUPLEX_FULL; + + if (!rtl_is_autoneg_mode_valid(autoneg)) + autoneg = AUTONEG_ENABLE; + + speed = RTE_MIN(speed, hw->HwSuppMaxPhyLinkSpeed); + + adv = 0; + switch (speed) { + case SPEED_5000: + adv |= ADVERTISE_5000_FULL; + /* Fall through */ + case SPEED_2500: + adv |= ADVERTISE_2500_FULL; + /* Fall through */ + default: + adv |= (ADVERTISE_10_HALF | ADVERTISE_10_FULL | + ADVERTISE_100_HALF | ADVERTISE_100_FULL | + ADVERTISE_1000_HALF | ADVERTISE_1000_FULL); + break; + } + + hw->autoneg = autoneg; + hw->speed = speed; + hw->duplex = duplex; + hw->advertising = adv; + hw->fcpause = fc; +} + +static void +rtl_init_software_variable(struct rtl_hw *hw) +{ + int tx_no_close_enable = 1; + unsigned int speed_mode = SPEED_5000; + unsigned int duplex_mode = DUPLEX_FULL; + unsigned int autoneg_mode = AUTONEG_ENABLE; + u8 tmp; + + switch (hw->mcfg) { + case CFG_METHOD_48: + case CFG_METHOD_49: + tmp = (u8)rtl_mac_ocp_read(hw, 0xD006); + if (tmp == 0x02 || tmp == 0x04) + hw->HwSuppDashVer = 2; + break; + case CFG_METHOD_54: + case CFG_METHOD_55: + hw->HwSuppDashVer = 4; + break; + default: + hw->HwSuppDashVer = 0; + break; + } + + switch (hw->mcfg) { + case CFG_METHOD_48: + case CFG_METHOD_49: + if (HW_DASH_SUPPORT_DASH(hw)) + hw->HwSuppOcpChannelVer = 2; + break; + case CFG_METHOD_54: + case CFG_METHOD_55: + hw->HwSuppOcpChannelVer = 2; + break; + } + + hw->AllowAccessDashOcp = rtl_is_allow_access_dash_ocp(hw); + + if (HW_DASH_SUPPORT_DASH(hw) && rtl_check_dash(hw)) + hw->DASH = 1; + else + hw->DASH = 0; + + if (HW_DASH_SUPPORT_TYPE_2(hw)) + hw->cmac_ioaddr = hw->mmio_addr; + + switch (hw->mcfg) { + case CFG_METHOD_48: + case CFG_METHOD_49: + hw->chipset_name = RTL8125A; + break; + case CFG_METHOD_50: + case CFG_METHOD_51: + hw->chipset_name = RTL8125B; + break; + case CFG_METHOD_52: + case CFG_METHOD_53: + hw->chipset_name = RTL8168KB; + break; + case CFG_METHOD_54: + case CFG_METHOD_55: + hw->chipset_name = RTL8125BP; + break; + case CFG_METHOD_56: + case CFG_METHOD_57: + hw->chipset_name = RTL8125D; + break; + case CFG_METHOD_69 ... CFG_METHOD_71: + hw->chipset_name = RTL8126A; + break; + default: + hw->chipset_name = UNKNOWN; + break; + } + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + hw->HwSuppNowIsOobVer = 1; + } + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + hw->HwSuppCheckPhyDisableModeVer = 3; + } + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_51: + case CFG_METHOD_54 ... CFG_METHOD_57: + hw->HwSuppMaxPhyLinkSpeed = 2500; + break; + case CFG_METHOD_69 ... CFG_METHOD_71: + hw->HwSuppMaxPhyLinkSpeed = 5000; + break; + default: + hw->HwSuppMaxPhyLinkSpeed = 1000; + break; + } + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_53: + hw->HwSuppTxNoCloseVer = 3; + break; + case CFG_METHOD_54 ... CFG_METHOD_57: + hw->HwSuppTxNoCloseVer = 6; + break; + case CFG_METHOD_69: + hw->HwSuppTxNoCloseVer = 4; + break; + case CFG_METHOD_70: + case CFG_METHOD_71: + hw->HwSuppTxNoCloseVer = 5; + break; + } + + switch (hw->HwSuppTxNoCloseVer) { + case 5: + case 6: + hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V4; + break; + case 4: + hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V3; + break; + case 3: + hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V2; + break; + default: + tx_no_close_enable = 0; + break; + } + + if (hw->HwSuppTxNoCloseVer > 0 && tx_no_close_enable == 1) + hw->EnableTxNoClose = TRUE; + + switch (hw->HwSuppTxNoCloseVer) { + case 4: + case 5: + hw->hw_clo_ptr_reg = HW_CLO_PTR0_8126; + hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8126; + break; + case 6: + hw->hw_clo_ptr_reg = HW_CLO_PTR0_8125BP; + hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8125BP; + break; + default: + hw->hw_clo_ptr_reg = HW_CLO_PTR0_8125; + hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8125; + break; + } + + switch (hw->mcfg) { + case CFG_METHOD_48: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_48; + break; + case CFG_METHOD_49: + case CFG_METHOD_52: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_49; + break; + case CFG_METHOD_50: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_50; + break; + case CFG_METHOD_51: + case CFG_METHOD_53: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_51; + break; + case CFG_METHOD_54: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_54; + break; + case CFG_METHOD_55: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_55; + break; + case CFG_METHOD_56: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_56; + break; + case CFG_METHOD_57: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_57; + break; + case CFG_METHOD_69: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_69; + break; + case CFG_METHOD_70: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_70; + break; + case CFG_METHOD_71: + hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_71; + break; + } + + if (hw->HwIcVerUnknown) { + hw->NotWrRamCodeToMicroP = TRUE; + hw->NotWrMcuPatchCode = TRUE; + } + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + hw->HwSuppMacMcuVer = 2; + break; + } + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + hw->MacMcuPageSize = RTL_MAC_MCU_PAGE_SIZE; + break; + } + + switch (hw->mcfg) { + case CFG_METHOD_49: + case CFG_METHOD_52: + if ((rtl_mac_ocp_read(hw, 0xD442) & BIT_5) && + (rtl_mdio_direct_read_phy_ocp(hw, 0xD068) & BIT_1)) + hw->RequirePhyMdiSwapPatch = TRUE; + break; + } + + switch (hw->mcfg) { + case CFG_METHOD_48: + case CFG_METHOD_49: + case CFG_METHOD_52: + hw->HwSuppIntMitiVer = 3; + break; + case CFG_METHOD_50: + case CFG_METHOD_51: + case CFG_METHOD_53: + case CFG_METHOD_69: + hw->HwSuppIntMitiVer = 4; + break; + case CFG_METHOD_54 ... CFG_METHOD_57: + hw->HwSuppIntMitiVer = 6; + break; + case CFG_METHOD_70: + case CFG_METHOD_71: + hw->HwSuppIntMitiVer = 5; + break; + } + + rtl_set_link_option(hw, autoneg_mode, speed_mode, duplex_mode, rtl_fc_full); + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + hw->mcu_pme_setting = rtl_mac_ocp_read(hw, 0xE00A); + break; + } + + hw->mtu = RTL_DEFAULT_MTU; +} + +static void +rtl_exit_realwow(struct rtl_hw *hw) +{ + /* Disable realwow function */ + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + rtl_mac_ocp_write(hw, 0xC0BC, 0x00FF); + break; + } +} + +static void +rtl_disable_now_is_oob(struct rtl_hw *hw) +{ + if (hw->HwSuppNowIsOobVer == 1) + RTL_W8(hw, MCUCmd_reg, RTL_R8(hw, MCUCmd_reg) & ~Now_is_oob); +} + +static void +rtl_wait_ll_share_fifo_ready(struct rtl_hw *hw) +{ + int i; + + for (i = 0; i < 10; i++) { + udelay(100); + if (RTL_R16(hw, 0xD2) & BIT_9) + break; + } +} + +static void +rtl_exit_oob(struct rtl_hw *hw) +{ + u16 data16; + + rtl_disable_rx_packet_filter(hw); + + //if (HW_DASH_SUPPORT_DASH(hw)) { + // rtl_driver_start(hw); + // rtl_dash2_disable_txrx(hw); + //} + + rtl_exit_realwow(hw); + + rtl_nic_reset(hw); + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + rtl_disable_now_is_oob(hw); + + data16 = rtl_mac_ocp_read(hw, 0xE8DE) & ~BIT_14; + rtl_mac_ocp_write(hw, 0xE8DE, data16); + rtl_wait_ll_share_fifo_ready(hw); + + rtl_mac_ocp_write(hw, 0xC0AA, 0x07D0); + + rtl_mac_ocp_write(hw, 0xC0A6, 0x01B5); + + rtl_mac_ocp_write(hw, 0xC01E, 0x5555); + + rtl_wait_ll_share_fifo_ready(hw); + break; + } +} + +static void +rtl_disable_ups(struct rtl_hw *hw) +{ + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + rtl_mac_ocp_write(hw, 0xD40A, rtl_mac_ocp_read(hw, 0xD40A) & ~BIT_4); + break; + } +} + +static void +rtl8125_disable_ocp_phy_power_saving(struct rtl_hw *hw) +{ + u16 val; + + if (hw->mcfg == CFG_METHOD_48 || hw->mcfg == CFG_METHOD_49 || + hw->mcfg == CFG_METHOD_52) { + val = rtl_mdio_direct_read_phy_ocp(hw, 0xC416); + if (val != 0x0050) { + rtl_set_phy_mcu_patch_request(hw); + rtl_mdio_direct_write_phy_ocp(hw, 0xC416, 0x0000); + rtl_mdio_direct_write_phy_ocp(hw, 0xC416, 0x0500); + rtl_clear_phy_mcu_patch_request(hw); + } + } +} + +static void +rtl_hw_init(struct rtl_hw *hw) +{ + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + rtl_enable_aspm_clkreq_lock(hw, 0); + rtl_enable_force_clkreq(hw, 0); + break; + } + + rtl_disable_ups(hw); + + hw->hw_ops.hw_mac_mcu_config(hw); + + /* Disable ocp phy power saving */ + rtl8125_disable_ocp_phy_power_saving(hw); +} + +void +rtl_hw_initialize(struct rtl_hw *hw) +{ + rtl_init_software_variable(hw); + + rtl_exit_oob(hw); + + rtl_hw_init(hw); + + rtl_nic_reset(hw); +} + +void +rtl_get_mac_version(struct rtl_hw *hw, struct rte_pci_device *pci_dev) +{ + u32 reg, val32; + u32 ic_version_id; + + val32 = RTL_R32(hw, TxConfig); + reg = val32 & 0x7c800000; + ic_version_id = val32 & 0x00700000; + + switch (reg) { + case 0x60800000: + if (ic_version_id == 0x00000000) + hw->mcfg = CFG_METHOD_48; + + else if (ic_version_id == 0x100000) + hw->mcfg = CFG_METHOD_49; + + else { + hw->mcfg = CFG_METHOD_49; + hw->HwIcVerUnknown = TRUE; + } + + hw->efuse_ver = EFUSE_SUPPORT_V4; + break; + case 0x64000000: + if (ic_version_id == 0x00000000) + hw->mcfg = CFG_METHOD_50; + + else if (ic_version_id == 0x100000) + hw->mcfg = CFG_METHOD_51; + + else { + hw->mcfg = CFG_METHOD_51; + hw->HwIcVerUnknown = TRUE; + } + + hw->efuse_ver = EFUSE_SUPPORT_V4; + break; + case 0x68000000: + if (ic_version_id == 0x00000000) + hw->mcfg = CFG_METHOD_54; + else if (ic_version_id == 0x100000) + hw->mcfg = CFG_METHOD_55; + else { + hw->mcfg = CFG_METHOD_55; + hw->HwIcVerUnknown = TRUE; + } + + hw->efuse_ver = EFUSE_SUPPORT_V4; + break; + case 0x68800000: + if (ic_version_id == 0x00000000) + hw->mcfg = CFG_METHOD_56; + else if (ic_version_id == 0x100000) + hw->mcfg = CFG_METHOD_57; + else { + hw->mcfg = CFG_METHOD_57; + hw->HwIcVerUnknown = TRUE; + } + + hw->efuse_ver = EFUSE_SUPPORT_V4; + break; + case 0x64800000: + if (ic_version_id == 0x00000000) + hw->mcfg = CFG_METHOD_69; + else if (ic_version_id == 0x100000) + hw->mcfg = CFG_METHOD_70; + else if (ic_version_id == 0x200000) + hw->mcfg = CFG_METHOD_71; + else { + hw->mcfg = CFG_METHOD_71; + hw->HwIcVerUnknown = TRUE; + } + + hw->efuse_ver = EFUSE_SUPPORT_V4; + break; + default: + PMD_INIT_LOG(NOTICE, "unknown chip version (%x)", reg); + hw->mcfg = CFG_METHOD_DEFAULT; + hw->HwIcVerUnknown = TRUE; + hw->efuse_ver = EFUSE_NOT_SUPPORT; + break; + } + + if (pci_dev->id.device_id == 0x8162) { + if (hw->mcfg == CFG_METHOD_49) + hw->mcfg = CFG_METHOD_52; + else if (hw->mcfg == CFG_METHOD_51) + hw->mcfg = CFG_METHOD_53; + } +} + +int +rtl_get_mac_address(struct rtl_hw *hw, struct rte_ether_addr *ea) +{ + u8 mac_addr[MAC_ADDR_LEN]; + + switch (hw->mcfg) { + case CFG_METHOD_48 ... CFG_METHOD_57: + case CFG_METHOD_69 ... CFG_METHOD_71: + *(u32 *)&mac_addr[0] = RTL_R32(hw, BACKUP_ADDR0_8125); + *(u16 *)&mac_addr[4] = RTL_R16(hw, BACKUP_ADDR1_8125); + break; + default: + break; + } + + rte_ether_addr_copy((struct rte_ether_addr *)mac_addr, ea); + + return 0; +} + +void +rtl_rar_set(struct rtl_hw *hw, uint8_t *addr) +{ + uint32_t rar_low = 0; + uint32_t rar_high = 0; + + rar_low = ((uint32_t)addr[0] | ((uint32_t)addr[1] << 8) | + ((uint32_t)addr[2] << 16) | ((uint32_t)addr[3] << 24)); + + rar_high = ((uint32_t)addr[4] | ((uint32_t)addr[5] << 8)); + + rtl_enable_cfg9346_write(hw); + + RTL_W32(hw, MAC0, rar_low); + RTL_W32(hw, MAC4, rar_high); + + rtl_disable_cfg9346_write(hw); +} + diff --git a/drivers/net/r8169/r8169_hw.h b/drivers/net/r8169/r8169_hw.h index 8fd48a3077..3746b46084 100644 --- a/drivers/net/r8169/r8169_hw.h +++ b/drivers/net/r8169/r8169_hw.h @@ -42,6 +42,15 @@ void rtl_hw_disable_mac_mcu_bps(struct rtl_hw *hw); void rtl_write_mac_mcu_ram_code(struct rtl_hw *hw, const u16 *entry, u16 entry_cnt); +void rtl_hw_initialize(struct rtl_hw *hw); + +bool rtl_is_speed_mode_valid(u32 speed); + +void rtl_get_mac_version(struct rtl_hw *hw, struct rte_pci_device *pci_dev); +int rtl_get_mac_address(struct rtl_hw *hw, struct rte_ether_addr *ea); + +void rtl_rar_set(struct rtl_hw *hw, uint8_t *addr); + extern const struct rtl_hw_ops rtl8125a_ops; extern const struct rtl_hw_ops rtl8125b_ops; extern const struct rtl_hw_ops rtl8125bp_ops; @@ -60,5 +69,38 @@ extern const struct rtl_hw_ops rtl8126a_ops; #define HW_SUPPORT_MAC_MCU(_M) ((_M)->HwSuppMacMcuVer > 0) #define HW_HAS_WRITE_PHY_MCU_RAM_CODE(_M) (((_M)->HwHasWrRamCodeToMicroP == TRUE) ? 1 : 0) +/* Tx NO CLOSE */ +#define MAX_TX_NO_CLOSE_DESC_PTR_V2 0x10000 +#define MAX_TX_NO_CLOSE_DESC_PTR_MASK_V2 0xFFFF +#define MAX_TX_NO_CLOSE_DESC_PTR_V3 0x100000000 +#define MAX_TX_NO_CLOSE_DESC_PTR_MASK_V3 0xFFFFFFFF +#define MAX_TX_NO_CLOSE_DESC_PTR_V4 0x80000000 +#define MAX_TX_NO_CLOSE_DESC_PTR_MASK_V4 0x7FFFFFFF +#define TX_NO_CLOSE_SW_PTR_MASK_V2 0x1FFFF + +/* Ram code version */ +#define NIC_RAMCODE_VERSION_CFG_METHOD_48 (0x0b11) +#define NIC_RAMCODE_VERSION_CFG_METHOD_49 (0x0b33) +#define NIC_RAMCODE_VERSION_CFG_METHOD_50 (0x0b17) +#define NIC_RAMCODE_VERSION_CFG_METHOD_51 (0x0b99) +#define NIC_RAMCODE_VERSION_CFG_METHOD_54 (0x0013) +#define NIC_RAMCODE_VERSION_CFG_METHOD_55 (0x0001) +#define NIC_RAMCODE_VERSION_CFG_METHOD_56 (0x0016) +#define NIC_RAMCODE_VERSION_CFG_METHOD_57 (0x0001) +#define NIC_RAMCODE_VERSION_CFG_METHOD_69 (0x0023) +#define NIC_RAMCODE_VERSION_CFG_METHOD_70 (0x0033) +#define NIC_RAMCODE_VERSION_CFG_METHOD_71 (0x0051) + +#define RTL_MAC_MCU_PAGE_SIZE 256 +#define RTL_DEFAULT_MTU 1500 + +enum effuse { + EFUSE_NOT_SUPPORT = 0, + EFUSE_SUPPORT_V1, + EFUSE_SUPPORT_V2, + EFUSE_SUPPORT_V3, + EFUSE_SUPPORT_V4, +}; + #endif diff --git a/drivers/net/r8169/r8169_phy.h b/drivers/net/r8169/r8169_phy.h index f4da9f50ed..599a8957c4 100644 --- a/drivers/net/r8169/r8169_phy.h +++ b/drivers/net/r8169/r8169_phy.h @@ -20,17 +20,17 @@ #define MII_PHYSID1 0x02 /* PHYS ID 1 */ #define MII_PHYSID2 0x03 /* PHYS ID 2 */ #define MII_ADVERTISE 0x04 /* Advertisement control reg */ -#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ #define MII_EXPANSION 0x06 /* Expansion register */ #define MII_CTRL1000 0x09 /* 1000BASE-T control */ #define MII_STAT1000 0x0a /* 1000BASE-T status */ -#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */ -#define MII_MMD_DATA 0x0e /* MMD Access Data Register */ +#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */ +#define MII_MMD_DATA 0x0e /* MMD Access Data Register */ #define MII_ESTATUS 0x0f /* Extended Status */ #define MII_DCOUNTER 0x12 /* Disconnect counter */ #define MII_FCSCOUNTER 0x13 /* False carrier counter */ #define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ -#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ #define MII_SREVISION 0x16 /* Silicon revision */ #define MII_RESV1 0x17 /* Reserved... */ #define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ @@ -80,14 +80,14 @@ #define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ #define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ #define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ -#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ +#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ #define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ #define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ #define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ #define ADVERTISE_RESV 0x1000 /* Unused... */ #define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ -#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ -#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ /* 1000BASE-T Control register */ #define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ @@ -95,7 +95,7 @@ #define RTK_ADVERTISE_2500FULL 0x80 #define RTK_ADVERTISE_5000FULL 0x100 -#define RTK_ADVERTISE_10000FULL 0x1000 +#define RTK_ADVERTISE_10000FULL 0x1000 #define RTK_LPA_ADVERTISE_2500FULL 0x20 #define RTK_LPA_ADVERTISE_5000FULL 0x40 #define RTK_LPA_ADVERTISE_10000FULL 0x800 -- 2.34.1