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 0D7DF45CA6; Fri, 8 Nov 2024 13:13:36 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7AB564338A; Fri, 8 Nov 2024 13:13:31 +0100 (CET) Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by mails.dpdk.org (Postfix) with ESMTP id 7D5C64339C for ; Fri, 8 Nov 2024 13:13:29 +0100 (CET) X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 4A8CDRdD41901963, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=realsil.com.cn; s=dkim; t=1731068007; bh=z6IxeqiqFGJfMLhM2Q2KaEBQK4U7yFc5fbAFyH9myRI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=UMCsSMLq8ovaWEm7aKEFpsSsCyaboVE+/GP2x4Gq3RhkiPIbmyzdRyPJfcTYjCR3O jY7AddMMG5EreYL+ToQ2wB/XgteVgRrzhG0GD0GlaseOR41HjKwQm19XdVbQpsAHs0 GfzNqu7zhwduaZ0DH3nqinh5ksFjb4aK76MTErm0VNPHNd/uLnRhXDn3hSBdLFlwUN gZ4TJKtsQpMXMhSsEZ87alwhYyZLW06/euB71953Pb5cwnSX7hKhLqHQGi6aOc4nlX P6IH27MKO7X40kOJKYWkIhmi9NqcVujpyfHZKJURFnxozhw5ww9eTbIhZF58SwwOgM YmVQ3Ag+qNKgw== Received: from RSEXH36501.realsil.com.cn (rsl1.realsil.com.cn[172.29.17.2]) by rtits2.realtek.com.tw (8.15.2/3.06/5.92) with ESMTPS id 4A8CDRdD41901963 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Fri, 8 Nov 2024 20:13:27 +0800 Received: from RSEXDAG02.realsil.com.cn (172.29.17.196) by RSEXH36501.realsil.com.cn (172.29.17.2) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Fri, 8 Nov 2024 20:13:27 +0800 Received: from RSEXH36502.realsil.com.cn (172.29.17.3) by RSEXDAG02.realsil.com.cn (172.29.17.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Fri, 8 Nov 2024 20:13:27 +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; Fri, 8 Nov 2024 20:13:27 +0800 From: Howard Wang To: CC: , Howard Wang Subject: [PATCH v6 09/17] net/r8169: add support for hw initialization Date: Fri, 8 Nov 2024 20:11:15 +0800 Message-ID: <20241108121123.248797-10-howard_wang@realsil.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241108121123.248797-1-howard_wang@realsil.com.cn> References: <20241108121123.248797-1-howard_wang@realsil.com.cn> 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 This patch initializes software variables, resets the NIC, and performs other hw initialization tasks. Signed-off-by: Howard Wang --- drivers/net/r8169/meson.build | 1 + drivers/net/r8169/r8169_compat.h | 39 +++ drivers/net/r8169/r8169_dash.c | 86 +++++ drivers/net/r8169/r8169_dash.h | 33 ++ drivers/net/r8169/r8169_ethdev.c | 52 +++ drivers/net/r8169/r8169_ethdev.h | 30 +- drivers/net/r8169/r8169_hw.c | 583 +++++++++++++++++++++++++++++++ drivers/net/r8169/r8169_hw.h | 42 +++ drivers/net/r8169/r8169_phy.c | 1 - drivers/net/r8169/r8169_phy.h | 6 +- 10 files changed, 868 insertions(+), 5 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 664280edad..4612ab7883 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_compat.h b/drivers/net/r8169/r8169_compat.h index f9740f54b8..fa23f11843 100644 --- a/drivers/net/r8169/r8169_compat.h +++ b/drivers/net/r8169/r8169_compat.h @@ -232,6 +232,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, @@ -477,6 +481,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)) @@ -510,6 +524,31 @@ enum RTL_register_content { #define TRUE 1 #define FALSE 0 +#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 MAC_ADDR_LEN RTE_ETHER_ADDR_LEN + static inline u32 rtl_read32(void *addr) { diff --git a/drivers/net/r8169/r8169_dash.c b/drivers/net/r8169/r8169_dash.c new file mode 100644 index 0000000000..b6c5885642 --- /dev/null +++ b/drivers/net/r8169/r8169_dash.c @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 Realtek Corporation. All rights reserved + */ + +#include +#include +#include + +#include +#include + +#include "r8169_compat.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 (HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(hw) == FALSE) + 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) +{ + u32 ver; + + if (_rtl_check_dash(hw)) { + 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..41983b5db5 --- /dev/null +++ b/drivers/net/r8169/r8169_dash.h @@ -0,0 +1,33 @@ +/* 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_compat.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 717a5ca599..2f845ce1e6 100644 --- a/drivers/net/r8169/r8169_ethdev.c +++ b/drivers/net/r8169/r8169_ethdev.c @@ -3,16 +3,21 @@ */ #include +#include #include #include #include +#include +#include #include #include #include #include #include +#include +#include #include #include "r8169_ethdev.h" @@ -96,6 +101,15 @@ rtl_dev_stop(struct rte_eth_dev *dev) struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); struct rtl_hw *hw = &adapter->hw; + 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); return 0; @@ -107,6 +121,8 @@ rtl_dev_stop(struct rte_eth_dev *dev) static int rtl_dev_close(struct rte_eth_dev *dev) { + 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) @@ -114,14 +130,20 @@ rtl_dev_close(struct rte_eth_dev *dev) 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; } static int rtl_dev_init(struct rte_eth_dev *dev) { + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 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; + char buf[RTE_ETHER_ADDR_FMT_SIZE]; dev->dev_ops = &rtl_eth_dev_ops; dev->tx_pkt_burst = &rtl_xmit_pkts; @@ -131,9 +153,39 @@ rtl_dev_init(struct rte_eth_dev *dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; + 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]); + + rte_ether_format_addr(buf, sizeof(buf), perm_addr); + + PMD_INIT_LOG(NOTICE, "r8169: Assign randomly generated MAC address %s", buf); + } + + /* 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 ac7232c1ed..e1f5489973 100644 --- a/drivers/net/r8169/r8169_ethdev.h +++ b/drivers/net/r8169/r8169_ethdev.h @@ -22,13 +22,27 @@ 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 *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; @@ -42,10 +56,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 246f877c49..4db2f0040e 100644 --- a/drivers/net/r8169/r8169_hw.c +++ b/drivers/net/r8169/r8169_hw.c @@ -11,6 +11,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, @@ -917,3 +918,585 @@ rtl_write_mac_mcu_ram_code(struct rtl_hw *hw, const u16 *entry, u16 entry_cnt) else _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++) { + rte_delay_us(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); + + 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 fd31617e62..9519739740 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,4 +69,37 @@ 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.c b/drivers/net/r8169/r8169_phy.c index 5f41e11ee5..f5cd192d13 100644 --- a/drivers/net/r8169/r8169_phy.c +++ b/drivers/net/r8169/r8169_phy.c @@ -14,7 +14,6 @@ #include "r8169_phy.h" #include "r8169_logs.h" - static void rtl_clear_set_mac_ocp_bit(struct rtl_hw *hw, u16 addr, u16 clearmask, u16 setmask) diff --git a/drivers/net/r8169/r8169_phy.h b/drivers/net/r8169/r8169_phy.h index 4cd715f023..e923b5e94e 100644 --- a/drivers/net/r8169/r8169_phy.h +++ b/drivers/net/r8169/r8169_phy.h @@ -24,8 +24,8 @@ #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 */ @@ -80,7 +80,7 @@ #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 */ -- 2.34.1