125e992a4SHeiner Kallweit // SPDX-License-Identifier: GPL-2.0-only 225e992a4SHeiner Kallweit /* 325e992a4SHeiner Kallweit * r8169.c: RealTek 8169/8168/8101 ethernet driver. 425e992a4SHeiner Kallweit * 525e992a4SHeiner Kallweit * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw> 625e992a4SHeiner Kallweit * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com> 725e992a4SHeiner Kallweit * Copyright (c) a lot of people too. Please respect their work. 825e992a4SHeiner Kallweit * 925e992a4SHeiner Kallweit * See MAINTAINERS file for support contact information. 1025e992a4SHeiner Kallweit */ 1125e992a4SHeiner Kallweit 1225e992a4SHeiner Kallweit #include <linux/module.h> 1325e992a4SHeiner Kallweit #include <linux/pci.h> 1425e992a4SHeiner Kallweit #include <linux/netdevice.h> 1525e992a4SHeiner Kallweit #include <linux/etherdevice.h> 1625e992a4SHeiner Kallweit #include <linux/clk.h> 1725e992a4SHeiner Kallweit #include <linux/delay.h> 1825e992a4SHeiner Kallweit #include <linux/ethtool.h> 1925e992a4SHeiner Kallweit #include <linux/phy.h> 2025e992a4SHeiner Kallweit #include <linux/if_vlan.h> 2125e992a4SHeiner Kallweit #include <linux/in.h> 2225e992a4SHeiner Kallweit #include <linux/io.h> 2325e992a4SHeiner Kallweit #include <linux/ip.h> 2425e992a4SHeiner Kallweit #include <linux/tcp.h> 2525e992a4SHeiner Kallweit #include <linux/interrupt.h> 2625e992a4SHeiner Kallweit #include <linux/dma-mapping.h> 2725e992a4SHeiner Kallweit #include <linux/pm_runtime.h> 286cf96dd4SHeiner Kallweit #include <linux/bitfield.h> 2925e992a4SHeiner Kallweit #include <linux/prefetch.h> 3025e992a4SHeiner Kallweit #include <linux/ipv6.h> 3125e992a4SHeiner Kallweit #include <net/ip6_checksum.h> 3225e992a4SHeiner Kallweit 332992bdfaSHeiner Kallweit #include "r8169.h" 348197f9d2SHeiner Kallweit #include "r8169_firmware.h" 358197f9d2SHeiner Kallweit 3625e992a4SHeiner Kallweit #define MODULENAME "r8169" 3725e992a4SHeiner Kallweit 3825e992a4SHeiner Kallweit #define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw" 3925e992a4SHeiner Kallweit #define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw" 4025e992a4SHeiner Kallweit #define FIRMWARE_8168E_1 "rtl_nic/rtl8168e-1.fw" 4125e992a4SHeiner Kallweit #define FIRMWARE_8168E_2 "rtl_nic/rtl8168e-2.fw" 4225e992a4SHeiner Kallweit #define FIRMWARE_8168E_3 "rtl_nic/rtl8168e-3.fw" 4325e992a4SHeiner Kallweit #define FIRMWARE_8168F_1 "rtl_nic/rtl8168f-1.fw" 4425e992a4SHeiner Kallweit #define FIRMWARE_8168F_2 "rtl_nic/rtl8168f-2.fw" 4525e992a4SHeiner Kallweit #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" 4625e992a4SHeiner Kallweit #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" 4725e992a4SHeiner Kallweit #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" 4825e992a4SHeiner Kallweit #define FIRMWARE_8411_2 "rtl_nic/rtl8411-2.fw" 4925e992a4SHeiner Kallweit #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" 5025e992a4SHeiner Kallweit #define FIRMWARE_8106E_2 "rtl_nic/rtl8106e-2.fw" 5125e992a4SHeiner Kallweit #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" 5225e992a4SHeiner Kallweit #define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw" 5325e992a4SHeiner Kallweit #define FIRMWARE_8168H_1 "rtl_nic/rtl8168h-1.fw" 5425e992a4SHeiner Kallweit #define FIRMWARE_8168H_2 "rtl_nic/rtl8168h-2.fw" 55229c1e0dSHeiner Kallweit #define FIRMWARE_8168FP_3 "rtl_nic/rtl8168fp-3.fw" 5625e992a4SHeiner Kallweit #define FIRMWARE_8107E_1 "rtl_nic/rtl8107e-1.fw" 5725e992a4SHeiner Kallweit #define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw" 5802bf642bSHeiner Kallweit #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw" 5925e992a4SHeiner Kallweit 6025e992a4SHeiner Kallweit /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). 6125e992a4SHeiner Kallweit The RTL chips use a 64 element hash table based on the Ethernet CRC. */ 6281cd17a4SHeiner Kallweit #define MC_FILTER_LIMIT 32 6325e992a4SHeiner Kallweit 6425e992a4SHeiner Kallweit #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ 6525e992a4SHeiner Kallweit #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ 6625e992a4SHeiner Kallweit 6725e992a4SHeiner Kallweit #define R8169_REGS_SIZE 256 6825e992a4SHeiner Kallweit #define R8169_RX_BUF_SIZE (SZ_16K - 1) 6925e992a4SHeiner Kallweit #define NUM_TX_DESC 64 /* Number of Tx descriptor registers */ 7025e992a4SHeiner Kallweit #define NUM_RX_DESC 256U /* Number of Rx descriptor registers */ 7125e992a4SHeiner Kallweit #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) 7225e992a4SHeiner Kallweit #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) 7325e992a4SHeiner Kallweit 740360c046SHeiner Kallweit #define OCP_STD_PHY_BASE 0xa400 750360c046SHeiner Kallweit 76145a40e8SHeiner Kallweit #define RTL_CFG_NO_GBIT 1 77145a40e8SHeiner Kallweit 7825e992a4SHeiner Kallweit /* write/read MMIO register */ 7925e992a4SHeiner Kallweit #define RTL_W8(tp, reg, val8) writeb((val8), tp->mmio_addr + (reg)) 8025e992a4SHeiner Kallweit #define RTL_W16(tp, reg, val16) writew((val16), tp->mmio_addr + (reg)) 8125e992a4SHeiner Kallweit #define RTL_W32(tp, reg, val32) writel((val32), tp->mmio_addr + (reg)) 8225e992a4SHeiner Kallweit #define RTL_R8(tp, reg) readb(tp->mmio_addr + (reg)) 8325e992a4SHeiner Kallweit #define RTL_R16(tp, reg) readw(tp->mmio_addr + (reg)) 8425e992a4SHeiner Kallweit #define RTL_R32(tp, reg) readl(tp->mmio_addr + (reg)) 8525e992a4SHeiner Kallweit 86b410439cSHeiner Kallweit #define JUMBO_4K (4 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) 87b410439cSHeiner Kallweit #define JUMBO_6K (6 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) 88b410439cSHeiner Kallweit #define JUMBO_7K (7 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) 89b410439cSHeiner Kallweit #define JUMBO_9K (9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) 9025e992a4SHeiner Kallweit 9125e992a4SHeiner Kallweit static const struct { 9225e992a4SHeiner Kallweit const char *name; 9325e992a4SHeiner Kallweit const char *fw_name; 9425e992a4SHeiner Kallweit } rtl_chip_infos[] = { 9525e992a4SHeiner Kallweit /* PCI devices. */ 9625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_02] = {"RTL8169s" }, 9725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_03] = {"RTL8110s" }, 9825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_04] = {"RTL8169sb/8110sb" }, 9925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_05] = {"RTL8169sc/8110sc" }, 10025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_06] = {"RTL8169sc/8110sc" }, 10125e992a4SHeiner Kallweit /* PCI-E devices. */ 10225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_07] = {"RTL8102e" }, 10325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_08] = {"RTL8102e" }, 1049e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_09] = {"RTL8102e/RTL8103e" }, 10525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_10] = {"RTL8101e" }, 10625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_11] = {"RTL8168b/8111b" }, 10725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_12] = {"RTL8168b/8111b" }, 10825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_13] = {"RTL8101e" }, 10925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_14] = {"RTL8100e" }, 11025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_15] = {"RTL8100e" }, 11125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_16] = {"RTL8101e" }, 11225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b" }, 11325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp" }, 11425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_19] = {"RTL8168c/8111c" }, 11525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_20] = {"RTL8168c/8111c" }, 11625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_21] = {"RTL8168c/8111c" }, 11725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_22] = {"RTL8168c/8111c" }, 11825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_23] = {"RTL8168cp/8111cp" }, 11925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_24] = {"RTL8168cp/8111cp" }, 12025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_25] = {"RTL8168d/8111d", FIRMWARE_8168D_1}, 12125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_26] = {"RTL8168d/8111d", FIRMWARE_8168D_2}, 12225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_27] = {"RTL8168dp/8111dp" }, 12325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_28] = {"RTL8168dp/8111dp" }, 12425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_29] = {"RTL8105e", FIRMWARE_8105E_1}, 12525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_30] = {"RTL8105e", FIRMWARE_8105E_1}, 12625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_31] = {"RTL8168dp/8111dp" }, 12725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_32] = {"RTL8168e/8111e", FIRMWARE_8168E_1}, 12825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_33] = {"RTL8168e/8111e", FIRMWARE_8168E_2}, 12925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_34] = {"RTL8168evl/8111evl", FIRMWARE_8168E_3}, 13025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_35] = {"RTL8168f/8111f", FIRMWARE_8168F_1}, 13125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_36] = {"RTL8168f/8111f", FIRMWARE_8168F_2}, 13225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_37] = {"RTL8402", FIRMWARE_8402_1 }, 13325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_38] = {"RTL8411", FIRMWARE_8411_1 }, 13425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_39] = {"RTL8106e", FIRMWARE_8106E_1}, 13525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_40] = {"RTL8168g/8111g", FIRMWARE_8168G_2}, 13625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_41] = {"RTL8168g/8111g" }, 1379e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_42] = {"RTL8168gu/8111gu", FIRMWARE_8168G_3}, 1389e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_43] = {"RTL8106eus", FIRMWARE_8106E_2}, 1399e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_44] = {"RTL8411b", FIRMWARE_8411_2 }, 14025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_45] = {"RTL8168h/8111h", FIRMWARE_8168H_1}, 14125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_46] = {"RTL8168h/8111h", FIRMWARE_8168H_2}, 14225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_47] = {"RTL8107e", FIRMWARE_8107E_1}, 14325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_48] = {"RTL8107e", FIRMWARE_8107E_2}, 14425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_49] = {"RTL8168ep/8111ep" }, 14525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_50] = {"RTL8168ep/8111ep" }, 14625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep" }, 147229c1e0dSHeiner Kallweit [RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117", FIRMWARE_8168FP_3}, 148f1bce4adSHeiner Kallweit [RTL_GIGA_MAC_VER_60] = {"RTL8125" }, 14902bf642bSHeiner Kallweit [RTL_GIGA_MAC_VER_61] = {"RTL8125", FIRMWARE_8125A_3}, 15025e992a4SHeiner Kallweit }; 15125e992a4SHeiner Kallweit 15225e992a4SHeiner Kallweit static const struct pci_device_id rtl8169_pci_tbl[] = { 153145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x2502) }, 154145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x2600) }, 155145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8129) }, 156145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_NO_GBIT }, 157145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8161) }, 158145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8167) }, 159145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8168) }, 160145a40e8SHeiner Kallweit { PCI_VDEVICE(NCUBE, 0x8168) }, 161145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8169) }, 16225e992a4SHeiner Kallweit { PCI_VENDOR_ID_DLINK, 0x4300, 163145a40e8SHeiner Kallweit PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0 }, 1649d9f3fbaSHeiner Kallweit { PCI_VDEVICE(DLINK, 0x4300) }, 1659d9f3fbaSHeiner Kallweit { PCI_VDEVICE(DLINK, 0x4302) }, 1669d9f3fbaSHeiner Kallweit { PCI_VDEVICE(AT, 0xc107) }, 1679d9f3fbaSHeiner Kallweit { PCI_VDEVICE(USR, 0x0116) }, 1689d9f3fbaSHeiner Kallweit { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 }, 1699d9f3fbaSHeiner Kallweit { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 }, 170f1bce4adSHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8125) }, 171f1bce4adSHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x3000) }, 17225e992a4SHeiner Kallweit {} 17325e992a4SHeiner Kallweit }; 17425e992a4SHeiner Kallweit 17525e992a4SHeiner Kallweit MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); 17625e992a4SHeiner Kallweit 17725e992a4SHeiner Kallweit enum rtl_registers { 17825e992a4SHeiner Kallweit MAC0 = 0, /* Ethernet hardware address. */ 17925e992a4SHeiner Kallweit MAC4 = 4, 18025e992a4SHeiner Kallweit MAR0 = 8, /* Multicast filter. */ 18125e992a4SHeiner Kallweit CounterAddrLow = 0x10, 18225e992a4SHeiner Kallweit CounterAddrHigh = 0x14, 18325e992a4SHeiner Kallweit TxDescStartAddrLow = 0x20, 18425e992a4SHeiner Kallweit TxDescStartAddrHigh = 0x24, 18525e992a4SHeiner Kallweit TxHDescStartAddrLow = 0x28, 18625e992a4SHeiner Kallweit TxHDescStartAddrHigh = 0x2c, 18725e992a4SHeiner Kallweit FLASH = 0x30, 18825e992a4SHeiner Kallweit ERSR = 0x36, 18925e992a4SHeiner Kallweit ChipCmd = 0x37, 19025e992a4SHeiner Kallweit TxPoll = 0x38, 19125e992a4SHeiner Kallweit IntrMask = 0x3c, 19225e992a4SHeiner Kallweit IntrStatus = 0x3e, 19325e992a4SHeiner Kallweit 19425e992a4SHeiner Kallweit TxConfig = 0x40, 19525e992a4SHeiner Kallweit #define TXCFG_AUTO_FIFO (1 << 7) /* 8111e-vl */ 19625e992a4SHeiner Kallweit #define TXCFG_EMPTY (1 << 11) /* 8111e-vl */ 19725e992a4SHeiner Kallweit 19825e992a4SHeiner Kallweit RxConfig = 0x44, 19925e992a4SHeiner Kallweit #define RX128_INT_EN (1 << 15) /* 8111c and later */ 20025e992a4SHeiner Kallweit #define RX_MULTI_EN (1 << 14) /* 8111c only */ 20125e992a4SHeiner Kallweit #define RXCFG_FIFO_SHIFT 13 20225e992a4SHeiner Kallweit /* No threshold before first PCI xfer */ 20325e992a4SHeiner Kallweit #define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) 20425e992a4SHeiner Kallweit #define RX_EARLY_OFF (1 << 11) 20525e992a4SHeiner Kallweit #define RXCFG_DMA_SHIFT 8 20625e992a4SHeiner Kallweit /* Unlimited maximum PCI burst. */ 20725e992a4SHeiner Kallweit #define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) 20825e992a4SHeiner Kallweit 20925e992a4SHeiner Kallweit Cfg9346 = 0x50, 21025e992a4SHeiner Kallweit Config0 = 0x51, 21125e992a4SHeiner Kallweit Config1 = 0x52, 21225e992a4SHeiner Kallweit Config2 = 0x53, 21325e992a4SHeiner Kallweit #define PME_SIGNAL (1 << 5) /* 8168c and later */ 21425e992a4SHeiner Kallweit 21525e992a4SHeiner Kallweit Config3 = 0x54, 21625e992a4SHeiner Kallweit Config4 = 0x55, 21725e992a4SHeiner Kallweit Config5 = 0x56, 21825e992a4SHeiner Kallweit PHYAR = 0x60, 21925e992a4SHeiner Kallweit PHYstatus = 0x6c, 22025e992a4SHeiner Kallweit RxMaxSize = 0xda, 22125e992a4SHeiner Kallweit CPlusCmd = 0xe0, 22225e992a4SHeiner Kallweit IntrMitigate = 0xe2, 22325e992a4SHeiner Kallweit 2246cf96dd4SHeiner Kallweit #define RTL_COALESCE_TX_USECS GENMASK(15, 12) 2256cf96dd4SHeiner Kallweit #define RTL_COALESCE_TX_FRAMES GENMASK(11, 8) 2266cf96dd4SHeiner Kallweit #define RTL_COALESCE_RX_USECS GENMASK(7, 4) 2276cf96dd4SHeiner Kallweit #define RTL_COALESCE_RX_FRAMES GENMASK(3, 0) 2286cf96dd4SHeiner Kallweit 2292b3e48b6SHeiner Kallweit #define RTL_COALESCE_T_MAX 0x0fU 2302b3e48b6SHeiner Kallweit #define RTL_COALESCE_FRAME_MAX (RTL_COALESCE_T_MAX * 4) 23125e992a4SHeiner Kallweit 23225e992a4SHeiner Kallweit RxDescAddrLow = 0xe4, 23325e992a4SHeiner Kallweit RxDescAddrHigh = 0xe8, 23425e992a4SHeiner Kallweit EarlyTxThres = 0xec, /* 8169. Unit of 32 bytes. */ 23525e992a4SHeiner Kallweit 23625e992a4SHeiner Kallweit #define NoEarlyTx 0x3f /* Max value : no early transmit. */ 23725e992a4SHeiner Kallweit 23825e992a4SHeiner Kallweit MaxTxPacketSize = 0xec, /* 8101/8168. Unit of 128 bytes. */ 23925e992a4SHeiner Kallweit 24025e992a4SHeiner Kallweit #define TxPacketMax (8064 >> 7) 24125e992a4SHeiner Kallweit #define EarlySize 0x27 24225e992a4SHeiner Kallweit 24325e992a4SHeiner Kallweit FuncEvent = 0xf0, 24425e992a4SHeiner Kallweit FuncEventMask = 0xf4, 24525e992a4SHeiner Kallweit FuncPresetState = 0xf8, 24625e992a4SHeiner Kallweit IBCR0 = 0xf8, 24725e992a4SHeiner Kallweit IBCR2 = 0xf9, 24825e992a4SHeiner Kallweit IBIMR0 = 0xfa, 24925e992a4SHeiner Kallweit IBISR0 = 0xfb, 25025e992a4SHeiner Kallweit FuncForceEvent = 0xfc, 25125e992a4SHeiner Kallweit }; 25225e992a4SHeiner Kallweit 25325e992a4SHeiner Kallweit enum rtl8168_8101_registers { 25425e992a4SHeiner Kallweit CSIDR = 0x64, 25525e992a4SHeiner Kallweit CSIAR = 0x68, 25625e992a4SHeiner Kallweit #define CSIAR_FLAG 0x80000000 25725e992a4SHeiner Kallweit #define CSIAR_WRITE_CMD 0x80000000 25825e992a4SHeiner Kallweit #define CSIAR_BYTE_ENABLE 0x0000f000 25925e992a4SHeiner Kallweit #define CSIAR_ADDR_MASK 0x00000fff 26025e992a4SHeiner Kallweit PMCH = 0x6f, 26125e992a4SHeiner Kallweit EPHYAR = 0x80, 26225e992a4SHeiner Kallweit #define EPHYAR_FLAG 0x80000000 26325e992a4SHeiner Kallweit #define EPHYAR_WRITE_CMD 0x80000000 26425e992a4SHeiner Kallweit #define EPHYAR_REG_MASK 0x1f 26525e992a4SHeiner Kallweit #define EPHYAR_REG_SHIFT 16 26625e992a4SHeiner Kallweit #define EPHYAR_DATA_MASK 0xffff 26725e992a4SHeiner Kallweit DLLPR = 0xd0, 26825e992a4SHeiner Kallweit #define PFM_EN (1 << 6) 26925e992a4SHeiner Kallweit #define TX_10M_PS_EN (1 << 7) 27025e992a4SHeiner Kallweit DBG_REG = 0xd1, 27125e992a4SHeiner Kallweit #define FIX_NAK_1 (1 << 4) 27225e992a4SHeiner Kallweit #define FIX_NAK_2 (1 << 3) 27325e992a4SHeiner Kallweit TWSI = 0xd2, 27425e992a4SHeiner Kallweit MCU = 0xd3, 27525e992a4SHeiner Kallweit #define NOW_IS_OOB (1 << 7) 27625e992a4SHeiner Kallweit #define TX_EMPTY (1 << 5) 27725e992a4SHeiner Kallweit #define RX_EMPTY (1 << 4) 27825e992a4SHeiner Kallweit #define RXTX_EMPTY (TX_EMPTY | RX_EMPTY) 27925e992a4SHeiner Kallweit #define EN_NDP (1 << 3) 28025e992a4SHeiner Kallweit #define EN_OOB_RESET (1 << 2) 28125e992a4SHeiner Kallweit #define LINK_LIST_RDY (1 << 1) 28225e992a4SHeiner Kallweit EFUSEAR = 0xdc, 28325e992a4SHeiner Kallweit #define EFUSEAR_FLAG 0x80000000 28425e992a4SHeiner Kallweit #define EFUSEAR_WRITE_CMD 0x80000000 28525e992a4SHeiner Kallweit #define EFUSEAR_READ_CMD 0x00000000 28625e992a4SHeiner Kallweit #define EFUSEAR_REG_MASK 0x03ff 28725e992a4SHeiner Kallweit #define EFUSEAR_REG_SHIFT 8 28825e992a4SHeiner Kallweit #define EFUSEAR_DATA_MASK 0xff 28925e992a4SHeiner Kallweit MISC_1 = 0xf2, 29025e992a4SHeiner Kallweit #define PFM_D3COLD_EN (1 << 6) 29125e992a4SHeiner Kallweit }; 29225e992a4SHeiner Kallweit 29325e992a4SHeiner Kallweit enum rtl8168_registers { 29425e992a4SHeiner Kallweit LED_FREQ = 0x1a, 29525e992a4SHeiner Kallweit EEE_LED = 0x1b, 29625e992a4SHeiner Kallweit ERIDR = 0x70, 29725e992a4SHeiner Kallweit ERIAR = 0x74, 29825e992a4SHeiner Kallweit #define ERIAR_FLAG 0x80000000 29925e992a4SHeiner Kallweit #define ERIAR_WRITE_CMD 0x80000000 30025e992a4SHeiner Kallweit #define ERIAR_READ_CMD 0x00000000 30125e992a4SHeiner Kallweit #define ERIAR_ADDR_BYTE_ALIGN 4 30225e992a4SHeiner Kallweit #define ERIAR_TYPE_SHIFT 16 30325e992a4SHeiner Kallweit #define ERIAR_EXGMAC (0x00 << ERIAR_TYPE_SHIFT) 30425e992a4SHeiner Kallweit #define ERIAR_MSIX (0x01 << ERIAR_TYPE_SHIFT) 30525e992a4SHeiner Kallweit #define ERIAR_ASF (0x02 << ERIAR_TYPE_SHIFT) 30625e992a4SHeiner Kallweit #define ERIAR_OOB (0x02 << ERIAR_TYPE_SHIFT) 30725e992a4SHeiner Kallweit #define ERIAR_MASK_SHIFT 12 30825e992a4SHeiner Kallweit #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) 30925e992a4SHeiner Kallweit #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) 31025e992a4SHeiner Kallweit #define ERIAR_MASK_0100 (0x4 << ERIAR_MASK_SHIFT) 31125e992a4SHeiner Kallweit #define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT) 31225e992a4SHeiner Kallweit #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) 31325e992a4SHeiner Kallweit EPHY_RXER_NUM = 0x7c, 31425e992a4SHeiner Kallweit OCPDR = 0xb0, /* OCP GPHY access */ 31525e992a4SHeiner Kallweit #define OCPDR_WRITE_CMD 0x80000000 31625e992a4SHeiner Kallweit #define OCPDR_READ_CMD 0x00000000 31725e992a4SHeiner Kallweit #define OCPDR_REG_MASK 0x7f 31825e992a4SHeiner Kallweit #define OCPDR_GPHY_REG_SHIFT 16 31925e992a4SHeiner Kallweit #define OCPDR_DATA_MASK 0xffff 32025e992a4SHeiner Kallweit OCPAR = 0xb4, 32125e992a4SHeiner Kallweit #define OCPAR_FLAG 0x80000000 32225e992a4SHeiner Kallweit #define OCPAR_GPHY_WRITE_CMD 0x8000f060 32325e992a4SHeiner Kallweit #define OCPAR_GPHY_READ_CMD 0x0000f060 32425e992a4SHeiner Kallweit GPHY_OCP = 0xb8, 32525e992a4SHeiner Kallweit RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ 32625e992a4SHeiner Kallweit MISC = 0xf0, /* 8168e only. */ 32725e992a4SHeiner Kallweit #define TXPLA_RST (1 << 29) 32825e992a4SHeiner Kallweit #define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */ 32925e992a4SHeiner Kallweit #define PWM_EN (1 << 22) 33025e992a4SHeiner Kallweit #define RXDV_GATED_EN (1 << 19) 33125e992a4SHeiner Kallweit #define EARLY_TALLY_EN (1 << 16) 33225e992a4SHeiner Kallweit }; 33325e992a4SHeiner Kallweit 334f1bce4adSHeiner Kallweit enum rtl8125_registers { 335f1bce4adSHeiner Kallweit IntrMask_8125 = 0x38, 336f1bce4adSHeiner Kallweit IntrStatus_8125 = 0x3c, 337f1bce4adSHeiner Kallweit TxPoll_8125 = 0x90, 338f1bce4adSHeiner Kallweit MAC0_BKP = 0x19e0, 339f1bce4adSHeiner Kallweit }; 340f1bce4adSHeiner Kallweit 341f1bce4adSHeiner Kallweit #define RX_VLAN_INNER_8125 BIT(22) 342f1bce4adSHeiner Kallweit #define RX_VLAN_OUTER_8125 BIT(23) 343f1bce4adSHeiner Kallweit #define RX_VLAN_8125 (RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125) 344f1bce4adSHeiner Kallweit 345f1bce4adSHeiner Kallweit #define RX_FETCH_DFLT_8125 (8 << 27) 346f1bce4adSHeiner Kallweit 34725e992a4SHeiner Kallweit enum rtl_register_content { 34825e992a4SHeiner Kallweit /* InterruptStatusBits */ 34925e992a4SHeiner Kallweit SYSErr = 0x8000, 35025e992a4SHeiner Kallweit PCSTimeout = 0x4000, 35125e992a4SHeiner Kallweit SWInt = 0x0100, 35225e992a4SHeiner Kallweit TxDescUnavail = 0x0080, 35325e992a4SHeiner Kallweit RxFIFOOver = 0x0040, 35425e992a4SHeiner Kallweit LinkChg = 0x0020, 35525e992a4SHeiner Kallweit RxOverflow = 0x0010, 35625e992a4SHeiner Kallweit TxErr = 0x0008, 35725e992a4SHeiner Kallweit TxOK = 0x0004, 35825e992a4SHeiner Kallweit RxErr = 0x0002, 35925e992a4SHeiner Kallweit RxOK = 0x0001, 36025e992a4SHeiner Kallweit 36125e992a4SHeiner Kallweit /* RxStatusDesc */ 36225e992a4SHeiner Kallweit RxRWT = (1 << 22), 36325e992a4SHeiner Kallweit RxRES = (1 << 21), 36425e992a4SHeiner Kallweit RxRUNT = (1 << 20), 36525e992a4SHeiner Kallweit RxCRC = (1 << 19), 36625e992a4SHeiner Kallweit 36725e992a4SHeiner Kallweit /* ChipCmdBits */ 36825e992a4SHeiner Kallweit StopReq = 0x80, 36925e992a4SHeiner Kallweit CmdReset = 0x10, 37025e992a4SHeiner Kallweit CmdRxEnb = 0x08, 37125e992a4SHeiner Kallweit CmdTxEnb = 0x04, 37225e992a4SHeiner Kallweit RxBufEmpty = 0x01, 37325e992a4SHeiner Kallweit 37425e992a4SHeiner Kallweit /* TXPoll register p.5 */ 37525e992a4SHeiner Kallweit HPQ = 0x80, /* Poll cmd on the high prio queue */ 37625e992a4SHeiner Kallweit NPQ = 0x40, /* Poll cmd on the low prio queue */ 37725e992a4SHeiner Kallweit FSWInt = 0x01, /* Forced software interrupt */ 37825e992a4SHeiner Kallweit 37925e992a4SHeiner Kallweit /* Cfg9346Bits */ 38025e992a4SHeiner Kallweit Cfg9346_Lock = 0x00, 38125e992a4SHeiner Kallweit Cfg9346_Unlock = 0xc0, 38225e992a4SHeiner Kallweit 38325e992a4SHeiner Kallweit /* rx_mode_bits */ 38425e992a4SHeiner Kallweit AcceptErr = 0x20, 38525e992a4SHeiner Kallweit AcceptRunt = 0x10, 38610478283SHeiner Kallweit #define RX_CONFIG_ACCEPT_ERR_MASK 0x30 38725e992a4SHeiner Kallweit AcceptBroadcast = 0x08, 38825e992a4SHeiner Kallweit AcceptMulticast = 0x04, 38925e992a4SHeiner Kallweit AcceptMyPhys = 0x02, 39025e992a4SHeiner Kallweit AcceptAllPhys = 0x01, 39110478283SHeiner Kallweit #define RX_CONFIG_ACCEPT_OK_MASK 0x0f 39225e992a4SHeiner Kallweit #define RX_CONFIG_ACCEPT_MASK 0x3f 39325e992a4SHeiner Kallweit 39425e992a4SHeiner Kallweit /* TxConfigBits */ 39525e992a4SHeiner Kallweit TxInterFrameGapShift = 24, 39625e992a4SHeiner Kallweit TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ 39725e992a4SHeiner Kallweit 39825e992a4SHeiner Kallweit /* Config1 register p.24 */ 39925e992a4SHeiner Kallweit LEDS1 = (1 << 7), 40025e992a4SHeiner Kallweit LEDS0 = (1 << 6), 40125e992a4SHeiner Kallweit Speed_down = (1 << 4), 40225e992a4SHeiner Kallweit MEMMAP = (1 << 3), 40325e992a4SHeiner Kallweit IOMAP = (1 << 2), 40425e992a4SHeiner Kallweit VPD = (1 << 1), 40525e992a4SHeiner Kallweit PMEnable = (1 << 0), /* Power Management Enable */ 40625e992a4SHeiner Kallweit 40725e992a4SHeiner Kallweit /* Config2 register p. 25 */ 40825e992a4SHeiner Kallweit ClkReqEn = (1 << 7), /* Clock Request Enable */ 40925e992a4SHeiner Kallweit MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ 41025e992a4SHeiner Kallweit PCI_Clock_66MHz = 0x01, 41125e992a4SHeiner Kallweit PCI_Clock_33MHz = 0x00, 41225e992a4SHeiner Kallweit 41325e992a4SHeiner Kallweit /* Config3 register p.25 */ 41425e992a4SHeiner Kallweit MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ 41525e992a4SHeiner Kallweit LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ 41625e992a4SHeiner Kallweit Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */ 41725e992a4SHeiner Kallweit Rdy_to_L23 = (1 << 1), /* L23 Enable */ 41825e992a4SHeiner Kallweit Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ 41925e992a4SHeiner Kallweit 42025e992a4SHeiner Kallweit /* Config4 register */ 42125e992a4SHeiner Kallweit Jumbo_En1 = (1 << 1), /* 8168 only. Reserved in the 8168b */ 42225e992a4SHeiner Kallweit 42325e992a4SHeiner Kallweit /* Config5 register p.27 */ 42425e992a4SHeiner Kallweit BWF = (1 << 6), /* Accept Broadcast wakeup frame */ 42525e992a4SHeiner Kallweit MWF = (1 << 5), /* Accept Multicast wakeup frame */ 42625e992a4SHeiner Kallweit UWF = (1 << 4), /* Accept Unicast wakeup frame */ 42725e992a4SHeiner Kallweit Spi_en = (1 << 3), 42825e992a4SHeiner Kallweit LanWake = (1 << 1), /* LanWake enable/disable */ 42925e992a4SHeiner Kallweit PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ 43025e992a4SHeiner Kallweit ASPM_en = (1 << 0), /* ASPM enable */ 43125e992a4SHeiner Kallweit 43225e992a4SHeiner Kallweit /* CPlusCmd p.31 */ 43325e992a4SHeiner Kallweit EnableBist = (1 << 15), // 8168 8101 43425e992a4SHeiner Kallweit Mac_dbgo_oe = (1 << 14), // 8168 8101 43509e65335SHeiner Kallweit EnAnaPLL = (1 << 14), // 8169 43625e992a4SHeiner Kallweit Normal_mode = (1 << 13), // unused 43725e992a4SHeiner Kallweit Force_half_dup = (1 << 12), // 8168 8101 43825e992a4SHeiner Kallweit Force_rxflow_en = (1 << 11), // 8168 8101 43925e992a4SHeiner Kallweit Force_txflow_en = (1 << 10), // 8168 8101 44025e992a4SHeiner Kallweit Cxpl_dbg_sel = (1 << 9), // 8168 8101 44125e992a4SHeiner Kallweit ASF = (1 << 8), // 8168 8101 44225e992a4SHeiner Kallweit PktCntrDisable = (1 << 7), // 8168 8101 44325e992a4SHeiner Kallweit Mac_dbgo_sel = 0x001c, // 8168 44425e992a4SHeiner Kallweit RxVlan = (1 << 6), 44525e992a4SHeiner Kallweit RxChkSum = (1 << 5), 44625e992a4SHeiner Kallweit PCIDAC = (1 << 4), 44725e992a4SHeiner Kallweit PCIMulRW = (1 << 3), 44825e992a4SHeiner Kallweit #define INTT_MASK GENMASK(1, 0) 449bc73241eSHeiner Kallweit #define CPCMD_MASK (Normal_mode | RxVlan | RxChkSum | INTT_MASK) 45025e992a4SHeiner Kallweit 45125e992a4SHeiner Kallweit /* rtl8169_PHYstatus */ 45225e992a4SHeiner Kallweit TBI_Enable = 0x80, 45325e992a4SHeiner Kallweit TxFlowCtrl = 0x40, 45425e992a4SHeiner Kallweit RxFlowCtrl = 0x20, 45525e992a4SHeiner Kallweit _1000bpsF = 0x10, 45625e992a4SHeiner Kallweit _100bps = 0x08, 45725e992a4SHeiner Kallweit _10bps = 0x04, 45825e992a4SHeiner Kallweit LinkStatus = 0x02, 45925e992a4SHeiner Kallweit FullDup = 0x01, 46025e992a4SHeiner Kallweit 46125e992a4SHeiner Kallweit /* ResetCounterCommand */ 46225e992a4SHeiner Kallweit CounterReset = 0x1, 46325e992a4SHeiner Kallweit 46425e992a4SHeiner Kallweit /* DumpCounterCommand */ 46525e992a4SHeiner Kallweit CounterDump = 0x8, 46625e992a4SHeiner Kallweit 46725e992a4SHeiner Kallweit /* magic enable v2 */ 46825e992a4SHeiner Kallweit MagicPacket_v2 = (1 << 16), /* Wake up when receives a Magic Packet */ 46925e992a4SHeiner Kallweit }; 47025e992a4SHeiner Kallweit 47125e992a4SHeiner Kallweit enum rtl_desc_bit { 47225e992a4SHeiner Kallweit /* First doubleword. */ 47325e992a4SHeiner Kallweit DescOwn = (1 << 31), /* Descriptor is owned by NIC */ 47425e992a4SHeiner Kallweit RingEnd = (1 << 30), /* End of descriptor ring */ 47525e992a4SHeiner Kallweit FirstFrag = (1 << 29), /* First segment of a packet */ 47625e992a4SHeiner Kallweit LastFrag = (1 << 28), /* Final segment of a packet */ 47725e992a4SHeiner Kallweit }; 47825e992a4SHeiner Kallweit 47925e992a4SHeiner Kallweit /* Generic case. */ 48025e992a4SHeiner Kallweit enum rtl_tx_desc_bit { 48125e992a4SHeiner Kallweit /* First doubleword. */ 48225e992a4SHeiner Kallweit TD_LSO = (1 << 27), /* Large Send Offload */ 48325e992a4SHeiner Kallweit #define TD_MSS_MAX 0x07ffu /* MSS value */ 48425e992a4SHeiner Kallweit 48525e992a4SHeiner Kallweit /* Second doubleword. */ 48625e992a4SHeiner Kallweit TxVlanTag = (1 << 17), /* Add VLAN tag */ 48725e992a4SHeiner Kallweit }; 48825e992a4SHeiner Kallweit 48925e992a4SHeiner Kallweit /* 8169, 8168b and 810x except 8102e. */ 49025e992a4SHeiner Kallweit enum rtl_tx_desc_bit_0 { 49125e992a4SHeiner Kallweit /* First doubleword. */ 49225e992a4SHeiner Kallweit #define TD0_MSS_SHIFT 16 /* MSS position (11 bits) */ 49325e992a4SHeiner Kallweit TD0_TCP_CS = (1 << 16), /* Calculate TCP/IP checksum */ 49425e992a4SHeiner Kallweit TD0_UDP_CS = (1 << 17), /* Calculate UDP/IP checksum */ 49525e992a4SHeiner Kallweit TD0_IP_CS = (1 << 18), /* Calculate IP checksum */ 49625e992a4SHeiner Kallweit }; 49725e992a4SHeiner Kallweit 49825e992a4SHeiner Kallweit /* 8102e, 8168c and beyond. */ 49925e992a4SHeiner Kallweit enum rtl_tx_desc_bit_1 { 50025e992a4SHeiner Kallweit /* First doubleword. */ 50125e992a4SHeiner Kallweit TD1_GTSENV4 = (1 << 26), /* Giant Send for IPv4 */ 50225e992a4SHeiner Kallweit TD1_GTSENV6 = (1 << 25), /* Giant Send for IPv6 */ 50325e992a4SHeiner Kallweit #define GTTCPHO_SHIFT 18 504e64e0c89SHeiner Kallweit #define GTTCPHO_MAX 0x7f 50525e992a4SHeiner Kallweit 50625e992a4SHeiner Kallweit /* Second doubleword. */ 50725e992a4SHeiner Kallweit #define TCPHO_SHIFT 18 508e64e0c89SHeiner Kallweit #define TCPHO_MAX 0x3ff 50925e992a4SHeiner Kallweit #define TD1_MSS_SHIFT 18 /* MSS position (11 bits) */ 51025e992a4SHeiner Kallweit TD1_IPv6_CS = (1 << 28), /* Calculate IPv6 checksum */ 51125e992a4SHeiner Kallweit TD1_IPv4_CS = (1 << 29), /* Calculate IPv4 checksum */ 51225e992a4SHeiner Kallweit TD1_TCP_CS = (1 << 30), /* Calculate TCP/IP checksum */ 51325e992a4SHeiner Kallweit TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */ 51425e992a4SHeiner Kallweit }; 51525e992a4SHeiner Kallweit 51625e992a4SHeiner Kallweit enum rtl_rx_desc_bit { 51725e992a4SHeiner Kallweit /* Rx private */ 51825e992a4SHeiner Kallweit PID1 = (1 << 18), /* Protocol ID bit 1/2 */ 51925e992a4SHeiner Kallweit PID0 = (1 << 17), /* Protocol ID bit 0/2 */ 52025e992a4SHeiner Kallweit 52125e992a4SHeiner Kallweit #define RxProtoUDP (PID1) 52225e992a4SHeiner Kallweit #define RxProtoTCP (PID0) 52325e992a4SHeiner Kallweit #define RxProtoIP (PID1 | PID0) 52425e992a4SHeiner Kallweit #define RxProtoMask RxProtoIP 52525e992a4SHeiner Kallweit 52625e992a4SHeiner Kallweit IPFail = (1 << 16), /* IP checksum failed */ 52725e992a4SHeiner Kallweit UDPFail = (1 << 15), /* UDP/IP checksum failed */ 52825e992a4SHeiner Kallweit TCPFail = (1 << 14), /* TCP/IP checksum failed */ 52925e992a4SHeiner Kallweit RxVlanTag = (1 << 16), /* VLAN tag available */ 53025e992a4SHeiner Kallweit }; 53125e992a4SHeiner Kallweit 5320170d594SHeiner Kallweit #define RTL_GSO_MAX_SIZE_V1 32000 5330170d594SHeiner Kallweit #define RTL_GSO_MAX_SEGS_V1 24 5340170d594SHeiner Kallweit #define RTL_GSO_MAX_SIZE_V2 64000 5350170d594SHeiner Kallweit #define RTL_GSO_MAX_SEGS_V2 64 5360170d594SHeiner Kallweit 53725e992a4SHeiner Kallweit struct TxDesc { 53825e992a4SHeiner Kallweit __le32 opts1; 53925e992a4SHeiner Kallweit __le32 opts2; 54025e992a4SHeiner Kallweit __le64 addr; 54125e992a4SHeiner Kallweit }; 54225e992a4SHeiner Kallweit 54325e992a4SHeiner Kallweit struct RxDesc { 54425e992a4SHeiner Kallweit __le32 opts1; 54525e992a4SHeiner Kallweit __le32 opts2; 54625e992a4SHeiner Kallweit __le64 addr; 54725e992a4SHeiner Kallweit }; 54825e992a4SHeiner Kallweit 54925e992a4SHeiner Kallweit struct ring_info { 55025e992a4SHeiner Kallweit struct sk_buff *skb; 55125e992a4SHeiner Kallweit u32 len; 55225e992a4SHeiner Kallweit }; 55325e992a4SHeiner Kallweit 55425e992a4SHeiner Kallweit struct rtl8169_counters { 55525e992a4SHeiner Kallweit __le64 tx_packets; 55625e992a4SHeiner Kallweit __le64 rx_packets; 55725e992a4SHeiner Kallweit __le64 tx_errors; 55825e992a4SHeiner Kallweit __le32 rx_errors; 55925e992a4SHeiner Kallweit __le16 rx_missed; 56025e992a4SHeiner Kallweit __le16 align_errors; 56125e992a4SHeiner Kallweit __le32 tx_one_collision; 56225e992a4SHeiner Kallweit __le32 tx_multi_collision; 56325e992a4SHeiner Kallweit __le64 rx_unicast; 56425e992a4SHeiner Kallweit __le64 rx_broadcast; 56525e992a4SHeiner Kallweit __le32 rx_multicast; 56625e992a4SHeiner Kallweit __le16 tx_aborted; 56725e992a4SHeiner Kallweit __le16 tx_underun; 56825e992a4SHeiner Kallweit }; 56925e992a4SHeiner Kallweit 57025e992a4SHeiner Kallweit struct rtl8169_tc_offsets { 57125e992a4SHeiner Kallweit bool inited; 57225e992a4SHeiner Kallweit __le64 tx_errors; 57325e992a4SHeiner Kallweit __le32 tx_multi_collision; 57425e992a4SHeiner Kallweit __le16 tx_aborted; 5750da3359aSHeiner Kallweit __le16 rx_missed; 57625e992a4SHeiner Kallweit }; 57725e992a4SHeiner Kallweit 57825e992a4SHeiner Kallweit enum rtl_flag { 57925e992a4SHeiner Kallweit RTL_FLAG_TASK_ENABLED = 0, 58025e992a4SHeiner Kallweit RTL_FLAG_TASK_RESET_PENDING, 58125e992a4SHeiner Kallweit RTL_FLAG_MAX 58225e992a4SHeiner Kallweit }; 58325e992a4SHeiner Kallweit 58425e992a4SHeiner Kallweit struct rtl8169_stats { 58525e992a4SHeiner Kallweit u64 packets; 58625e992a4SHeiner Kallweit u64 bytes; 58725e992a4SHeiner Kallweit struct u64_stats_sync syncp; 58825e992a4SHeiner Kallweit }; 58925e992a4SHeiner Kallweit 59025e992a4SHeiner Kallweit struct rtl8169_private { 59125e992a4SHeiner Kallweit void __iomem *mmio_addr; /* memory map physical address */ 59225e992a4SHeiner Kallweit struct pci_dev *pci_dev; 59325e992a4SHeiner Kallweit struct net_device *dev; 59425e992a4SHeiner Kallweit struct phy_device *phydev; 59525e992a4SHeiner Kallweit struct napi_struct napi; 59625e992a4SHeiner Kallweit enum mac_version mac_version; 59725e992a4SHeiner Kallweit u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ 59825e992a4SHeiner Kallweit u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ 59925e992a4SHeiner Kallweit u32 dirty_tx; 60025e992a4SHeiner Kallweit struct rtl8169_stats rx_stats; 60125e992a4SHeiner Kallweit struct rtl8169_stats tx_stats; 60225e992a4SHeiner Kallweit struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ 60325e992a4SHeiner Kallweit struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ 60425e992a4SHeiner Kallweit dma_addr_t TxPhyAddr; 60525e992a4SHeiner Kallweit dma_addr_t RxPhyAddr; 60632879f00SHeiner Kallweit struct page *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */ 60725e992a4SHeiner Kallweit struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ 60825e992a4SHeiner Kallweit u16 cp_cmd; 609c1d532d2SHeiner Kallweit u32 irq_mask; 61025e992a4SHeiner Kallweit struct clk *clk; 61125e992a4SHeiner Kallweit 61225e992a4SHeiner Kallweit struct { 61325e992a4SHeiner Kallweit DECLARE_BITMAP(flags, RTL_FLAG_MAX); 61425e992a4SHeiner Kallweit struct mutex mutex; 61525e992a4SHeiner Kallweit struct work_struct work; 61625e992a4SHeiner Kallweit } wk; 61725e992a4SHeiner Kallweit 61825e992a4SHeiner Kallweit unsigned irq_enabled:1; 61925e992a4SHeiner Kallweit unsigned supports_gmii:1; 62062b1b3b3SHeiner Kallweit unsigned aspm_manageable:1; 62125e992a4SHeiner Kallweit dma_addr_t counters_phys_addr; 62225e992a4SHeiner Kallweit struct rtl8169_counters *counters; 62325e992a4SHeiner Kallweit struct rtl8169_tc_offsets tc_offset; 62425e992a4SHeiner Kallweit u32 saved_wolopts; 6257ec3f872SHeiner Kallweit int eee_adv; 62625e992a4SHeiner Kallweit 62725e992a4SHeiner Kallweit const char *fw_name; 6288197f9d2SHeiner Kallweit struct rtl_fw *rtl_fw; 62925e992a4SHeiner Kallweit 63025e992a4SHeiner Kallweit u32 ocp_base; 63125e992a4SHeiner Kallweit }; 63225e992a4SHeiner Kallweit 63325e992a4SHeiner Kallweit typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); 63425e992a4SHeiner Kallweit 63525e992a4SHeiner Kallweit MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); 63625e992a4SHeiner Kallweit MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); 63725e992a4SHeiner Kallweit MODULE_SOFTDEP("pre: realtek"); 63825e992a4SHeiner Kallweit MODULE_LICENSE("GPL"); 63925e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168D_1); 64025e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168D_2); 64125e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_1); 64225e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_2); 64325e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_3); 64425e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8105E_1); 64525e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168F_1); 64625e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168F_2); 64725e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8402_1); 64825e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8411_1); 64925e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8411_2); 65025e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8106E_1); 65125e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8106E_2); 65225e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168G_2); 65325e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168G_3); 65425e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168H_1); 65525e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168H_2); 656229c1e0dSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168FP_3); 65725e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8107E_1); 65825e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8107E_2); 65902bf642bSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8125A_3); 66025e992a4SHeiner Kallweit 66125e992a4SHeiner Kallweit static inline struct device *tp_to_dev(struct rtl8169_private *tp) 66225e992a4SHeiner Kallweit { 66325e992a4SHeiner Kallweit return &tp->pci_dev->dev; 66425e992a4SHeiner Kallweit } 66525e992a4SHeiner Kallweit 66625e992a4SHeiner Kallweit static void rtl_lock_work(struct rtl8169_private *tp) 66725e992a4SHeiner Kallweit { 66825e992a4SHeiner Kallweit mutex_lock(&tp->wk.mutex); 66925e992a4SHeiner Kallweit } 67025e992a4SHeiner Kallweit 67125e992a4SHeiner Kallweit static void rtl_unlock_work(struct rtl8169_private *tp) 67225e992a4SHeiner Kallweit { 67325e992a4SHeiner Kallweit mutex_unlock(&tp->wk.mutex); 67425e992a4SHeiner Kallweit } 67525e992a4SHeiner Kallweit 67625e992a4SHeiner Kallweit static void rtl_lock_config_regs(struct rtl8169_private *tp) 67725e992a4SHeiner Kallweit { 67825e992a4SHeiner Kallweit RTL_W8(tp, Cfg9346, Cfg9346_Lock); 67925e992a4SHeiner Kallweit } 68025e992a4SHeiner Kallweit 68125e992a4SHeiner Kallweit static void rtl_unlock_config_regs(struct rtl8169_private *tp) 68225e992a4SHeiner Kallweit { 68325e992a4SHeiner Kallweit RTL_W8(tp, Cfg9346, Cfg9346_Unlock); 68425e992a4SHeiner Kallweit } 68525e992a4SHeiner Kallweit 686711463f8SHeiner Kallweit static void rtl_pci_commit(struct rtl8169_private *tp) 687711463f8SHeiner Kallweit { 688711463f8SHeiner Kallweit /* Read an arbitrary register to commit a preceding PCI write */ 689711463f8SHeiner Kallweit RTL_R8(tp, ChipCmd); 690711463f8SHeiner Kallweit } 691711463f8SHeiner Kallweit 692f1bce4adSHeiner Kallweit static bool rtl_is_8125(struct rtl8169_private *tp) 693f1bce4adSHeiner Kallweit { 694f1bce4adSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_60; 695f1bce4adSHeiner Kallweit } 696f1bce4adSHeiner Kallweit 6979e9f33baSHeiner Kallweit static bool rtl_is_8168evl_up(struct rtl8169_private *tp) 6989e9f33baSHeiner Kallweit { 6999e9f33baSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_34 && 700c623305bSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_39 && 7011287723aSHeiner Kallweit tp->mac_version <= RTL_GIGA_MAC_VER_52; 7029e9f33baSHeiner Kallweit } 7039e9f33baSHeiner Kallweit 7042e779ddbSHeiner Kallweit static bool rtl_supports_eee(struct rtl8169_private *tp) 7052e779ddbSHeiner Kallweit { 7062e779ddbSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_34 && 7072e779ddbSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_37 && 7082e779ddbSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_39; 7092e779ddbSHeiner Kallweit } 7102e779ddbSHeiner Kallweit 711ce37115eSHeiner Kallweit static void rtl_read_mac_from_reg(struct rtl8169_private *tp, u8 *mac, int reg) 712ce37115eSHeiner Kallweit { 713ce37115eSHeiner Kallweit int i; 714ce37115eSHeiner Kallweit 715ce37115eSHeiner Kallweit for (i = 0; i < ETH_ALEN; i++) 716ce37115eSHeiner Kallweit mac[i] = RTL_R8(tp, reg + i); 717ce37115eSHeiner Kallweit } 718ce37115eSHeiner Kallweit 71925e992a4SHeiner Kallweit struct rtl_cond { 72025e992a4SHeiner Kallweit bool (*check)(struct rtl8169_private *); 72125e992a4SHeiner Kallweit const char *msg; 72225e992a4SHeiner Kallweit }; 72325e992a4SHeiner Kallweit 72425e992a4SHeiner Kallweit static bool rtl_loop_wait(struct rtl8169_private *tp, const struct rtl_cond *c, 725d6836ef0SHeiner Kallweit unsigned long usecs, int n, bool high) 72625e992a4SHeiner Kallweit { 72725e992a4SHeiner Kallweit int i; 72825e992a4SHeiner Kallweit 72925e992a4SHeiner Kallweit for (i = 0; i < n; i++) { 73025e992a4SHeiner Kallweit if (c->check(tp) == high) 73125e992a4SHeiner Kallweit return true; 732d6836ef0SHeiner Kallweit fsleep(usecs); 73325e992a4SHeiner Kallweit } 73493882c6fSHeiner Kallweit 73593882c6fSHeiner Kallweit if (net_ratelimit()) 736d6836ef0SHeiner Kallweit netdev_err(tp->dev, "%s == %d (loop: %d, delay: %lu).\n", 737d6836ef0SHeiner Kallweit c->msg, !high, n, usecs); 73825e992a4SHeiner Kallweit return false; 73925e992a4SHeiner Kallweit } 74025e992a4SHeiner Kallweit 741d6836ef0SHeiner Kallweit static bool rtl_loop_wait_high(struct rtl8169_private *tp, 74225e992a4SHeiner Kallweit const struct rtl_cond *c, 743d6836ef0SHeiner Kallweit unsigned long d, int n) 74425e992a4SHeiner Kallweit { 745d6836ef0SHeiner Kallweit return rtl_loop_wait(tp, c, d, n, true); 74625e992a4SHeiner Kallweit } 74725e992a4SHeiner Kallweit 748d6836ef0SHeiner Kallweit static bool rtl_loop_wait_low(struct rtl8169_private *tp, 74925e992a4SHeiner Kallweit const struct rtl_cond *c, 750d6836ef0SHeiner Kallweit unsigned long d, int n) 75125e992a4SHeiner Kallweit { 752d6836ef0SHeiner Kallweit return rtl_loop_wait(tp, c, d, n, false); 75325e992a4SHeiner Kallweit } 75425e992a4SHeiner Kallweit 75525e992a4SHeiner Kallweit #define DECLARE_RTL_COND(name) \ 75625e992a4SHeiner Kallweit static bool name ## _check(struct rtl8169_private *); \ 75725e992a4SHeiner Kallweit \ 75825e992a4SHeiner Kallweit static const struct rtl_cond name = { \ 75925e992a4SHeiner Kallweit .check = name ## _check, \ 76025e992a4SHeiner Kallweit .msg = #name \ 76125e992a4SHeiner Kallweit }; \ 76225e992a4SHeiner Kallweit \ 76325e992a4SHeiner Kallweit static bool name ## _check(struct rtl8169_private *tp) 76425e992a4SHeiner Kallweit 76525e992a4SHeiner Kallweit static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg) 76625e992a4SHeiner Kallweit { 76725e992a4SHeiner Kallweit if (reg & 0xffff0001) { 76893882c6fSHeiner Kallweit if (net_ratelimit()) 76993882c6fSHeiner Kallweit netdev_err(tp->dev, "Invalid ocp reg %x!\n", reg); 77025e992a4SHeiner Kallweit return true; 77125e992a4SHeiner Kallweit } 77225e992a4SHeiner Kallweit return false; 77325e992a4SHeiner Kallweit } 77425e992a4SHeiner Kallweit 77525e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocp_gphy_cond) 77625e992a4SHeiner Kallweit { 77725e992a4SHeiner Kallweit return RTL_R32(tp, GPHY_OCP) & OCPAR_FLAG; 77825e992a4SHeiner Kallweit } 77925e992a4SHeiner Kallweit 78025e992a4SHeiner Kallweit static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) 78125e992a4SHeiner Kallweit { 78225e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 78325e992a4SHeiner Kallweit return; 78425e992a4SHeiner Kallweit 78525e992a4SHeiner Kallweit RTL_W32(tp, GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); 78625e992a4SHeiner Kallweit 787d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10); 78825e992a4SHeiner Kallweit } 78925e992a4SHeiner Kallweit 7909b994b4aSHeiner Kallweit static int r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) 79125e992a4SHeiner Kallweit { 79225e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 79325e992a4SHeiner Kallweit return 0; 79425e992a4SHeiner Kallweit 79525e992a4SHeiner Kallweit RTL_W32(tp, GPHY_OCP, reg << 15); 79625e992a4SHeiner Kallweit 797d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ? 7989b994b4aSHeiner Kallweit (RTL_R32(tp, GPHY_OCP) & 0xffff) : -ETIMEDOUT; 79925e992a4SHeiner Kallweit } 80025e992a4SHeiner Kallweit 80125e992a4SHeiner Kallweit static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) 80225e992a4SHeiner Kallweit { 80325e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 80425e992a4SHeiner Kallweit return; 80525e992a4SHeiner Kallweit 80625e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, OCPAR_FLAG | (reg << 15) | data); 80725e992a4SHeiner Kallweit } 80825e992a4SHeiner Kallweit 80925e992a4SHeiner Kallweit static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) 81025e992a4SHeiner Kallweit { 81125e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 81225e992a4SHeiner Kallweit return 0; 81325e992a4SHeiner Kallweit 81425e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, reg << 15); 81525e992a4SHeiner Kallweit 81625e992a4SHeiner Kallweit return RTL_R32(tp, OCPDR); 81725e992a4SHeiner Kallweit } 81825e992a4SHeiner Kallweit 819ef712edeSHeiner Kallweit static void r8168_mac_ocp_modify(struct rtl8169_private *tp, u32 reg, u16 mask, 820ef712edeSHeiner Kallweit u16 set) 821ef712edeSHeiner Kallweit { 822ef712edeSHeiner Kallweit u16 data = r8168_mac_ocp_read(tp, reg); 823ef712edeSHeiner Kallweit 824ef712edeSHeiner Kallweit r8168_mac_ocp_write(tp, reg, (data & ~mask) | set); 825ef712edeSHeiner Kallweit } 826ef712edeSHeiner Kallweit 82725e992a4SHeiner Kallweit static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) 82825e992a4SHeiner Kallweit { 82925e992a4SHeiner Kallweit if (reg == 0x1f) { 83025e992a4SHeiner Kallweit tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE; 83125e992a4SHeiner Kallweit return; 83225e992a4SHeiner Kallweit } 83325e992a4SHeiner Kallweit 83425e992a4SHeiner Kallweit if (tp->ocp_base != OCP_STD_PHY_BASE) 83525e992a4SHeiner Kallweit reg -= 0x10; 83625e992a4SHeiner Kallweit 83725e992a4SHeiner Kallweit r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value); 83825e992a4SHeiner Kallweit } 83925e992a4SHeiner Kallweit 84025e992a4SHeiner Kallweit static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) 84125e992a4SHeiner Kallweit { 8429c6850feSHeiner Kallweit if (reg == 0x1f) 8439c6850feSHeiner Kallweit return tp->ocp_base == OCP_STD_PHY_BASE ? 0 : tp->ocp_base >> 4; 8449c6850feSHeiner Kallweit 84525e992a4SHeiner Kallweit if (tp->ocp_base != OCP_STD_PHY_BASE) 84625e992a4SHeiner Kallweit reg -= 0x10; 84725e992a4SHeiner Kallweit 84825e992a4SHeiner Kallweit return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); 84925e992a4SHeiner Kallweit } 85025e992a4SHeiner Kallweit 85125e992a4SHeiner Kallweit static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value) 85225e992a4SHeiner Kallweit { 85325e992a4SHeiner Kallweit if (reg == 0x1f) { 85425e992a4SHeiner Kallweit tp->ocp_base = value << 4; 85525e992a4SHeiner Kallweit return; 85625e992a4SHeiner Kallweit } 85725e992a4SHeiner Kallweit 85825e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, tp->ocp_base + reg, value); 85925e992a4SHeiner Kallweit } 86025e992a4SHeiner Kallweit 86125e992a4SHeiner Kallweit static int mac_mcu_read(struct rtl8169_private *tp, int reg) 86225e992a4SHeiner Kallweit { 86325e992a4SHeiner Kallweit return r8168_mac_ocp_read(tp, tp->ocp_base + reg); 86425e992a4SHeiner Kallweit } 86525e992a4SHeiner Kallweit 86625e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_phyar_cond) 86725e992a4SHeiner Kallweit { 86825e992a4SHeiner Kallweit return RTL_R32(tp, PHYAR) & 0x80000000; 86925e992a4SHeiner Kallweit } 87025e992a4SHeiner Kallweit 87125e992a4SHeiner Kallweit static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value) 87225e992a4SHeiner Kallweit { 87325e992a4SHeiner Kallweit RTL_W32(tp, PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff)); 87425e992a4SHeiner Kallweit 875d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_phyar_cond, 25, 20); 87625e992a4SHeiner Kallweit /* 87725e992a4SHeiner Kallweit * According to hardware specs a 20us delay is required after write 87825e992a4SHeiner Kallweit * complete indication, but before sending next command. 87925e992a4SHeiner Kallweit */ 88025e992a4SHeiner Kallweit udelay(20); 88125e992a4SHeiner Kallweit } 88225e992a4SHeiner Kallweit 88325e992a4SHeiner Kallweit static int r8169_mdio_read(struct rtl8169_private *tp, int reg) 88425e992a4SHeiner Kallweit { 88525e992a4SHeiner Kallweit int value; 88625e992a4SHeiner Kallweit 88725e992a4SHeiner Kallweit RTL_W32(tp, PHYAR, 0x0 | (reg & 0x1f) << 16); 88825e992a4SHeiner Kallweit 889d6836ef0SHeiner Kallweit value = rtl_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ? 8909b994b4aSHeiner Kallweit RTL_R32(tp, PHYAR) & 0xffff : -ETIMEDOUT; 89125e992a4SHeiner Kallweit 89225e992a4SHeiner Kallweit /* 89325e992a4SHeiner Kallweit * According to hardware specs a 20us delay is required after read 89425e992a4SHeiner Kallweit * complete indication, but before sending next command. 89525e992a4SHeiner Kallweit */ 89625e992a4SHeiner Kallweit udelay(20); 89725e992a4SHeiner Kallweit 89825e992a4SHeiner Kallweit return value; 89925e992a4SHeiner Kallweit } 90025e992a4SHeiner Kallweit 90125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocpar_cond) 90225e992a4SHeiner Kallweit { 90325e992a4SHeiner Kallweit return RTL_R32(tp, OCPAR) & OCPAR_FLAG; 90425e992a4SHeiner Kallweit } 90525e992a4SHeiner Kallweit 90625e992a4SHeiner Kallweit static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data) 90725e992a4SHeiner Kallweit { 90825e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT)); 90925e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_GPHY_WRITE_CMD); 91025e992a4SHeiner Kallweit RTL_W32(tp, EPHY_RXER_NUM, 0); 91125e992a4SHeiner Kallweit 912d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100); 91325e992a4SHeiner Kallweit } 91425e992a4SHeiner Kallweit 91525e992a4SHeiner Kallweit static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value) 91625e992a4SHeiner Kallweit { 91725e992a4SHeiner Kallweit r8168dp_1_mdio_access(tp, reg, 91825e992a4SHeiner Kallweit OCPDR_WRITE_CMD | (value & OCPDR_DATA_MASK)); 91925e992a4SHeiner Kallweit } 92025e992a4SHeiner Kallweit 92125e992a4SHeiner Kallweit static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg) 92225e992a4SHeiner Kallweit { 92325e992a4SHeiner Kallweit r8168dp_1_mdio_access(tp, reg, OCPDR_READ_CMD); 92425e992a4SHeiner Kallweit 92525e992a4SHeiner Kallweit mdelay(1); 92625e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_GPHY_READ_CMD); 92725e992a4SHeiner Kallweit RTL_W32(tp, EPHY_RXER_NUM, 0); 92825e992a4SHeiner Kallweit 929d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ? 9309b994b4aSHeiner Kallweit RTL_R32(tp, OCPDR) & OCPDR_DATA_MASK : -ETIMEDOUT; 93125e992a4SHeiner Kallweit } 93225e992a4SHeiner Kallweit 93325e992a4SHeiner Kallweit #define R8168DP_1_MDIO_ACCESS_BIT 0x00020000 93425e992a4SHeiner Kallweit 93525e992a4SHeiner Kallweit static void r8168dp_2_mdio_start(struct rtl8169_private *tp) 93625e992a4SHeiner Kallweit { 93725e992a4SHeiner Kallweit RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT); 93825e992a4SHeiner Kallweit } 93925e992a4SHeiner Kallweit 94025e992a4SHeiner Kallweit static void r8168dp_2_mdio_stop(struct rtl8169_private *tp) 94125e992a4SHeiner Kallweit { 94225e992a4SHeiner Kallweit RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) | R8168DP_1_MDIO_ACCESS_BIT); 94325e992a4SHeiner Kallweit } 94425e992a4SHeiner Kallweit 94525e992a4SHeiner Kallweit static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value) 94625e992a4SHeiner Kallweit { 94725e992a4SHeiner Kallweit r8168dp_2_mdio_start(tp); 94825e992a4SHeiner Kallweit 94925e992a4SHeiner Kallweit r8169_mdio_write(tp, reg, value); 95025e992a4SHeiner Kallweit 95125e992a4SHeiner Kallweit r8168dp_2_mdio_stop(tp); 95225e992a4SHeiner Kallweit } 95325e992a4SHeiner Kallweit 95425e992a4SHeiner Kallweit static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) 95525e992a4SHeiner Kallweit { 95625e992a4SHeiner Kallweit int value; 95725e992a4SHeiner Kallweit 95862bdc8fdSHeiner Kallweit /* Work around issue with chip reporting wrong PHY ID */ 95962bdc8fdSHeiner Kallweit if (reg == MII_PHYSID2) 96062bdc8fdSHeiner Kallweit return 0xc912; 96162bdc8fdSHeiner Kallweit 96225e992a4SHeiner Kallweit r8168dp_2_mdio_start(tp); 96325e992a4SHeiner Kallweit 96425e992a4SHeiner Kallweit value = r8169_mdio_read(tp, reg); 96525e992a4SHeiner Kallweit 96625e992a4SHeiner Kallweit r8168dp_2_mdio_stop(tp); 96725e992a4SHeiner Kallweit 96825e992a4SHeiner Kallweit return value; 96925e992a4SHeiner Kallweit } 97025e992a4SHeiner Kallweit 97125e992a4SHeiner Kallweit static void rtl_writephy(struct rtl8169_private *tp, int location, int val) 97225e992a4SHeiner Kallweit { 97325e992a4SHeiner Kallweit switch (tp->mac_version) { 97425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 97525e992a4SHeiner Kallweit r8168dp_1_mdio_write(tp, location, val); 97625e992a4SHeiner Kallweit break; 97725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 97825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 97925e992a4SHeiner Kallweit r8168dp_2_mdio_write(tp, location, val); 98025e992a4SHeiner Kallweit break; 981f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61: 98225e992a4SHeiner Kallweit r8168g_mdio_write(tp, location, val); 98325e992a4SHeiner Kallweit break; 98425e992a4SHeiner Kallweit default: 98525e992a4SHeiner Kallweit r8169_mdio_write(tp, location, val); 98625e992a4SHeiner Kallweit break; 98725e992a4SHeiner Kallweit } 98825e992a4SHeiner Kallweit } 98925e992a4SHeiner Kallweit 99025e992a4SHeiner Kallweit static int rtl_readphy(struct rtl8169_private *tp, int location) 99125e992a4SHeiner Kallweit { 99225e992a4SHeiner Kallweit switch (tp->mac_version) { 99325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 99425e992a4SHeiner Kallweit return r8168dp_1_mdio_read(tp, location); 99525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 99625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 99725e992a4SHeiner Kallweit return r8168dp_2_mdio_read(tp, location); 998f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61: 99925e992a4SHeiner Kallweit return r8168g_mdio_read(tp, location); 100025e992a4SHeiner Kallweit default: 100125e992a4SHeiner Kallweit return r8169_mdio_read(tp, location); 100225e992a4SHeiner Kallweit } 100325e992a4SHeiner Kallweit } 100425e992a4SHeiner Kallweit 100525e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ephyar_cond) 100625e992a4SHeiner Kallweit { 100725e992a4SHeiner Kallweit return RTL_R32(tp, EPHYAR) & EPHYAR_FLAG; 100825e992a4SHeiner Kallweit } 100925e992a4SHeiner Kallweit 101025e992a4SHeiner Kallweit static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value) 101125e992a4SHeiner Kallweit { 101225e992a4SHeiner Kallweit RTL_W32(tp, EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) | 101325e992a4SHeiner Kallweit (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 101425e992a4SHeiner Kallweit 1015d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100); 101625e992a4SHeiner Kallweit 101725e992a4SHeiner Kallweit udelay(10); 101825e992a4SHeiner Kallweit } 101925e992a4SHeiner Kallweit 102025e992a4SHeiner Kallweit static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr) 102125e992a4SHeiner Kallweit { 102225e992a4SHeiner Kallweit RTL_W32(tp, EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 102325e992a4SHeiner Kallweit 1024d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ? 102525e992a4SHeiner Kallweit RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0; 102625e992a4SHeiner Kallweit } 102725e992a4SHeiner Kallweit 1028561535b0SHeiner Kallweit static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type) 1029561535b0SHeiner Kallweit { 1030561535b0SHeiner Kallweit /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ 1031561535b0SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB) 1032561535b0SHeiner Kallweit *cmd |= 0x7f0 << 18; 1033561535b0SHeiner Kallweit } 1034561535b0SHeiner Kallweit 103525e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_eriar_cond) 103625e992a4SHeiner Kallweit { 103725e992a4SHeiner Kallweit return RTL_R32(tp, ERIAR) & ERIAR_FLAG; 103825e992a4SHeiner Kallweit } 103925e992a4SHeiner Kallweit 104025e992a4SHeiner Kallweit static void _rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 104125e992a4SHeiner Kallweit u32 val, int type) 104225e992a4SHeiner Kallweit { 1043561535b0SHeiner Kallweit u32 cmd = ERIAR_WRITE_CMD | type | mask | addr; 1044561535b0SHeiner Kallweit 104525e992a4SHeiner Kallweit BUG_ON((addr & 3) || (mask == 0)); 104625e992a4SHeiner Kallweit RTL_W32(tp, ERIDR, val); 1047561535b0SHeiner Kallweit r8168fp_adjust_ocp_cmd(tp, &cmd, type); 1048561535b0SHeiner Kallweit RTL_W32(tp, ERIAR, cmd); 104925e992a4SHeiner Kallweit 1050d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); 105125e992a4SHeiner Kallweit } 105225e992a4SHeiner Kallweit 105325e992a4SHeiner Kallweit static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 105425e992a4SHeiner Kallweit u32 val) 105525e992a4SHeiner Kallweit { 105625e992a4SHeiner Kallweit _rtl_eri_write(tp, addr, mask, val, ERIAR_EXGMAC); 105725e992a4SHeiner Kallweit } 105825e992a4SHeiner Kallweit 105925e992a4SHeiner Kallweit static u32 _rtl_eri_read(struct rtl8169_private *tp, int addr, int type) 106025e992a4SHeiner Kallweit { 1061561535b0SHeiner Kallweit u32 cmd = ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr; 1062561535b0SHeiner Kallweit 1063561535b0SHeiner Kallweit r8168fp_adjust_ocp_cmd(tp, &cmd, type); 1064561535b0SHeiner Kallweit RTL_W32(tp, ERIAR, cmd); 106525e992a4SHeiner Kallweit 1066d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? 106725e992a4SHeiner Kallweit RTL_R32(tp, ERIDR) : ~0; 106825e992a4SHeiner Kallweit } 106925e992a4SHeiner Kallweit 107025e992a4SHeiner Kallweit static u32 rtl_eri_read(struct rtl8169_private *tp, int addr) 107125e992a4SHeiner Kallweit { 107225e992a4SHeiner Kallweit return _rtl_eri_read(tp, addr, ERIAR_EXGMAC); 107325e992a4SHeiner Kallweit } 107425e992a4SHeiner Kallweit 107554113dedSHeiner Kallweit static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 p, u32 m) 107625e992a4SHeiner Kallweit { 107754113dedSHeiner Kallweit u32 val = rtl_eri_read(tp, addr); 107825e992a4SHeiner Kallweit 107954113dedSHeiner Kallweit rtl_eri_write(tp, addr, ERIAR_MASK_1111, (val & ~m) | p); 108025e992a4SHeiner Kallweit } 108125e992a4SHeiner Kallweit 108254113dedSHeiner Kallweit static void rtl_eri_set_bits(struct rtl8169_private *tp, int addr, u32 p) 108325e992a4SHeiner Kallweit { 108454113dedSHeiner Kallweit rtl_w0w1_eri(tp, addr, p, 0); 108525e992a4SHeiner Kallweit } 108625e992a4SHeiner Kallweit 108754113dedSHeiner Kallweit static void rtl_eri_clear_bits(struct rtl8169_private *tp, int addr, u32 m) 108825e992a4SHeiner Kallweit { 108954113dedSHeiner Kallweit rtl_w0w1_eri(tp, addr, 0, m); 109025e992a4SHeiner Kallweit } 109125e992a4SHeiner Kallweit 1092a15aaa03SHeiner Kallweit static u32 r8168dp_ocp_read(struct rtl8169_private *tp, u16 reg) 109325e992a4SHeiner Kallweit { 1094a15aaa03SHeiner Kallweit RTL_W32(tp, OCPAR, 0x0fu << 12 | (reg & 0x0fff)); 1095d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ? 109625e992a4SHeiner Kallweit RTL_R32(tp, OCPDR) : ~0; 109725e992a4SHeiner Kallweit } 109825e992a4SHeiner Kallweit 1099787c0c04SHeiner Kallweit static u32 r8168ep_ocp_read(struct rtl8169_private *tp, u16 reg) 110025e992a4SHeiner Kallweit { 110125e992a4SHeiner Kallweit return _rtl_eri_read(tp, reg, ERIAR_OOB); 110225e992a4SHeiner Kallweit } 110325e992a4SHeiner Kallweit 110425e992a4SHeiner Kallweit static void r8168dp_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, 110525e992a4SHeiner Kallweit u32 data) 110625e992a4SHeiner Kallweit { 110725e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, data); 110825e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); 1109d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20); 111025e992a4SHeiner Kallweit } 111125e992a4SHeiner Kallweit 111225e992a4SHeiner Kallweit static void r8168ep_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, 111325e992a4SHeiner Kallweit u32 data) 111425e992a4SHeiner Kallweit { 111525e992a4SHeiner Kallweit _rtl_eri_write(tp, reg, ((u32)mask & 0x0f) << ERIAR_MASK_SHIFT, 111625e992a4SHeiner Kallweit data, ERIAR_OOB); 111725e992a4SHeiner Kallweit } 111825e992a4SHeiner Kallweit 111925e992a4SHeiner Kallweit static void r8168dp_oob_notify(struct rtl8169_private *tp, u8 cmd) 112025e992a4SHeiner Kallweit { 112125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe8, ERIAR_MASK_0001, cmd); 112225e992a4SHeiner Kallweit 112325e992a4SHeiner Kallweit r8168dp_ocp_write(tp, 0x1, 0x30, 0x00000001); 112425e992a4SHeiner Kallweit } 112525e992a4SHeiner Kallweit 112625e992a4SHeiner Kallweit #define OOB_CMD_RESET 0x00 112725e992a4SHeiner Kallweit #define OOB_CMD_DRIVER_START 0x05 112825e992a4SHeiner Kallweit #define OOB_CMD_DRIVER_STOP 0x06 112925e992a4SHeiner Kallweit 113025e992a4SHeiner Kallweit static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp) 113125e992a4SHeiner Kallweit { 113225e992a4SHeiner Kallweit return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10; 113325e992a4SHeiner Kallweit } 113425e992a4SHeiner Kallweit 113525e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_dp_ocp_read_cond) 113625e992a4SHeiner Kallweit { 113725e992a4SHeiner Kallweit u16 reg; 113825e992a4SHeiner Kallweit 113925e992a4SHeiner Kallweit reg = rtl8168_get_ocp_reg(tp); 114025e992a4SHeiner Kallweit 1141a15aaa03SHeiner Kallweit return r8168dp_ocp_read(tp, reg) & 0x00000800; 114225e992a4SHeiner Kallweit } 114325e992a4SHeiner Kallweit 114425e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ep_ocp_read_cond) 114525e992a4SHeiner Kallweit { 1146787c0c04SHeiner Kallweit return r8168ep_ocp_read(tp, 0x124) & 0x00000001; 114725e992a4SHeiner Kallweit } 114825e992a4SHeiner Kallweit 114925e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocp_tx_cond) 115025e992a4SHeiner Kallweit { 115125e992a4SHeiner Kallweit return RTL_R8(tp, IBISR0) & 0x20; 115225e992a4SHeiner Kallweit } 115325e992a4SHeiner Kallweit 115425e992a4SHeiner Kallweit static void rtl8168ep_stop_cmac(struct rtl8169_private *tp) 115525e992a4SHeiner Kallweit { 115625e992a4SHeiner Kallweit RTL_W8(tp, IBCR2, RTL_R8(tp, IBCR2) & ~0x01); 1157d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_ocp_tx_cond, 50000, 2000); 115825e992a4SHeiner Kallweit RTL_W8(tp, IBISR0, RTL_R8(tp, IBISR0) | 0x20); 115925e992a4SHeiner Kallweit RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01); 116025e992a4SHeiner Kallweit } 116125e992a4SHeiner Kallweit 116225e992a4SHeiner Kallweit static void rtl8168dp_driver_start(struct rtl8169_private *tp) 116325e992a4SHeiner Kallweit { 116425e992a4SHeiner Kallweit r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START); 1165d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10); 116625e992a4SHeiner Kallweit } 116725e992a4SHeiner Kallweit 116825e992a4SHeiner Kallweit static void rtl8168ep_driver_start(struct rtl8169_private *tp) 116925e992a4SHeiner Kallweit { 117025e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START); 1171787c0c04SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01); 1172d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 10); 117325e992a4SHeiner Kallweit } 117425e992a4SHeiner Kallweit 117525e992a4SHeiner Kallweit static void rtl8168_driver_start(struct rtl8169_private *tp) 117625e992a4SHeiner Kallweit { 117725e992a4SHeiner Kallweit switch (tp->mac_version) { 117825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 117925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 118025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 118125e992a4SHeiner Kallweit rtl8168dp_driver_start(tp); 118225e992a4SHeiner Kallweit break; 11831287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 118425e992a4SHeiner Kallweit rtl8168ep_driver_start(tp); 118525e992a4SHeiner Kallweit break; 118625e992a4SHeiner Kallweit default: 118725e992a4SHeiner Kallweit BUG(); 118825e992a4SHeiner Kallweit break; 118925e992a4SHeiner Kallweit } 119025e992a4SHeiner Kallweit } 119125e992a4SHeiner Kallweit 119225e992a4SHeiner Kallweit static void rtl8168dp_driver_stop(struct rtl8169_private *tp) 119325e992a4SHeiner Kallweit { 119425e992a4SHeiner Kallweit r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP); 1195d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10); 119625e992a4SHeiner Kallweit } 119725e992a4SHeiner Kallweit 119825e992a4SHeiner Kallweit static void rtl8168ep_driver_stop(struct rtl8169_private *tp) 119925e992a4SHeiner Kallweit { 120025e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp); 120125e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP); 1202787c0c04SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01); 1203d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10); 120425e992a4SHeiner Kallweit } 120525e992a4SHeiner Kallweit 120625e992a4SHeiner Kallweit static void rtl8168_driver_stop(struct rtl8169_private *tp) 120725e992a4SHeiner Kallweit { 120825e992a4SHeiner Kallweit switch (tp->mac_version) { 120925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 121025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 121125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 121225e992a4SHeiner Kallweit rtl8168dp_driver_stop(tp); 121325e992a4SHeiner Kallweit break; 12141287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 121525e992a4SHeiner Kallweit rtl8168ep_driver_stop(tp); 121625e992a4SHeiner Kallweit break; 121725e992a4SHeiner Kallweit default: 121825e992a4SHeiner Kallweit BUG(); 121925e992a4SHeiner Kallweit break; 122025e992a4SHeiner Kallweit } 122125e992a4SHeiner Kallweit } 122225e992a4SHeiner Kallweit 122325e992a4SHeiner Kallweit static bool r8168dp_check_dash(struct rtl8169_private *tp) 122425e992a4SHeiner Kallweit { 122525e992a4SHeiner Kallweit u16 reg = rtl8168_get_ocp_reg(tp); 122625e992a4SHeiner Kallweit 1227a15aaa03SHeiner Kallweit return !!(r8168dp_ocp_read(tp, reg) & 0x00008000); 122825e992a4SHeiner Kallweit } 122925e992a4SHeiner Kallweit 123025e992a4SHeiner Kallweit static bool r8168ep_check_dash(struct rtl8169_private *tp) 123125e992a4SHeiner Kallweit { 1232787c0c04SHeiner Kallweit return r8168ep_ocp_read(tp, 0x128) & 0x00000001; 123325e992a4SHeiner Kallweit } 123425e992a4SHeiner Kallweit 123525e992a4SHeiner Kallweit static bool r8168_check_dash(struct rtl8169_private *tp) 123625e992a4SHeiner Kallweit { 123725e992a4SHeiner Kallweit switch (tp->mac_version) { 123825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 123925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 124025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 124125e992a4SHeiner Kallweit return r8168dp_check_dash(tp); 12421287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 124325e992a4SHeiner Kallweit return r8168ep_check_dash(tp); 124425e992a4SHeiner Kallweit default: 124525e992a4SHeiner Kallweit return false; 124625e992a4SHeiner Kallweit } 124725e992a4SHeiner Kallweit } 124825e992a4SHeiner Kallweit 124925e992a4SHeiner Kallweit static void rtl_reset_packet_filter(struct rtl8169_private *tp) 125025e992a4SHeiner Kallweit { 125154113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0xdc, BIT(0)); 125254113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xdc, BIT(0)); 125325e992a4SHeiner Kallweit } 125425e992a4SHeiner Kallweit 125525e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_efusear_cond) 125625e992a4SHeiner Kallweit { 125725e992a4SHeiner Kallweit return RTL_R32(tp, EFUSEAR) & EFUSEAR_FLAG; 125825e992a4SHeiner Kallweit } 125925e992a4SHeiner Kallweit 12602992bdfaSHeiner Kallweit u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr) 126125e992a4SHeiner Kallweit { 126225e992a4SHeiner Kallweit RTL_W32(tp, EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT); 126325e992a4SHeiner Kallweit 1264d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ? 126525e992a4SHeiner Kallweit RTL_R32(tp, EFUSEAR) & EFUSEAR_DATA_MASK : ~0; 126625e992a4SHeiner Kallweit } 126725e992a4SHeiner Kallweit 1268c1d532d2SHeiner Kallweit static u32 rtl_get_events(struct rtl8169_private *tp) 1269c1d532d2SHeiner Kallweit { 1270f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1271f1bce4adSHeiner Kallweit return RTL_R32(tp, IntrStatus_8125); 1272f1bce4adSHeiner Kallweit else 1273c1d532d2SHeiner Kallweit return RTL_R16(tp, IntrStatus); 1274c1d532d2SHeiner Kallweit } 1275c1d532d2SHeiner Kallweit 1276c1d532d2SHeiner Kallweit static void rtl_ack_events(struct rtl8169_private *tp, u32 bits) 127725e992a4SHeiner Kallweit { 1278f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1279f1bce4adSHeiner Kallweit RTL_W32(tp, IntrStatus_8125, bits); 1280f1bce4adSHeiner Kallweit else 128125e992a4SHeiner Kallweit RTL_W16(tp, IntrStatus, bits); 128225e992a4SHeiner Kallweit } 128325e992a4SHeiner Kallweit 128425e992a4SHeiner Kallweit static void rtl_irq_disable(struct rtl8169_private *tp) 128525e992a4SHeiner Kallweit { 1286f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1287f1bce4adSHeiner Kallweit RTL_W32(tp, IntrMask_8125, 0); 1288f1bce4adSHeiner Kallweit else 128925e992a4SHeiner Kallweit RTL_W16(tp, IntrMask, 0); 129025e992a4SHeiner Kallweit tp->irq_enabled = 0; 129125e992a4SHeiner Kallweit } 129225e992a4SHeiner Kallweit 129325e992a4SHeiner Kallweit static void rtl_irq_enable(struct rtl8169_private *tp) 129425e992a4SHeiner Kallweit { 129525e992a4SHeiner Kallweit tp->irq_enabled = 1; 1296f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1297f1bce4adSHeiner Kallweit RTL_W32(tp, IntrMask_8125, tp->irq_mask); 1298f1bce4adSHeiner Kallweit else 129925e992a4SHeiner Kallweit RTL_W16(tp, IntrMask, tp->irq_mask); 130025e992a4SHeiner Kallweit } 130125e992a4SHeiner Kallweit 130225e992a4SHeiner Kallweit static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) 130325e992a4SHeiner Kallweit { 130425e992a4SHeiner Kallweit rtl_irq_disable(tp); 1305c1d532d2SHeiner Kallweit rtl_ack_events(tp, 0xffffffff); 1306711463f8SHeiner Kallweit rtl_pci_commit(tp); 130725e992a4SHeiner Kallweit } 130825e992a4SHeiner Kallweit 130925e992a4SHeiner Kallweit static void rtl_link_chg_patch(struct rtl8169_private *tp) 131025e992a4SHeiner Kallweit { 131125e992a4SHeiner Kallweit struct phy_device *phydev = tp->phydev; 131225e992a4SHeiner Kallweit 131325e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34 || 131425e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_38) { 131525e992a4SHeiner Kallweit if (phydev->speed == SPEED_1000) { 131625e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011); 131725e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 131825e992a4SHeiner Kallweit } else if (phydev->speed == SPEED_100) { 131925e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 132025e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 132125e992a4SHeiner Kallweit } else { 132225e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 132325e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f); 132425e992a4SHeiner Kallweit } 132525e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 132625e992a4SHeiner Kallweit } else if (tp->mac_version == RTL_GIGA_MAC_VER_35 || 132725e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_36) { 132825e992a4SHeiner Kallweit if (phydev->speed == SPEED_1000) { 132925e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011); 133025e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 133125e992a4SHeiner Kallweit } else { 133225e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 133325e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f); 133425e992a4SHeiner Kallweit } 133525e992a4SHeiner Kallweit } else if (tp->mac_version == RTL_GIGA_MAC_VER_37) { 133625e992a4SHeiner Kallweit if (phydev->speed == SPEED_10) { 133725e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02); 133825e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060a); 133925e992a4SHeiner Kallweit } else { 134025e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000); 134125e992a4SHeiner Kallweit } 134225e992a4SHeiner Kallweit } 134325e992a4SHeiner Kallweit } 134425e992a4SHeiner Kallweit 134525e992a4SHeiner Kallweit #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) 134625e992a4SHeiner Kallweit 134725e992a4SHeiner Kallweit static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 134825e992a4SHeiner Kallweit { 134925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 135025e992a4SHeiner Kallweit 135125e992a4SHeiner Kallweit rtl_lock_work(tp); 135225e992a4SHeiner Kallweit wol->supported = WAKE_ANY; 135325e992a4SHeiner Kallweit wol->wolopts = tp->saved_wolopts; 135425e992a4SHeiner Kallweit rtl_unlock_work(tp); 135525e992a4SHeiner Kallweit } 135625e992a4SHeiner Kallweit 135725e992a4SHeiner Kallweit static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) 135825e992a4SHeiner Kallweit { 135925e992a4SHeiner Kallweit static const struct { 136025e992a4SHeiner Kallweit u32 opt; 136125e992a4SHeiner Kallweit u16 reg; 136225e992a4SHeiner Kallweit u8 mask; 136325e992a4SHeiner Kallweit } cfg[] = { 136425e992a4SHeiner Kallweit { WAKE_PHY, Config3, LinkUp }, 136525e992a4SHeiner Kallweit { WAKE_UCAST, Config5, UWF }, 136625e992a4SHeiner Kallweit { WAKE_BCAST, Config5, BWF }, 136725e992a4SHeiner Kallweit { WAKE_MCAST, Config5, MWF }, 136825e992a4SHeiner Kallweit { WAKE_ANY, Config5, LanWake }, 136925e992a4SHeiner Kallweit { WAKE_MAGIC, Config3, MagicPacket } 137025e992a4SHeiner Kallweit }; 1371f1bce4adSHeiner Kallweit unsigned int i, tmp = ARRAY_SIZE(cfg); 137225e992a4SHeiner Kallweit u8 options; 137325e992a4SHeiner Kallweit 137425e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 137525e992a4SHeiner Kallweit 13769e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp)) { 1377f1bce4adSHeiner Kallweit tmp--; 137825e992a4SHeiner Kallweit if (wolopts & WAKE_MAGIC) 137954113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x0dc, MagicPacket_v2); 138025e992a4SHeiner Kallweit else 138154113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x0dc, MagicPacket_v2); 1382f1bce4adSHeiner Kallweit } else if (rtl_is_8125(tp)) { 1383f1bce4adSHeiner Kallweit tmp--; 1384f1bce4adSHeiner Kallweit if (wolopts & WAKE_MAGIC) 1385f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b6, 0, BIT(0)); 1386f1bce4adSHeiner Kallweit else 1387f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0); 138825e992a4SHeiner Kallweit } 138925e992a4SHeiner Kallweit 139025e992a4SHeiner Kallweit for (i = 0; i < tmp; i++) { 139125e992a4SHeiner Kallweit options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; 139225e992a4SHeiner Kallweit if (wolopts & cfg[i].opt) 139325e992a4SHeiner Kallweit options |= cfg[i].mask; 139425e992a4SHeiner Kallweit RTL_W8(tp, cfg[i].reg, options); 139525e992a4SHeiner Kallweit } 139625e992a4SHeiner Kallweit 139725e992a4SHeiner Kallweit switch (tp->mac_version) { 1398edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 139925e992a4SHeiner Kallweit options = RTL_R8(tp, Config1) & ~PMEnable; 140025e992a4SHeiner Kallweit if (wolopts) 140125e992a4SHeiner Kallweit options |= PMEnable; 140225e992a4SHeiner Kallweit RTL_W8(tp, Config1, options); 140325e992a4SHeiner Kallweit break; 1404edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_34: 1405edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_37: 1406838974e1SHeiner Kallweit case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_61: 140725e992a4SHeiner Kallweit options = RTL_R8(tp, Config2) & ~PME_SIGNAL; 140825e992a4SHeiner Kallweit if (wolopts) 140925e992a4SHeiner Kallweit options |= PME_SIGNAL; 141025e992a4SHeiner Kallweit RTL_W8(tp, Config2, options); 141125e992a4SHeiner Kallweit break; 1412edcde3eeSHeiner Kallweit default: 1413edcde3eeSHeiner Kallweit break; 141425e992a4SHeiner Kallweit } 141525e992a4SHeiner Kallweit 141625e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 141725e992a4SHeiner Kallweit 141825e992a4SHeiner Kallweit device_set_wakeup_enable(tp_to_dev(tp), wolopts); 1419398fd408SHeiner Kallweit tp->dev->wol_enabled = wolopts ? 1 : 0; 142025e992a4SHeiner Kallweit } 142125e992a4SHeiner Kallweit 142225e992a4SHeiner Kallweit static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 142325e992a4SHeiner Kallweit { 142425e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 142525e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 142625e992a4SHeiner Kallweit 142725e992a4SHeiner Kallweit if (wol->wolopts & ~WAKE_ANY) 142825e992a4SHeiner Kallweit return -EINVAL; 142925e992a4SHeiner Kallweit 143025e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 143125e992a4SHeiner Kallweit 143225e992a4SHeiner Kallweit rtl_lock_work(tp); 143325e992a4SHeiner Kallweit 143425e992a4SHeiner Kallweit tp->saved_wolopts = wol->wolopts; 143525e992a4SHeiner Kallweit 143625e992a4SHeiner Kallweit if (pm_runtime_active(d)) 143725e992a4SHeiner Kallweit __rtl8169_set_wol(tp, tp->saved_wolopts); 143825e992a4SHeiner Kallweit 143925e992a4SHeiner Kallweit rtl_unlock_work(tp); 144025e992a4SHeiner Kallweit 144125e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 144225e992a4SHeiner Kallweit 144325e992a4SHeiner Kallweit return 0; 144425e992a4SHeiner Kallweit } 144525e992a4SHeiner Kallweit 144625e992a4SHeiner Kallweit static void rtl8169_get_drvinfo(struct net_device *dev, 144725e992a4SHeiner Kallweit struct ethtool_drvinfo *info) 144825e992a4SHeiner Kallweit { 144925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 145025e992a4SHeiner Kallweit struct rtl_fw *rtl_fw = tp->rtl_fw; 145125e992a4SHeiner Kallweit 145225e992a4SHeiner Kallweit strlcpy(info->driver, MODULENAME, sizeof(info->driver)); 145325e992a4SHeiner Kallweit strlcpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); 145425e992a4SHeiner Kallweit BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); 145525e992a4SHeiner Kallweit if (rtl_fw) 145625e992a4SHeiner Kallweit strlcpy(info->fw_version, rtl_fw->version, 145725e992a4SHeiner Kallweit sizeof(info->fw_version)); 145825e992a4SHeiner Kallweit } 145925e992a4SHeiner Kallweit 146025e992a4SHeiner Kallweit static int rtl8169_get_regs_len(struct net_device *dev) 146125e992a4SHeiner Kallweit { 146225e992a4SHeiner Kallweit return R8169_REGS_SIZE; 146325e992a4SHeiner Kallweit } 146425e992a4SHeiner Kallweit 146525e992a4SHeiner Kallweit static netdev_features_t rtl8169_fix_features(struct net_device *dev, 146625e992a4SHeiner Kallweit netdev_features_t features) 146725e992a4SHeiner Kallweit { 146825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 146925e992a4SHeiner Kallweit 147025e992a4SHeiner Kallweit if (dev->mtu > TD_MSS_MAX) 147125e992a4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 147225e992a4SHeiner Kallweit 1473a8ec173aSHeiner Kallweit if (dev->mtu > ETH_DATA_LEN && 147425e992a4SHeiner Kallweit tp->mac_version > RTL_GIGA_MAC_VER_06) 14757cb83b21SHeiner Kallweit features &= ~(NETIF_F_CSUM_MASK | NETIF_F_ALL_TSO); 147625e992a4SHeiner Kallweit 147725e992a4SHeiner Kallweit return features; 147825e992a4SHeiner Kallweit } 147925e992a4SHeiner Kallweit 148010478283SHeiner Kallweit static void rtl_set_rx_config_features(struct rtl8169_private *tp, 148125e992a4SHeiner Kallweit netdev_features_t features) 148225e992a4SHeiner Kallweit { 148310478283SHeiner Kallweit u32 rx_config = RTL_R32(tp, RxConfig); 148425e992a4SHeiner Kallweit 148525e992a4SHeiner Kallweit if (features & NETIF_F_RXALL) 148610478283SHeiner Kallweit rx_config |= RX_CONFIG_ACCEPT_ERR_MASK; 148725e992a4SHeiner Kallweit else 148810478283SHeiner Kallweit rx_config &= ~RX_CONFIG_ACCEPT_ERR_MASK; 148925e992a4SHeiner Kallweit 1490f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) { 1491f1bce4adSHeiner Kallweit if (features & NETIF_F_HW_VLAN_CTAG_RX) 1492f1bce4adSHeiner Kallweit rx_config |= RX_VLAN_8125; 1493f1bce4adSHeiner Kallweit else 1494f1bce4adSHeiner Kallweit rx_config &= ~RX_VLAN_8125; 1495f1bce4adSHeiner Kallweit } 1496f1bce4adSHeiner Kallweit 149725e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, rx_config); 149810478283SHeiner Kallweit } 149910478283SHeiner Kallweit 150010478283SHeiner Kallweit static int rtl8169_set_features(struct net_device *dev, 150110478283SHeiner Kallweit netdev_features_t features) 150210478283SHeiner Kallweit { 150310478283SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 150410478283SHeiner Kallweit 150510478283SHeiner Kallweit rtl_lock_work(tp); 150610478283SHeiner Kallweit 150710478283SHeiner Kallweit rtl_set_rx_config_features(tp, features); 150825e992a4SHeiner Kallweit 150925e992a4SHeiner Kallweit if (features & NETIF_F_RXCSUM) 151025e992a4SHeiner Kallweit tp->cp_cmd |= RxChkSum; 151125e992a4SHeiner Kallweit else 151225e992a4SHeiner Kallweit tp->cp_cmd &= ~RxChkSum; 151325e992a4SHeiner Kallweit 1514f1bce4adSHeiner Kallweit if (!rtl_is_8125(tp)) { 151525e992a4SHeiner Kallweit if (features & NETIF_F_HW_VLAN_CTAG_RX) 151625e992a4SHeiner Kallweit tp->cp_cmd |= RxVlan; 151725e992a4SHeiner Kallweit else 151825e992a4SHeiner Kallweit tp->cp_cmd &= ~RxVlan; 1519f1bce4adSHeiner Kallweit } 152025e992a4SHeiner Kallweit 152125e992a4SHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 1522711463f8SHeiner Kallweit rtl_pci_commit(tp); 152325e992a4SHeiner Kallweit 152425e992a4SHeiner Kallweit rtl_unlock_work(tp); 152525e992a4SHeiner Kallweit 152625e992a4SHeiner Kallweit return 0; 152725e992a4SHeiner Kallweit } 152825e992a4SHeiner Kallweit 152925e992a4SHeiner Kallweit static inline u32 rtl8169_tx_vlan_tag(struct sk_buff *skb) 153025e992a4SHeiner Kallweit { 153125e992a4SHeiner Kallweit return (skb_vlan_tag_present(skb)) ? 15327424edbbSHeiner Kallweit TxVlanTag | swab16(skb_vlan_tag_get(skb)) : 0x00; 153325e992a4SHeiner Kallweit } 153425e992a4SHeiner Kallweit 153525e992a4SHeiner Kallweit static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) 153625e992a4SHeiner Kallweit { 153725e992a4SHeiner Kallweit u32 opts2 = le32_to_cpu(desc->opts2); 153825e992a4SHeiner Kallweit 153925e992a4SHeiner Kallweit if (opts2 & RxVlanTag) 15407424edbbSHeiner Kallweit __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), swab16(opts2 & 0xffff)); 154125e992a4SHeiner Kallweit } 154225e992a4SHeiner Kallweit 154325e992a4SHeiner Kallweit static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, 154425e992a4SHeiner Kallweit void *p) 154525e992a4SHeiner Kallweit { 154625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 154725e992a4SHeiner Kallweit u32 __iomem *data = tp->mmio_addr; 154825e992a4SHeiner Kallweit u32 *dw = p; 154925e992a4SHeiner Kallweit int i; 155025e992a4SHeiner Kallweit 155125e992a4SHeiner Kallweit rtl_lock_work(tp); 155225e992a4SHeiner Kallweit for (i = 0; i < R8169_REGS_SIZE; i += 4) 155325e992a4SHeiner Kallweit memcpy_fromio(dw++, data++, 4); 155425e992a4SHeiner Kallweit rtl_unlock_work(tp); 155525e992a4SHeiner Kallweit } 155625e992a4SHeiner Kallweit 155725e992a4SHeiner Kallweit static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = { 155825e992a4SHeiner Kallweit "tx_packets", 155925e992a4SHeiner Kallweit "rx_packets", 156025e992a4SHeiner Kallweit "tx_errors", 156125e992a4SHeiner Kallweit "rx_errors", 156225e992a4SHeiner Kallweit "rx_missed", 156325e992a4SHeiner Kallweit "align_errors", 156425e992a4SHeiner Kallweit "tx_single_collisions", 156525e992a4SHeiner Kallweit "tx_multi_collisions", 156625e992a4SHeiner Kallweit "unicast", 156725e992a4SHeiner Kallweit "broadcast", 156825e992a4SHeiner Kallweit "multicast", 156925e992a4SHeiner Kallweit "tx_aborted", 157025e992a4SHeiner Kallweit "tx_underrun", 157125e992a4SHeiner Kallweit }; 157225e992a4SHeiner Kallweit 157325e992a4SHeiner Kallweit static int rtl8169_get_sset_count(struct net_device *dev, int sset) 157425e992a4SHeiner Kallweit { 157525e992a4SHeiner Kallweit switch (sset) { 157625e992a4SHeiner Kallweit case ETH_SS_STATS: 157725e992a4SHeiner Kallweit return ARRAY_SIZE(rtl8169_gstrings); 157825e992a4SHeiner Kallweit default: 157925e992a4SHeiner Kallweit return -EOPNOTSUPP; 158025e992a4SHeiner Kallweit } 158125e992a4SHeiner Kallweit } 158225e992a4SHeiner Kallweit 158325e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_counters_cond) 158425e992a4SHeiner Kallweit { 158525e992a4SHeiner Kallweit return RTL_R32(tp, CounterAddrLow) & (CounterReset | CounterDump); 158625e992a4SHeiner Kallweit } 158725e992a4SHeiner Kallweit 1588d56f58ceSHeiner Kallweit static void rtl8169_do_counters(struct rtl8169_private *tp, u32 counter_cmd) 158925e992a4SHeiner Kallweit { 159025e992a4SHeiner Kallweit dma_addr_t paddr = tp->counters_phys_addr; 159125e992a4SHeiner Kallweit u32 cmd; 159225e992a4SHeiner Kallweit 159325e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32); 1594711463f8SHeiner Kallweit rtl_pci_commit(tp); 159525e992a4SHeiner Kallweit cmd = (u64)paddr & DMA_BIT_MASK(32); 159625e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrLow, cmd); 159725e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrLow, cmd | counter_cmd); 159825e992a4SHeiner Kallweit 1599d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_counters_cond, 10, 1000); 160025e992a4SHeiner Kallweit } 160125e992a4SHeiner Kallweit 1602d56f58ceSHeiner Kallweit static void rtl8169_reset_counters(struct rtl8169_private *tp) 160325e992a4SHeiner Kallweit { 160425e992a4SHeiner Kallweit /* 160525e992a4SHeiner Kallweit * Versions prior to RTL_GIGA_MAC_VER_19 don't support resetting the 160625e992a4SHeiner Kallweit * tally counters. 160725e992a4SHeiner Kallweit */ 1608d56f58ceSHeiner Kallweit if (tp->mac_version >= RTL_GIGA_MAC_VER_19) 1609d56f58ceSHeiner Kallweit rtl8169_do_counters(tp, CounterReset); 161025e992a4SHeiner Kallweit } 161125e992a4SHeiner Kallweit 1612d56f58ceSHeiner Kallweit static void rtl8169_update_counters(struct rtl8169_private *tp) 161325e992a4SHeiner Kallweit { 161425e992a4SHeiner Kallweit u8 val = RTL_R8(tp, ChipCmd); 161525e992a4SHeiner Kallweit 161625e992a4SHeiner Kallweit /* 161725e992a4SHeiner Kallweit * Some chips are unable to dump tally counters when the receiver 161825e992a4SHeiner Kallweit * is disabled. If 0xff chip may be in a PCI power-save state. 161925e992a4SHeiner Kallweit */ 1620d56f58ceSHeiner Kallweit if (val & CmdRxEnb && val != 0xff) 1621d56f58ceSHeiner Kallweit rtl8169_do_counters(tp, CounterDump); 162225e992a4SHeiner Kallweit } 162325e992a4SHeiner Kallweit 1624d56f58ceSHeiner Kallweit static void rtl8169_init_counter_offsets(struct rtl8169_private *tp) 162525e992a4SHeiner Kallweit { 162625e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 162725e992a4SHeiner Kallweit 162825e992a4SHeiner Kallweit /* 162925e992a4SHeiner Kallweit * rtl8169_init_counter_offsets is called from rtl_open. On chip 163025e992a4SHeiner Kallweit * versions prior to RTL_GIGA_MAC_VER_19 the tally counters are only 163125e992a4SHeiner Kallweit * reset by a power cycle, while the counter values collected by the 163225e992a4SHeiner Kallweit * driver are reset at every driver unload/load cycle. 163325e992a4SHeiner Kallweit * 163425e992a4SHeiner Kallweit * To make sure the HW values returned by @get_stats64 match the SW 163525e992a4SHeiner Kallweit * values, we collect the initial values at first open(*) and use them 163625e992a4SHeiner Kallweit * as offsets to normalize the values returned by @get_stats64. 163725e992a4SHeiner Kallweit * 163825e992a4SHeiner Kallweit * (*) We can't call rtl8169_init_counter_offsets from rtl_init_one 163925e992a4SHeiner Kallweit * for the reason stated in rtl8169_update_counters; CmdRxEnb is only 164025e992a4SHeiner Kallweit * set at open time by rtl_hw_start. 164125e992a4SHeiner Kallweit */ 164225e992a4SHeiner Kallweit 164325e992a4SHeiner Kallweit if (tp->tc_offset.inited) 1644d56f58ceSHeiner Kallweit return; 164525e992a4SHeiner Kallweit 1646d56f58ceSHeiner Kallweit rtl8169_reset_counters(tp); 1647d56f58ceSHeiner Kallweit rtl8169_update_counters(tp); 164825e992a4SHeiner Kallweit 164925e992a4SHeiner Kallweit tp->tc_offset.tx_errors = counters->tx_errors; 165025e992a4SHeiner Kallweit tp->tc_offset.tx_multi_collision = counters->tx_multi_collision; 165125e992a4SHeiner Kallweit tp->tc_offset.tx_aborted = counters->tx_aborted; 16520da3359aSHeiner Kallweit tp->tc_offset.rx_missed = counters->rx_missed; 165325e992a4SHeiner Kallweit tp->tc_offset.inited = true; 165425e992a4SHeiner Kallweit } 165525e992a4SHeiner Kallweit 165625e992a4SHeiner Kallweit static void rtl8169_get_ethtool_stats(struct net_device *dev, 165725e992a4SHeiner Kallweit struct ethtool_stats *stats, u64 *data) 165825e992a4SHeiner Kallweit { 165925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 166025e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 166125e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 166225e992a4SHeiner Kallweit 166325e992a4SHeiner Kallweit ASSERT_RTNL(); 166425e992a4SHeiner Kallweit 166525e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 166625e992a4SHeiner Kallweit 166725e992a4SHeiner Kallweit if (pm_runtime_active(d)) 166825e992a4SHeiner Kallweit rtl8169_update_counters(tp); 166925e992a4SHeiner Kallweit 167025e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 167125e992a4SHeiner Kallweit 167225e992a4SHeiner Kallweit data[0] = le64_to_cpu(counters->tx_packets); 167325e992a4SHeiner Kallweit data[1] = le64_to_cpu(counters->rx_packets); 167425e992a4SHeiner Kallweit data[2] = le64_to_cpu(counters->tx_errors); 167525e992a4SHeiner Kallweit data[3] = le32_to_cpu(counters->rx_errors); 167625e992a4SHeiner Kallweit data[4] = le16_to_cpu(counters->rx_missed); 167725e992a4SHeiner Kallweit data[5] = le16_to_cpu(counters->align_errors); 167825e992a4SHeiner Kallweit data[6] = le32_to_cpu(counters->tx_one_collision); 167925e992a4SHeiner Kallweit data[7] = le32_to_cpu(counters->tx_multi_collision); 168025e992a4SHeiner Kallweit data[8] = le64_to_cpu(counters->rx_unicast); 168125e992a4SHeiner Kallweit data[9] = le64_to_cpu(counters->rx_broadcast); 168225e992a4SHeiner Kallweit data[10] = le32_to_cpu(counters->rx_multicast); 168325e992a4SHeiner Kallweit data[11] = le16_to_cpu(counters->tx_aborted); 168425e992a4SHeiner Kallweit data[12] = le16_to_cpu(counters->tx_underun); 168525e992a4SHeiner Kallweit } 168625e992a4SHeiner Kallweit 168725e992a4SHeiner Kallweit static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) 168825e992a4SHeiner Kallweit { 168925e992a4SHeiner Kallweit switch(stringset) { 169025e992a4SHeiner Kallweit case ETH_SS_STATS: 169125e992a4SHeiner Kallweit memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings)); 169225e992a4SHeiner Kallweit break; 169325e992a4SHeiner Kallweit } 169425e992a4SHeiner Kallweit } 169525e992a4SHeiner Kallweit 169625e992a4SHeiner Kallweit /* 169725e992a4SHeiner Kallweit * Interrupt coalescing 169825e992a4SHeiner Kallweit * 169925e992a4SHeiner Kallweit * > 1 - the availability of the IntrMitigate (0xe2) register through the 170025e992a4SHeiner Kallweit * > 8169, 8168 and 810x line of chipsets 170125e992a4SHeiner Kallweit * 170225e992a4SHeiner Kallweit * 8169, 8168, and 8136(810x) serial chipsets support it. 170325e992a4SHeiner Kallweit * 170425e992a4SHeiner Kallweit * > 2 - the Tx timer unit at gigabit speed 170525e992a4SHeiner Kallweit * 170625e992a4SHeiner Kallweit * The unit of the timer depends on both the speed and the setting of CPlusCmd 170725e992a4SHeiner Kallweit * (0xe0) bit 1 and bit 0. 170825e992a4SHeiner Kallweit * 170925e992a4SHeiner Kallweit * For 8169 171025e992a4SHeiner Kallweit * bit[1:0] \ speed 1000M 100M 10M 171125e992a4SHeiner Kallweit * 0 0 320ns 2.56us 40.96us 171225e992a4SHeiner Kallweit * 0 1 2.56us 20.48us 327.7us 171325e992a4SHeiner Kallweit * 1 0 5.12us 40.96us 655.4us 171425e992a4SHeiner Kallweit * 1 1 10.24us 81.92us 1.31ms 171525e992a4SHeiner Kallweit * 171625e992a4SHeiner Kallweit * For the other 171725e992a4SHeiner Kallweit * bit[1:0] \ speed 1000M 100M 10M 171825e992a4SHeiner Kallweit * 0 0 5us 2.56us 40.96us 171925e992a4SHeiner Kallweit * 0 1 40us 20.48us 327.7us 172025e992a4SHeiner Kallweit * 1 0 80us 40.96us 655.4us 172125e992a4SHeiner Kallweit * 1 1 160us 81.92us 1.31ms 172225e992a4SHeiner Kallweit */ 172325e992a4SHeiner Kallweit 172425e992a4SHeiner Kallweit /* rx/tx scale factors for all CPlusCmd[0:1] cases */ 172525e992a4SHeiner Kallweit struct rtl_coalesce_info { 172625e992a4SHeiner Kallweit u32 speed; 17272815b305SHeiner Kallweit u32 scale_nsecs[4]; 172825e992a4SHeiner Kallweit }; 172925e992a4SHeiner Kallweit 17302815b305SHeiner Kallweit /* produce array with base delay *1, *8, *8*2, *8*2*2 */ 17312815b305SHeiner Kallweit #define COALESCE_DELAY(d) { (d), 8 * (d), 16 * (d), 32 * (d) } 17322815b305SHeiner Kallweit 173325e992a4SHeiner Kallweit static const struct rtl_coalesce_info rtl_coalesce_info_8169[] = { 17342815b305SHeiner Kallweit { SPEED_1000, COALESCE_DELAY(320) }, 173551f6291bSHeiner Kallweit { SPEED_100, COALESCE_DELAY(2560) }, 173651f6291bSHeiner Kallweit { SPEED_10, COALESCE_DELAY(40960) }, 173725e992a4SHeiner Kallweit { 0 }, 173825e992a4SHeiner Kallweit }; 173925e992a4SHeiner Kallweit 174025e992a4SHeiner Kallweit static const struct rtl_coalesce_info rtl_coalesce_info_8168_8136[] = { 17412815b305SHeiner Kallweit { SPEED_1000, COALESCE_DELAY(5000) }, 174251f6291bSHeiner Kallweit { SPEED_100, COALESCE_DELAY(2560) }, 174351f6291bSHeiner Kallweit { SPEED_10, COALESCE_DELAY(40960) }, 174425e992a4SHeiner Kallweit { 0 }, 174525e992a4SHeiner Kallweit }; 17462815b305SHeiner Kallweit #undef COALESCE_DELAY 174725e992a4SHeiner Kallweit 174825e992a4SHeiner Kallweit /* get rx/tx scale vector corresponding to current speed */ 1749ef2c0a78SHeiner Kallweit static const struct rtl_coalesce_info * 1750ef2c0a78SHeiner Kallweit rtl_coalesce_info(struct rtl8169_private *tp) 175125e992a4SHeiner Kallweit { 175225e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 175325e992a4SHeiner Kallweit 175420023d3eSHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 175520023d3eSHeiner Kallweit ci = rtl_coalesce_info_8169; 175620023d3eSHeiner Kallweit else 175720023d3eSHeiner Kallweit ci = rtl_coalesce_info_8168_8136; 175825e992a4SHeiner Kallweit 175951f6291bSHeiner Kallweit /* if speed is unknown assume highest one */ 176051f6291bSHeiner Kallweit if (tp->phydev->speed == SPEED_UNKNOWN) 176151f6291bSHeiner Kallweit return ci; 176251f6291bSHeiner Kallweit 176320023d3eSHeiner Kallweit for (; ci->speed; ci++) { 176420023d3eSHeiner Kallweit if (tp->phydev->speed == ci->speed) 176525e992a4SHeiner Kallweit return ci; 176625e992a4SHeiner Kallweit } 176725e992a4SHeiner Kallweit 176825e992a4SHeiner Kallweit return ERR_PTR(-ELNRNG); 176925e992a4SHeiner Kallweit } 177025e992a4SHeiner Kallweit 177125e992a4SHeiner Kallweit static int rtl_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) 177225e992a4SHeiner Kallweit { 177325e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 177425e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 17756cf96dd4SHeiner Kallweit u32 scale, c_us, c_fr; 17766cf96dd4SHeiner Kallweit u16 intrmit; 177725e992a4SHeiner Kallweit 1778f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1779f1bce4adSHeiner Kallweit return -EOPNOTSUPP; 1780f1bce4adSHeiner Kallweit 178125e992a4SHeiner Kallweit memset(ec, 0, sizeof(*ec)); 178225e992a4SHeiner Kallweit 178325e992a4SHeiner Kallweit /* get rx/tx scale corresponding to current speed and CPlusCmd[0:1] */ 1784ef2c0a78SHeiner Kallweit ci = rtl_coalesce_info(tp); 178525e992a4SHeiner Kallweit if (IS_ERR(ci)) 178625e992a4SHeiner Kallweit return PTR_ERR(ci); 178725e992a4SHeiner Kallweit 17882815b305SHeiner Kallweit scale = ci->scale_nsecs[tp->cp_cmd & INTT_MASK]; 178925e992a4SHeiner Kallweit 17906cf96dd4SHeiner Kallweit intrmit = RTL_R16(tp, IntrMitigate); 179125e992a4SHeiner Kallweit 17926cf96dd4SHeiner Kallweit c_us = FIELD_GET(RTL_COALESCE_TX_USECS, intrmit); 17936cf96dd4SHeiner Kallweit ec->tx_coalesce_usecs = DIV_ROUND_UP(c_us * scale, 1000); 179425e992a4SHeiner Kallweit 17956cf96dd4SHeiner Kallweit c_fr = FIELD_GET(RTL_COALESCE_TX_FRAMES, intrmit); 17966cf96dd4SHeiner Kallweit /* ethtool_coalesce states usecs and max_frames must not both be 0 */ 17976cf96dd4SHeiner Kallweit ec->tx_max_coalesced_frames = (c_us || c_fr) ? c_fr * 4 : 1; 17986cf96dd4SHeiner Kallweit 17996cf96dd4SHeiner Kallweit c_us = FIELD_GET(RTL_COALESCE_RX_USECS, intrmit); 18006cf96dd4SHeiner Kallweit ec->rx_coalesce_usecs = DIV_ROUND_UP(c_us * scale, 1000); 18016cf96dd4SHeiner Kallweit 18026cf96dd4SHeiner Kallweit c_fr = FIELD_GET(RTL_COALESCE_RX_FRAMES, intrmit); 18036cf96dd4SHeiner Kallweit ec->rx_max_coalesced_frames = (c_us || c_fr) ? c_fr * 4 : 1; 180425e992a4SHeiner Kallweit 180525e992a4SHeiner Kallweit return 0; 180625e992a4SHeiner Kallweit } 180725e992a4SHeiner Kallweit 1808cb9d97deSHeiner Kallweit /* choose appropriate scale factor and CPlusCmd[0:1] for (speed, usec) */ 1809cb9d97deSHeiner Kallweit static int rtl_coalesce_choose_scale(struct rtl8169_private *tp, u32 usec, 18102815b305SHeiner Kallweit u16 *cp01) 181125e992a4SHeiner Kallweit { 181225e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 181325e992a4SHeiner Kallweit u16 i; 181425e992a4SHeiner Kallweit 1815ef2c0a78SHeiner Kallweit ci = rtl_coalesce_info(tp); 181625e992a4SHeiner Kallweit if (IS_ERR(ci)) 18172815b305SHeiner Kallweit return PTR_ERR(ci); 181825e992a4SHeiner Kallweit 181925e992a4SHeiner Kallweit for (i = 0; i < 4; i++) { 1820cb9d97deSHeiner Kallweit if (usec <= ci->scale_nsecs[i] * RTL_COALESCE_T_MAX / 1000U) { 182125e992a4SHeiner Kallweit *cp01 = i; 18222815b305SHeiner Kallweit return ci->scale_nsecs[i]; 182325e992a4SHeiner Kallweit } 182425e992a4SHeiner Kallweit } 182525e992a4SHeiner Kallweit 1826cb9d97deSHeiner Kallweit return -ERANGE; 182725e992a4SHeiner Kallweit } 182825e992a4SHeiner Kallweit 182925e992a4SHeiner Kallweit static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) 183025e992a4SHeiner Kallweit { 183125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 18322b3e48b6SHeiner Kallweit u32 tx_fr = ec->tx_max_coalesced_frames; 18332b3e48b6SHeiner Kallweit u32 rx_fr = ec->rx_max_coalesced_frames; 18342b3e48b6SHeiner Kallweit u32 coal_usec_max, units; 18352815b305SHeiner Kallweit u16 w = 0, cp01 = 0; 18362b3e48b6SHeiner Kallweit int scale; 183725e992a4SHeiner Kallweit 1838f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1839f1bce4adSHeiner Kallweit return -EOPNOTSUPP; 1840f1bce4adSHeiner Kallweit 18412b3e48b6SHeiner Kallweit if (rx_fr > RTL_COALESCE_FRAME_MAX || tx_fr > RTL_COALESCE_FRAME_MAX) 18422b3e48b6SHeiner Kallweit return -ERANGE; 18432b3e48b6SHeiner Kallweit 1844cb9d97deSHeiner Kallweit coal_usec_max = max(ec->rx_coalesce_usecs, ec->tx_coalesce_usecs); 1845cb9d97deSHeiner Kallweit scale = rtl_coalesce_choose_scale(tp, coal_usec_max, &cp01); 18462815b305SHeiner Kallweit if (scale < 0) 18472815b305SHeiner Kallweit return scale; 184825e992a4SHeiner Kallweit 18492b3e48b6SHeiner Kallweit /* Accept max_frames=1 we returned in rtl_get_coalesce. Accept it 18502b3e48b6SHeiner Kallweit * not only when usecs=0 because of e.g. the following scenario: 185125e992a4SHeiner Kallweit * 185225e992a4SHeiner Kallweit * - both rx_usecs=0 & rx_frames=0 in hardware (no delay on RX) 185325e992a4SHeiner Kallweit * - rtl_get_coalesce returns rx_usecs=0, rx_frames=1 185425e992a4SHeiner Kallweit * - then user does `ethtool -C eth0 rx-usecs 100` 185525e992a4SHeiner Kallweit * 18562b3e48b6SHeiner Kallweit * Since ethtool sends to kernel whole ethtool_coalesce settings, 18572b3e48b6SHeiner Kallweit * if we want to ignore rx_frames then it has to be set to 0. 185825e992a4SHeiner Kallweit */ 18592b3e48b6SHeiner Kallweit if (rx_fr == 1) 18602b3e48b6SHeiner Kallweit rx_fr = 0; 18612b3e48b6SHeiner Kallweit if (tx_fr == 1) 18622b3e48b6SHeiner Kallweit tx_fr = 0; 186325e992a4SHeiner Kallweit 186481496b72SHeiner Kallweit /* HW requires time limit to be set if frame limit is set */ 186581496b72SHeiner Kallweit if ((tx_fr && !ec->tx_coalesce_usecs) || 186681496b72SHeiner Kallweit (rx_fr && !ec->rx_coalesce_usecs)) 186781496b72SHeiner Kallweit return -EINVAL; 186881496b72SHeiner Kallweit 18692b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_TX_FRAMES, DIV_ROUND_UP(tx_fr, 4)); 18702b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_RX_FRAMES, DIV_ROUND_UP(rx_fr, 4)); 187125e992a4SHeiner Kallweit 18722b3e48b6SHeiner Kallweit units = DIV_ROUND_UP(ec->tx_coalesce_usecs * 1000U, scale); 18732b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_TX_USECS, units); 18742b3e48b6SHeiner Kallweit units = DIV_ROUND_UP(ec->rx_coalesce_usecs * 1000U, scale); 18752b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_RX_USECS, units); 187625e992a4SHeiner Kallweit 187725e992a4SHeiner Kallweit rtl_lock_work(tp); 187825e992a4SHeiner Kallweit 18792b3e48b6SHeiner Kallweit RTL_W16(tp, IntrMitigate, w); 188025e992a4SHeiner Kallweit 18815cdfe830SHeiner Kallweit /* Meaning of PktCntrDisable bit changed from RTL8168e-vl */ 18825cdfe830SHeiner Kallweit if (rtl_is_8168evl_up(tp)) { 18835cdfe830SHeiner Kallweit if (!rx_fr && !tx_fr) 18845cdfe830SHeiner Kallweit /* disable packet counter */ 18855cdfe830SHeiner Kallweit tp->cp_cmd |= PktCntrDisable; 18865cdfe830SHeiner Kallweit else 18875cdfe830SHeiner Kallweit tp->cp_cmd &= ~PktCntrDisable; 18885cdfe830SHeiner Kallweit } 18895cdfe830SHeiner Kallweit 189025e992a4SHeiner Kallweit tp->cp_cmd = (tp->cp_cmd & ~INTT_MASK) | cp01; 189125e992a4SHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 1892711463f8SHeiner Kallweit rtl_pci_commit(tp); 189325e992a4SHeiner Kallweit 189425e992a4SHeiner Kallweit rtl_unlock_work(tp); 189525e992a4SHeiner Kallweit 189625e992a4SHeiner Kallweit return 0; 189725e992a4SHeiner Kallweit } 189825e992a4SHeiner Kallweit 189925e992a4SHeiner Kallweit static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data) 190025e992a4SHeiner Kallweit { 190125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 190225e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 190325e992a4SHeiner Kallweit int ret; 190425e992a4SHeiner Kallweit 19052e779ddbSHeiner Kallweit if (!rtl_supports_eee(tp)) 19062e779ddbSHeiner Kallweit return -EOPNOTSUPP; 19072e779ddbSHeiner Kallweit 190825e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 190925e992a4SHeiner Kallweit 191025e992a4SHeiner Kallweit if (!pm_runtime_active(d)) { 191125e992a4SHeiner Kallweit ret = -EOPNOTSUPP; 19122e779ddbSHeiner Kallweit } else { 19132e779ddbSHeiner Kallweit ret = phy_ethtool_get_eee(tp->phydev, data); 191425e992a4SHeiner Kallweit } 191525e992a4SHeiner Kallweit 191625e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 19172e779ddbSHeiner Kallweit 19182e779ddbSHeiner Kallweit return ret; 191925e992a4SHeiner Kallweit } 192025e992a4SHeiner Kallweit 192125e992a4SHeiner Kallweit static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data) 192225e992a4SHeiner Kallweit { 192325e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 192425e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 19252e779ddbSHeiner Kallweit int ret; 19262e779ddbSHeiner Kallweit 19272e779ddbSHeiner Kallweit if (!rtl_supports_eee(tp)) 19282e779ddbSHeiner Kallweit return -EOPNOTSUPP; 192925e992a4SHeiner Kallweit 193025e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 193125e992a4SHeiner Kallweit 19322e779ddbSHeiner Kallweit if (!pm_runtime_active(d)) { 193325e992a4SHeiner Kallweit ret = -EOPNOTSUPP; 193425e992a4SHeiner Kallweit goto out; 193525e992a4SHeiner Kallweit } 193625e992a4SHeiner Kallweit 19372e779ddbSHeiner Kallweit ret = phy_ethtool_set_eee(tp->phydev, data); 19387ec3f872SHeiner Kallweit 19397ec3f872SHeiner Kallweit if (!ret) 19407ec3f872SHeiner Kallweit tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN, 19417ec3f872SHeiner Kallweit MDIO_AN_EEE_ADV); 194225e992a4SHeiner Kallweit out: 194325e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 19442e779ddbSHeiner Kallweit return ret; 194525e992a4SHeiner Kallweit } 194625e992a4SHeiner Kallweit 194725e992a4SHeiner Kallweit static const struct ethtool_ops rtl8169_ethtool_ops = { 1948b604eb31SJakub Kicinski .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 1949b604eb31SJakub Kicinski ETHTOOL_COALESCE_MAX_FRAMES, 195025e992a4SHeiner Kallweit .get_drvinfo = rtl8169_get_drvinfo, 195125e992a4SHeiner Kallweit .get_regs_len = rtl8169_get_regs_len, 195225e992a4SHeiner Kallweit .get_link = ethtool_op_get_link, 195325e992a4SHeiner Kallweit .get_coalesce = rtl_get_coalesce, 195425e992a4SHeiner Kallweit .set_coalesce = rtl_set_coalesce, 195525e992a4SHeiner Kallweit .get_regs = rtl8169_get_regs, 195625e992a4SHeiner Kallweit .get_wol = rtl8169_get_wol, 195725e992a4SHeiner Kallweit .set_wol = rtl8169_set_wol, 195825e992a4SHeiner Kallweit .get_strings = rtl8169_get_strings, 195925e992a4SHeiner Kallweit .get_sset_count = rtl8169_get_sset_count, 196025e992a4SHeiner Kallweit .get_ethtool_stats = rtl8169_get_ethtool_stats, 196125e992a4SHeiner Kallweit .get_ts_info = ethtool_op_get_ts_info, 196225e992a4SHeiner Kallweit .nway_reset = phy_ethtool_nway_reset, 196325e992a4SHeiner Kallweit .get_eee = rtl8169_get_eee, 196425e992a4SHeiner Kallweit .set_eee = rtl8169_set_eee, 196525e992a4SHeiner Kallweit .get_link_ksettings = phy_ethtool_get_link_ksettings, 196625e992a4SHeiner Kallweit .set_link_ksettings = phy_ethtool_set_link_ksettings, 196725e992a4SHeiner Kallweit }; 196825e992a4SHeiner Kallweit 196925e992a4SHeiner Kallweit static void rtl_enable_eee(struct rtl8169_private *tp) 197025e992a4SHeiner Kallweit { 19712e779ddbSHeiner Kallweit struct phy_device *phydev = tp->phydev; 19727ec3f872SHeiner Kallweit int adv; 197325e992a4SHeiner Kallweit 19747ec3f872SHeiner Kallweit /* respect EEE advertisement the user may have set */ 19757ec3f872SHeiner Kallweit if (tp->eee_adv >= 0) 19767ec3f872SHeiner Kallweit adv = tp->eee_adv; 19777ec3f872SHeiner Kallweit else 19787ec3f872SHeiner Kallweit adv = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); 19797ec3f872SHeiner Kallweit 19807ec3f872SHeiner Kallweit if (adv >= 0) 19817ec3f872SHeiner Kallweit phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv); 198225e992a4SHeiner Kallweit } 198325e992a4SHeiner Kallweit 1984f1f9ca28SHeiner Kallweit static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) 198525e992a4SHeiner Kallweit { 198625e992a4SHeiner Kallweit /* 198725e992a4SHeiner Kallweit * The driver currently handles the 8168Bf and the 8168Be identically 198825e992a4SHeiner Kallweit * but they can be identified more specifically through the test below 198925e992a4SHeiner Kallweit * if needed: 199025e992a4SHeiner Kallweit * 199125e992a4SHeiner Kallweit * (RTL_R32(tp, TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be 199225e992a4SHeiner Kallweit * 199325e992a4SHeiner Kallweit * Same thing for the 8101Eb and the 8101Ec: 199425e992a4SHeiner Kallweit * 199525e992a4SHeiner Kallweit * (RTL_R32(tp, TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec 199625e992a4SHeiner Kallweit */ 199725e992a4SHeiner Kallweit static const struct rtl_mac_info { 199825e992a4SHeiner Kallweit u16 mask; 199925e992a4SHeiner Kallweit u16 val; 2000f1f9ca28SHeiner Kallweit enum mac_version ver; 200125e992a4SHeiner Kallweit } mac_info[] = { 2002f1bce4adSHeiner Kallweit /* 8125 family. */ 2003f1bce4adSHeiner Kallweit { 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 }, 2004f1bce4adSHeiner Kallweit { 0x7c8, 0x608, RTL_GIGA_MAC_VER_61 }, 2005f1bce4adSHeiner Kallweit 20061287723aSHeiner Kallweit /* RTL8117 */ 20071287723aSHeiner Kallweit { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52 }, 20081287723aSHeiner Kallweit 200925e992a4SHeiner Kallweit /* 8168EP family. */ 201025e992a4SHeiner Kallweit { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51 }, 201125e992a4SHeiner Kallweit { 0x7cf, 0x501, RTL_GIGA_MAC_VER_50 }, 201225e992a4SHeiner Kallweit { 0x7cf, 0x500, RTL_GIGA_MAC_VER_49 }, 201325e992a4SHeiner Kallweit 201425e992a4SHeiner Kallweit /* 8168H family. */ 201525e992a4SHeiner Kallweit { 0x7cf, 0x541, RTL_GIGA_MAC_VER_46 }, 201625e992a4SHeiner Kallweit { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 }, 201725e992a4SHeiner Kallweit 201825e992a4SHeiner Kallweit /* 8168G family. */ 201925e992a4SHeiner Kallweit { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 }, 202025e992a4SHeiner Kallweit { 0x7cf, 0x509, RTL_GIGA_MAC_VER_42 }, 202125e992a4SHeiner Kallweit { 0x7cf, 0x4c1, RTL_GIGA_MAC_VER_41 }, 202225e992a4SHeiner Kallweit { 0x7cf, 0x4c0, RTL_GIGA_MAC_VER_40 }, 202325e992a4SHeiner Kallweit 202425e992a4SHeiner Kallweit /* 8168F family. */ 202525e992a4SHeiner Kallweit { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38 }, 202625e992a4SHeiner Kallweit { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36 }, 202725e992a4SHeiner Kallweit { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35 }, 202825e992a4SHeiner Kallweit 202925e992a4SHeiner Kallweit /* 8168E family. */ 203025e992a4SHeiner Kallweit { 0x7c8, 0x2c8, RTL_GIGA_MAC_VER_34 }, 203125e992a4SHeiner Kallweit { 0x7cf, 0x2c1, RTL_GIGA_MAC_VER_32 }, 203225e992a4SHeiner Kallweit { 0x7c8, 0x2c0, RTL_GIGA_MAC_VER_33 }, 203325e992a4SHeiner Kallweit 203425e992a4SHeiner Kallweit /* 8168D family. */ 203525e992a4SHeiner Kallweit { 0x7cf, 0x281, RTL_GIGA_MAC_VER_25 }, 203625e992a4SHeiner Kallweit { 0x7c8, 0x280, RTL_GIGA_MAC_VER_26 }, 203725e992a4SHeiner Kallweit 203825e992a4SHeiner Kallweit /* 8168DP family. */ 203925e992a4SHeiner Kallweit { 0x7cf, 0x288, RTL_GIGA_MAC_VER_27 }, 204025e992a4SHeiner Kallweit { 0x7cf, 0x28a, RTL_GIGA_MAC_VER_28 }, 204125e992a4SHeiner Kallweit { 0x7cf, 0x28b, RTL_GIGA_MAC_VER_31 }, 204225e992a4SHeiner Kallweit 204325e992a4SHeiner Kallweit /* 8168C family. */ 204425e992a4SHeiner Kallweit { 0x7cf, 0x3c9, RTL_GIGA_MAC_VER_23 }, 204525e992a4SHeiner Kallweit { 0x7cf, 0x3c8, RTL_GIGA_MAC_VER_18 }, 204625e992a4SHeiner Kallweit { 0x7c8, 0x3c8, RTL_GIGA_MAC_VER_24 }, 204725e992a4SHeiner Kallweit { 0x7cf, 0x3c0, RTL_GIGA_MAC_VER_19 }, 204825e992a4SHeiner Kallweit { 0x7cf, 0x3c2, RTL_GIGA_MAC_VER_20 }, 204925e992a4SHeiner Kallweit { 0x7cf, 0x3c3, RTL_GIGA_MAC_VER_21 }, 205025e992a4SHeiner Kallweit { 0x7c8, 0x3c0, RTL_GIGA_MAC_VER_22 }, 205125e992a4SHeiner Kallweit 205225e992a4SHeiner Kallweit /* 8168B family. */ 205325e992a4SHeiner Kallweit { 0x7cf, 0x380, RTL_GIGA_MAC_VER_12 }, 205425e992a4SHeiner Kallweit { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 }, 205525e992a4SHeiner Kallweit { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 }, 205625e992a4SHeiner Kallweit 205725e992a4SHeiner Kallweit /* 8101 family. */ 205825e992a4SHeiner Kallweit { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 }, 205925e992a4SHeiner Kallweit { 0x7c8, 0x440, RTL_GIGA_MAC_VER_37 }, 206025e992a4SHeiner Kallweit { 0x7cf, 0x409, RTL_GIGA_MAC_VER_29 }, 206125e992a4SHeiner Kallweit { 0x7c8, 0x408, RTL_GIGA_MAC_VER_30 }, 206225e992a4SHeiner Kallweit { 0x7cf, 0x349, RTL_GIGA_MAC_VER_08 }, 206325e992a4SHeiner Kallweit { 0x7cf, 0x249, RTL_GIGA_MAC_VER_08 }, 206425e992a4SHeiner Kallweit { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 }, 206525e992a4SHeiner Kallweit { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 }, 206625e992a4SHeiner Kallweit { 0x7cf, 0x340, RTL_GIGA_MAC_VER_13 }, 20671f8492dfSHeiner Kallweit /* RTL8401, reportedly works if treated as RTL8101e */ 20681f8492dfSHeiner Kallweit { 0x7cf, 0x240, RTL_GIGA_MAC_VER_13 }, 206925e992a4SHeiner Kallweit { 0x7cf, 0x343, RTL_GIGA_MAC_VER_10 }, 207025e992a4SHeiner Kallweit { 0x7cf, 0x342, RTL_GIGA_MAC_VER_16 }, 207125e992a4SHeiner Kallweit { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 }, 207225e992a4SHeiner Kallweit { 0x7c8, 0x248, RTL_GIGA_MAC_VER_09 }, 207325e992a4SHeiner Kallweit { 0x7c8, 0x340, RTL_GIGA_MAC_VER_16 }, 207425e992a4SHeiner Kallweit /* FIXME: where did these entries come from ? -- FR */ 207525e992a4SHeiner Kallweit { 0xfc8, 0x388, RTL_GIGA_MAC_VER_15 }, 207625e992a4SHeiner Kallweit { 0xfc8, 0x308, RTL_GIGA_MAC_VER_14 }, 207725e992a4SHeiner Kallweit 207825e992a4SHeiner Kallweit /* 8110 family. */ 207925e992a4SHeiner Kallweit { 0xfc8, 0x980, RTL_GIGA_MAC_VER_06 }, 208025e992a4SHeiner Kallweit { 0xfc8, 0x180, RTL_GIGA_MAC_VER_05 }, 208125e992a4SHeiner Kallweit { 0xfc8, 0x100, RTL_GIGA_MAC_VER_04 }, 208225e992a4SHeiner Kallweit { 0xfc8, 0x040, RTL_GIGA_MAC_VER_03 }, 208325e992a4SHeiner Kallweit { 0xfc8, 0x008, RTL_GIGA_MAC_VER_02 }, 208425e992a4SHeiner Kallweit 208525e992a4SHeiner Kallweit /* Catch-all */ 208625e992a4SHeiner Kallweit { 0x000, 0x000, RTL_GIGA_MAC_NONE } 208725e992a4SHeiner Kallweit }; 208825e992a4SHeiner Kallweit const struct rtl_mac_info *p = mac_info; 2089f1f9ca28SHeiner Kallweit enum mac_version ver; 209025e992a4SHeiner Kallweit 2091f1f9ca28SHeiner Kallweit while ((xid & p->mask) != p->val) 209225e992a4SHeiner Kallweit p++; 2093f1f9ca28SHeiner Kallweit ver = p->ver; 209425e992a4SHeiner Kallweit 2095f1f9ca28SHeiner Kallweit if (ver != RTL_GIGA_MAC_NONE && !gmii) { 2096f1f9ca28SHeiner Kallweit if (ver == RTL_GIGA_MAC_VER_42) 2097f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_43; 2098f1f9ca28SHeiner Kallweit else if (ver == RTL_GIGA_MAC_VER_45) 2099f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_47; 2100f1f9ca28SHeiner Kallweit else if (ver == RTL_GIGA_MAC_VER_46) 2101f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_48; 210225e992a4SHeiner Kallweit } 2103f1f9ca28SHeiner Kallweit 2104f1f9ca28SHeiner Kallweit return ver; 210525e992a4SHeiner Kallweit } 210625e992a4SHeiner Kallweit 210725e992a4SHeiner Kallweit static void rtl_release_firmware(struct rtl8169_private *tp) 210825e992a4SHeiner Kallweit { 210925e992a4SHeiner Kallweit if (tp->rtl_fw) { 211025e992a4SHeiner Kallweit rtl_fw_release_firmware(tp->rtl_fw); 211125e992a4SHeiner Kallweit kfree(tp->rtl_fw); 211225e992a4SHeiner Kallweit tp->rtl_fw = NULL; 211325e992a4SHeiner Kallweit } 211425e992a4SHeiner Kallweit } 211525e992a4SHeiner Kallweit 21162992bdfaSHeiner Kallweit void r8169_apply_firmware(struct rtl8169_private *tp) 211725e992a4SHeiner Kallweit { 211825e992a4SHeiner Kallweit /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ 211925e992a4SHeiner Kallweit if (tp->rtl_fw) 212025e992a4SHeiner Kallweit rtl_fw_write_firmware(tp, tp->rtl_fw); 212125e992a4SHeiner Kallweit } 212225e992a4SHeiner Kallweit 212325e992a4SHeiner Kallweit static void rtl8168_config_eee_mac(struct rtl8169_private *tp) 212425e992a4SHeiner Kallweit { 212525e992a4SHeiner Kallweit /* Adjust EEE LED frequency */ 212625e992a4SHeiner Kallweit if (tp->mac_version != RTL_GIGA_MAC_VER_38) 212725e992a4SHeiner Kallweit RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07); 212825e992a4SHeiner Kallweit 212954113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, 0x0003); 213025e992a4SHeiner Kallweit } 213125e992a4SHeiner Kallweit 2132b3a42e3aSHeiner Kallweit static void rtl8125_config_eee_mac(struct rtl8169_private *tp) 2133b3a42e3aSHeiner Kallweit { 2134b3a42e3aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0)); 2135b3a42e3aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb62, 0, BIT(2) | BIT(1)); 2136b3a42e3aSHeiner Kallweit } 2137b3a42e3aSHeiner Kallweit 213825e992a4SHeiner Kallweit static void rtl_rar_exgmac_set(struct rtl8169_private *tp, u8 *addr) 213925e992a4SHeiner Kallweit { 214025e992a4SHeiner Kallweit const u16 w[] = { 214125e992a4SHeiner Kallweit addr[0] | (addr[1] << 8), 214225e992a4SHeiner Kallweit addr[2] | (addr[3] << 8), 214325e992a4SHeiner Kallweit addr[4] | (addr[5] << 8) 214425e992a4SHeiner Kallweit }; 214525e992a4SHeiner Kallweit 214625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe0, ERIAR_MASK_1111, w[0] | (w[1] << 16)); 214725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe4, ERIAR_MASK_1111, w[2]); 214825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xf0, ERIAR_MASK_1111, w[0] << 16); 214925e992a4SHeiner Kallweit rtl_eri_write(tp, 0xf4, ERIAR_MASK_1111, w[1] | (w[2] << 16)); 215025e992a4SHeiner Kallweit } 215125e992a4SHeiner Kallweit 21522992bdfaSHeiner Kallweit u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp) 21533127f7c9SHeiner Kallweit { 21543127f7c9SHeiner Kallweit u16 data1, data2, ioffset; 21553127f7c9SHeiner Kallweit 21563127f7c9SHeiner Kallweit r8168_mac_ocp_write(tp, 0xdd02, 0x807d); 21573127f7c9SHeiner Kallweit data1 = r8168_mac_ocp_read(tp, 0xdd02); 21583127f7c9SHeiner Kallweit data2 = r8168_mac_ocp_read(tp, 0xdd00); 21593127f7c9SHeiner Kallweit 21603127f7c9SHeiner Kallweit ioffset = (data2 >> 1) & 0x7ff8; 21613127f7c9SHeiner Kallweit ioffset |= data2 & 0x0007; 21623127f7c9SHeiner Kallweit if (data1 & BIT(7)) 21633127f7c9SHeiner Kallweit ioffset |= BIT(15); 21643127f7c9SHeiner Kallweit 21653127f7c9SHeiner Kallweit return ioffset; 21663127f7c9SHeiner Kallweit } 21673127f7c9SHeiner Kallweit 216825e992a4SHeiner Kallweit static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) 216925e992a4SHeiner Kallweit { 21703f6ca6c7SHeiner Kallweit set_bit(flag, tp->wk.flags); 217125e992a4SHeiner Kallweit schedule_work(&tp->wk.work); 217225e992a4SHeiner Kallweit } 217325e992a4SHeiner Kallweit 2174b5aed0b3SHeiner Kallweit static void rtl8169_init_phy(struct rtl8169_private *tp) 217525e992a4SHeiner Kallweit { 2176becd837eSHeiner Kallweit r8169_hw_phy_config(tp, tp->phydev, tp->mac_version); 217725e992a4SHeiner Kallweit 217825e992a4SHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { 217925e992a4SHeiner Kallweit pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); 218025e992a4SHeiner Kallweit pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); 2181b5aed0b3SHeiner Kallweit /* set undocumented MAC Reg C+CR Offset 0x82h */ 218225e992a4SHeiner Kallweit RTL_W8(tp, 0x82, 0x01); 218325e992a4SHeiner Kallweit } 218425e992a4SHeiner Kallweit 2185fc712387SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05 && 2186fc712387SHeiner Kallweit tp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_GIGABYTE && 2187fc712387SHeiner Kallweit tp->pci_dev->subsystem_device == 0xe000) 2188fc712387SHeiner Kallweit phy_write_paged(tp->phydev, 0x0001, 0x10, 0xf01b); 2189fc712387SHeiner Kallweit 219025e992a4SHeiner Kallweit /* We may have called phy_speed_down before */ 219125e992a4SHeiner Kallweit phy_speed_up(tp->phydev); 219225e992a4SHeiner Kallweit 2193af779778SHeiner Kallweit if (rtl_supports_eee(tp)) 2194af779778SHeiner Kallweit rtl_enable_eee(tp); 2195af779778SHeiner Kallweit 219625e992a4SHeiner Kallweit genphy_soft_reset(tp->phydev); 219725e992a4SHeiner Kallweit } 219825e992a4SHeiner Kallweit 219925e992a4SHeiner Kallweit static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) 220025e992a4SHeiner Kallweit { 220125e992a4SHeiner Kallweit rtl_lock_work(tp); 220225e992a4SHeiner Kallweit 220325e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 220425e992a4SHeiner Kallweit 220525e992a4SHeiner Kallweit RTL_W32(tp, MAC4, addr[4] | addr[5] << 8); 2206711463f8SHeiner Kallweit rtl_pci_commit(tp); 220725e992a4SHeiner Kallweit 220825e992a4SHeiner Kallweit RTL_W32(tp, MAC0, addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); 2209711463f8SHeiner Kallweit rtl_pci_commit(tp); 221025e992a4SHeiner Kallweit 221125e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34) 221225e992a4SHeiner Kallweit rtl_rar_exgmac_set(tp, addr); 221325e992a4SHeiner Kallweit 221425e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 221525e992a4SHeiner Kallweit 221625e992a4SHeiner Kallweit rtl_unlock_work(tp); 221725e992a4SHeiner Kallweit } 221825e992a4SHeiner Kallweit 221925e992a4SHeiner Kallweit static int rtl_set_mac_address(struct net_device *dev, void *p) 222025e992a4SHeiner Kallweit { 222125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 222225e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 222325e992a4SHeiner Kallweit int ret; 222425e992a4SHeiner Kallweit 222525e992a4SHeiner Kallweit ret = eth_mac_addr(dev, p); 222625e992a4SHeiner Kallweit if (ret) 222725e992a4SHeiner Kallweit return ret; 222825e992a4SHeiner Kallweit 222925e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 223025e992a4SHeiner Kallweit 223125e992a4SHeiner Kallweit if (pm_runtime_active(d)) 223225e992a4SHeiner Kallweit rtl_rar_set(tp, dev->dev_addr); 223325e992a4SHeiner Kallweit 223425e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 223525e992a4SHeiner Kallweit 223625e992a4SHeiner Kallweit return 0; 223725e992a4SHeiner Kallweit } 223825e992a4SHeiner Kallweit 223925e992a4SHeiner Kallweit static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) 224025e992a4SHeiner Kallweit { 224125e992a4SHeiner Kallweit switch (tp->mac_version) { 224225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25: 224325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_26: 224425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_29: 224525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_30: 224625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_32: 224725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_33: 224825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_34: 224900222d13SHeiner Kallweit case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_61: 225025e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | 225125e992a4SHeiner Kallweit AcceptBroadcast | AcceptMulticast | AcceptMyPhys); 225225e992a4SHeiner Kallweit break; 225325e992a4SHeiner Kallweit default: 225425e992a4SHeiner Kallweit break; 225525e992a4SHeiner Kallweit } 225625e992a4SHeiner Kallweit } 225725e992a4SHeiner Kallweit 225825e992a4SHeiner Kallweit static void rtl_pll_power_down(struct rtl8169_private *tp) 225925e992a4SHeiner Kallweit { 226025e992a4SHeiner Kallweit if (r8168_check_dash(tp)) 226125e992a4SHeiner Kallweit return; 226225e992a4SHeiner Kallweit 226325e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_32 || 226425e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_33) 226525e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x19, 0xff64); 226625e992a4SHeiner Kallweit 226725e992a4SHeiner Kallweit if (device_may_wakeup(tp_to_dev(tp))) { 226825e992a4SHeiner Kallweit phy_speed_down(tp->phydev, false); 226925e992a4SHeiner Kallweit rtl_wol_suspend_quirk(tp); 227025e992a4SHeiner Kallweit return; 227125e992a4SHeiner Kallweit } 227225e992a4SHeiner Kallweit 227325e992a4SHeiner Kallweit switch (tp->mac_version) { 227425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: 227525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_37: 227625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_39: 227725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_43: 227825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_44: 227925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_45: 228025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_46: 228125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_47: 228225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_48: 228325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_50: 228425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_51: 22851287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_52: 2286f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60: 2287f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_61: 228825e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); 228925e992a4SHeiner Kallweit break; 229025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40: 229125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_41: 229225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_49: 229354113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1a8, 0xfc000000); 229425e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); 229525e992a4SHeiner Kallweit break; 229625e992a4SHeiner Kallweit default: 229725e992a4SHeiner Kallweit break; 229825e992a4SHeiner Kallweit } 22999f0b54cdSHeiner Kallweit 23009f0b54cdSHeiner Kallweit clk_disable_unprepare(tp->clk); 230125e992a4SHeiner Kallweit } 230225e992a4SHeiner Kallweit 230325e992a4SHeiner Kallweit static void rtl_pll_power_up(struct rtl8169_private *tp) 230425e992a4SHeiner Kallweit { 23059f0b54cdSHeiner Kallweit clk_prepare_enable(tp->clk); 23069f0b54cdSHeiner Kallweit 230725e992a4SHeiner Kallweit switch (tp->mac_version) { 230825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: 230925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_37: 231025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_39: 231125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_43: 231225e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0x80); 231325e992a4SHeiner Kallweit break; 231425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_44: 231525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_45: 231625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_46: 231725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_47: 231825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_48: 231925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_50: 232025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_51: 23211287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_52: 2322f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60: 2323f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_61: 232425e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); 232525e992a4SHeiner Kallweit break; 232625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40: 232725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_41: 232825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_49: 232925e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); 233054113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x1a8, 0xfc000000); 233125e992a4SHeiner Kallweit break; 233225e992a4SHeiner Kallweit default: 233325e992a4SHeiner Kallweit break; 233425e992a4SHeiner Kallweit } 233525e992a4SHeiner Kallweit 233625e992a4SHeiner Kallweit phy_resume(tp->phydev); 233725e992a4SHeiner Kallweit } 233825e992a4SHeiner Kallweit 233925e992a4SHeiner Kallweit static void rtl_init_rxcfg(struct rtl8169_private *tp) 234025e992a4SHeiner Kallweit { 234125e992a4SHeiner Kallweit switch (tp->mac_version) { 234225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 234325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17: 234425e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX_FIFO_THRESH | RX_DMA_BURST); 234525e992a4SHeiner Kallweit break; 234625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: 234725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_36: 234825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_38: 234925e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); 235025e992a4SHeiner Kallweit break; 23511287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: 235225e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); 235325e992a4SHeiner Kallweit break; 2354f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: 235510478283SHeiner Kallweit RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST); 2356f1bce4adSHeiner Kallweit break; 235725e992a4SHeiner Kallweit default: 235825e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST); 235925e992a4SHeiner Kallweit break; 236025e992a4SHeiner Kallweit } 236125e992a4SHeiner Kallweit } 236225e992a4SHeiner Kallweit 236325e992a4SHeiner Kallweit static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) 236425e992a4SHeiner Kallweit { 236525e992a4SHeiner Kallweit tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0; 236625e992a4SHeiner Kallweit } 236725e992a4SHeiner Kallweit 236825e992a4SHeiner Kallweit static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) 236925e992a4SHeiner Kallweit { 237025e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 237125e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); 237225e992a4SHeiner Kallweit } 237325e992a4SHeiner Kallweit 237425e992a4SHeiner Kallweit static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) 237525e992a4SHeiner Kallweit { 237625e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); 237725e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); 237825e992a4SHeiner Kallweit } 237925e992a4SHeiner Kallweit 238025e992a4SHeiner Kallweit static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) 238125e992a4SHeiner Kallweit { 238225e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 238325e992a4SHeiner Kallweit } 238425e992a4SHeiner Kallweit 238525e992a4SHeiner Kallweit static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) 238625e992a4SHeiner Kallweit { 238725e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); 238825e992a4SHeiner Kallweit } 238925e992a4SHeiner Kallweit 239025e992a4SHeiner Kallweit static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) 239125e992a4SHeiner Kallweit { 239225e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, 0x3f); 239325e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 239425e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01); 239525e992a4SHeiner Kallweit } 239625e992a4SHeiner Kallweit 239725e992a4SHeiner Kallweit static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) 239825e992a4SHeiner Kallweit { 239925e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, 0x0c); 240025e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); 240125e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01); 240225e992a4SHeiner Kallweit } 240325e992a4SHeiner Kallweit 240425e992a4SHeiner Kallweit static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) 240525e992a4SHeiner Kallweit { 240625e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0)); 240725e992a4SHeiner Kallweit } 240825e992a4SHeiner Kallweit 240925e992a4SHeiner Kallweit static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) 241025e992a4SHeiner Kallweit { 241125e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0)); 241225e992a4SHeiner Kallweit } 241325e992a4SHeiner Kallweit 24149db0ac57SHeiner Kallweit static void rtl_jumbo_config(struct rtl8169_private *tp) 241525e992a4SHeiner Kallweit { 24169db0ac57SHeiner Kallweit bool jumbo = tp->dev->mtu > ETH_DATA_LEN; 24179db0ac57SHeiner Kallweit 241825e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 241925e992a4SHeiner Kallweit switch (tp->mac_version) { 242025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 242125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 24229db0ac57SHeiner Kallweit if (jumbo) { 242321b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 242425e992a4SHeiner Kallweit r8168b_1_hw_jumbo_enable(tp); 24259db0ac57SHeiner Kallweit } else { 24269db0ac57SHeiner Kallweit r8168b_1_hw_jumbo_disable(tp); 24279db0ac57SHeiner Kallweit } 242825e992a4SHeiner Kallweit break; 242925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26: 24309db0ac57SHeiner Kallweit if (jumbo) { 243121b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 243225e992a4SHeiner Kallweit r8168c_hw_jumbo_enable(tp); 24339db0ac57SHeiner Kallweit } else { 243425e992a4SHeiner Kallweit r8168c_hw_jumbo_disable(tp); 24359db0ac57SHeiner Kallweit } 243625e992a4SHeiner Kallweit break; 243725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28: 24389db0ac57SHeiner Kallweit if (jumbo) 24399db0ac57SHeiner Kallweit r8168dp_hw_jumbo_enable(tp); 24409db0ac57SHeiner Kallweit else 244125e992a4SHeiner Kallweit r8168dp_hw_jumbo_disable(tp); 244225e992a4SHeiner Kallweit break; 24430fc75219SHeiner Kallweit case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33: 24449db0ac57SHeiner Kallweit if (jumbo) { 24459db0ac57SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 24469db0ac57SHeiner Kallweit r8168e_hw_jumbo_enable(tp); 24479db0ac57SHeiner Kallweit } else { 244825e992a4SHeiner Kallweit r8168e_hw_jumbo_disable(tp); 24499db0ac57SHeiner Kallweit } 245025e992a4SHeiner Kallweit break; 245125e992a4SHeiner Kallweit default: 245225e992a4SHeiner Kallweit break; 245325e992a4SHeiner Kallweit } 245425e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 245521b5f672SHeiner Kallweit 24569db0ac57SHeiner Kallweit if (!jumbo && pci_is_pcie(tp->pci_dev) && tp->supports_gmii) 245721b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 4096); 245825e992a4SHeiner Kallweit } 245925e992a4SHeiner Kallweit 246025e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_chipcmd_cond) 246125e992a4SHeiner Kallweit { 246225e992a4SHeiner Kallweit return RTL_R8(tp, ChipCmd) & CmdReset; 246325e992a4SHeiner Kallweit } 246425e992a4SHeiner Kallweit 246525e992a4SHeiner Kallweit static void rtl_hw_reset(struct rtl8169_private *tp) 246625e992a4SHeiner Kallweit { 246725e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, CmdReset); 246825e992a4SHeiner Kallweit 2469d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100); 247025e992a4SHeiner Kallweit } 247125e992a4SHeiner Kallweit 247225e992a4SHeiner Kallweit static void rtl_request_firmware(struct rtl8169_private *tp) 247325e992a4SHeiner Kallweit { 247425e992a4SHeiner Kallweit struct rtl_fw *rtl_fw; 247525e992a4SHeiner Kallweit 247625e992a4SHeiner Kallweit /* firmware loaded already or no firmware available */ 247725e992a4SHeiner Kallweit if (tp->rtl_fw || !tp->fw_name) 247825e992a4SHeiner Kallweit return; 247925e992a4SHeiner Kallweit 248025e992a4SHeiner Kallweit rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL); 24813bf6ff3cSHeiner Kallweit if (!rtl_fw) 248225e992a4SHeiner Kallweit return; 248325e992a4SHeiner Kallweit 248425e992a4SHeiner Kallweit rtl_fw->phy_write = rtl_writephy; 248525e992a4SHeiner Kallweit rtl_fw->phy_read = rtl_readphy; 248625e992a4SHeiner Kallweit rtl_fw->mac_mcu_write = mac_mcu_write; 248725e992a4SHeiner Kallweit rtl_fw->mac_mcu_read = mac_mcu_read; 248825e992a4SHeiner Kallweit rtl_fw->fw_name = tp->fw_name; 248925e992a4SHeiner Kallweit rtl_fw->dev = tp_to_dev(tp); 249025e992a4SHeiner Kallweit 249125e992a4SHeiner Kallweit if (rtl_fw_request_firmware(rtl_fw)) 249225e992a4SHeiner Kallweit kfree(rtl_fw); 249325e992a4SHeiner Kallweit else 249425e992a4SHeiner Kallweit tp->rtl_fw = rtl_fw; 249525e992a4SHeiner Kallweit } 249625e992a4SHeiner Kallweit 249725e992a4SHeiner Kallweit static void rtl_rx_close(struct rtl8169_private *tp) 249825e992a4SHeiner Kallweit { 249925e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~RX_CONFIG_ACCEPT_MASK); 250025e992a4SHeiner Kallweit } 250125e992a4SHeiner Kallweit 250225e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_npq_cond) 250325e992a4SHeiner Kallweit { 250425e992a4SHeiner Kallweit return RTL_R8(tp, TxPoll) & NPQ; 250525e992a4SHeiner Kallweit } 250625e992a4SHeiner Kallweit 250725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_txcfg_empty_cond) 250825e992a4SHeiner Kallweit { 250925e992a4SHeiner Kallweit return RTL_R32(tp, TxConfig) & TXCFG_EMPTY; 251025e992a4SHeiner Kallweit } 251125e992a4SHeiner Kallweit 25126f9395c6SHeiner Kallweit DECLARE_RTL_COND(rtl_rxtx_empty_cond) 25136f9395c6SHeiner Kallweit { 25146f9395c6SHeiner Kallweit return (RTL_R8(tp, MCU) & RXTX_EMPTY) == RXTX_EMPTY; 25156f9395c6SHeiner Kallweit } 25166f9395c6SHeiner Kallweit 25176f9395c6SHeiner Kallweit static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp) 25186f9395c6SHeiner Kallweit { 25196f9395c6SHeiner Kallweit switch (tp->mac_version) { 25206f9395c6SHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: 25216f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42); 25226f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); 25236f9395c6SHeiner Kallweit break; 25246f9395c6SHeiner Kallweit case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: 25256f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); 25266f9395c6SHeiner Kallweit break; 25276f9395c6SHeiner Kallweit default: 25286f9395c6SHeiner Kallweit break; 25296f9395c6SHeiner Kallweit } 25306f9395c6SHeiner Kallweit } 25316f9395c6SHeiner Kallweit 25329617886fSHeiner Kallweit static void rtl_enable_rxdvgate(struct rtl8169_private *tp) 25339617886fSHeiner Kallweit { 25349617886fSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN); 25359617886fSHeiner Kallweit fsleep(2000); 25366f9395c6SHeiner Kallweit rtl_wait_txrx_fifo_empty(tp); 25379617886fSHeiner Kallweit } 25389617886fSHeiner Kallweit 253925e992a4SHeiner Kallweit static void rtl_set_tx_config_registers(struct rtl8169_private *tp) 254025e992a4SHeiner Kallweit { 254125e992a4SHeiner Kallweit u32 val = TX_DMA_BURST << TxDMAShift | 254225e992a4SHeiner Kallweit InterFrameGap << TxInterFrameGapShift; 254325e992a4SHeiner Kallweit 25449e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp)) 254525e992a4SHeiner Kallweit val |= TXCFG_AUTO_FIFO; 254625e992a4SHeiner Kallweit 254725e992a4SHeiner Kallweit RTL_W32(tp, TxConfig, val); 254825e992a4SHeiner Kallweit } 254925e992a4SHeiner Kallweit 255025e992a4SHeiner Kallweit static void rtl_set_rx_max_size(struct rtl8169_private *tp) 255125e992a4SHeiner Kallweit { 255225e992a4SHeiner Kallweit /* Low hurts. Let's disable the filtering. */ 255325e992a4SHeiner Kallweit RTL_W16(tp, RxMaxSize, R8169_RX_BUF_SIZE + 1); 255425e992a4SHeiner Kallweit } 255525e992a4SHeiner Kallweit 255625e992a4SHeiner Kallweit static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp) 255725e992a4SHeiner Kallweit { 255825e992a4SHeiner Kallweit /* 255925e992a4SHeiner Kallweit * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh 256025e992a4SHeiner Kallweit * register to be written before TxDescAddrLow to work. 256125e992a4SHeiner Kallweit * Switching from MMIO to I/O access fixes the issue as well. 256225e992a4SHeiner Kallweit */ 256325e992a4SHeiner Kallweit RTL_W32(tp, TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32); 256425e992a4SHeiner Kallweit RTL_W32(tp, TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32)); 256525e992a4SHeiner Kallweit RTL_W32(tp, RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32); 256625e992a4SHeiner Kallweit RTL_W32(tp, RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32)); 256725e992a4SHeiner Kallweit } 256825e992a4SHeiner Kallweit 2569ef891284SHeiner Kallweit static void rtl8169_set_magic_reg(struct rtl8169_private *tp) 257025e992a4SHeiner Kallweit { 257125e992a4SHeiner Kallweit u32 val; 257225e992a4SHeiner Kallweit 257325e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05) 257425e992a4SHeiner Kallweit val = 0x000fff00; 257525e992a4SHeiner Kallweit else if (tp->mac_version == RTL_GIGA_MAC_VER_06) 257625e992a4SHeiner Kallweit val = 0x00ffff00; 257725e992a4SHeiner Kallweit else 257825e992a4SHeiner Kallweit return; 257925e992a4SHeiner Kallweit 258025e992a4SHeiner Kallweit if (RTL_R8(tp, Config2) & PCI_Clock_66MHz) 258125e992a4SHeiner Kallweit val |= 0xff; 258225e992a4SHeiner Kallweit 258325e992a4SHeiner Kallweit RTL_W32(tp, 0x7c, val); 258425e992a4SHeiner Kallweit } 258525e992a4SHeiner Kallweit 258625e992a4SHeiner Kallweit static void rtl_set_rx_mode(struct net_device *dev) 258725e992a4SHeiner Kallweit { 258881cd17a4SHeiner Kallweit u32 rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast; 258981cd17a4SHeiner Kallweit /* Multicast hash filter */ 259081cd17a4SHeiner Kallweit u32 mc_filter[2] = { 0xffffffff, 0xffffffff }; 259125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 259281cd17a4SHeiner Kallweit u32 tmp; 259325e992a4SHeiner Kallweit 259425e992a4SHeiner Kallweit if (dev->flags & IFF_PROMISC) { 259581cd17a4SHeiner Kallweit rx_mode |= AcceptAllPhys; 259681cd17a4SHeiner Kallweit } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || 259781cd17a4SHeiner Kallweit dev->flags & IFF_ALLMULTI || 259881cd17a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_35) { 259981cd17a4SHeiner Kallweit /* accept all multicasts */ 260081cd17a4SHeiner Kallweit } else if (netdev_mc_empty(dev)) { 260181cd17a4SHeiner Kallweit rx_mode &= ~AcceptMulticast; 260225e992a4SHeiner Kallweit } else { 260325e992a4SHeiner Kallweit struct netdev_hw_addr *ha; 260425e992a4SHeiner Kallweit 260525e992a4SHeiner Kallweit mc_filter[1] = mc_filter[0] = 0; 260625e992a4SHeiner Kallweit netdev_for_each_mc_addr(ha, dev) { 2607bc54ac36SHeiner Kallweit u32 bit_nr = eth_hw_addr_crc(ha) >> 26; 260881cd17a4SHeiner Kallweit mc_filter[bit_nr >> 5] |= BIT(bit_nr & 31); 260981cd17a4SHeiner Kallweit } 261081cd17a4SHeiner Kallweit 261181cd17a4SHeiner Kallweit if (tp->mac_version > RTL_GIGA_MAC_VER_06) { 261281cd17a4SHeiner Kallweit tmp = mc_filter[0]; 261381cd17a4SHeiner Kallweit mc_filter[0] = swab32(mc_filter[1]); 261481cd17a4SHeiner Kallweit mc_filter[1] = swab32(tmp); 261525e992a4SHeiner Kallweit } 261625e992a4SHeiner Kallweit } 261725e992a4SHeiner Kallweit 261825e992a4SHeiner Kallweit RTL_W32(tp, MAR0 + 4, mc_filter[1]); 261925e992a4SHeiner Kallweit RTL_W32(tp, MAR0 + 0, mc_filter[0]); 262025e992a4SHeiner Kallweit 262181cd17a4SHeiner Kallweit tmp = RTL_R32(tp, RxConfig); 262210478283SHeiner Kallweit RTL_W32(tp, RxConfig, (tmp & ~RX_CONFIG_ACCEPT_OK_MASK) | rx_mode); 262325e992a4SHeiner Kallweit } 262425e992a4SHeiner Kallweit 262525e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_csiar_cond) 262625e992a4SHeiner Kallweit { 262725e992a4SHeiner Kallweit return RTL_R32(tp, CSIAR) & CSIAR_FLAG; 262825e992a4SHeiner Kallweit } 262925e992a4SHeiner Kallweit 263025e992a4SHeiner Kallweit static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value) 263125e992a4SHeiner Kallweit { 263225e992a4SHeiner Kallweit u32 func = PCI_FUNC(tp->pci_dev->devfn); 263325e992a4SHeiner Kallweit 263425e992a4SHeiner Kallweit RTL_W32(tp, CSIDR, value); 263525e992a4SHeiner Kallweit RTL_W32(tp, CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | 263625e992a4SHeiner Kallweit CSIAR_BYTE_ENABLE | func << 16); 263725e992a4SHeiner Kallweit 2638d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_csiar_cond, 10, 100); 263925e992a4SHeiner Kallweit } 264025e992a4SHeiner Kallweit 264125e992a4SHeiner Kallweit static u32 rtl_csi_read(struct rtl8169_private *tp, int addr) 264225e992a4SHeiner Kallweit { 264325e992a4SHeiner Kallweit u32 func = PCI_FUNC(tp->pci_dev->devfn); 264425e992a4SHeiner Kallweit 264525e992a4SHeiner Kallweit RTL_W32(tp, CSIAR, (addr & CSIAR_ADDR_MASK) | func << 16 | 264625e992a4SHeiner Kallweit CSIAR_BYTE_ENABLE); 264725e992a4SHeiner Kallweit 2648d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ? 264925e992a4SHeiner Kallweit RTL_R32(tp, CSIDR) : ~0; 265025e992a4SHeiner Kallweit } 265125e992a4SHeiner Kallweit 265225e992a4SHeiner Kallweit static void rtl_csi_access_enable(struct rtl8169_private *tp, u8 val) 265325e992a4SHeiner Kallweit { 265425e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 265525e992a4SHeiner Kallweit u32 csi; 265625e992a4SHeiner Kallweit 265725e992a4SHeiner Kallweit /* According to Realtek the value at config space address 0x070f 265825e992a4SHeiner Kallweit * controls the L0s/L1 entrance latency. We try standard ECAM access 265925e992a4SHeiner Kallweit * first and if it fails fall back to CSI. 266025e992a4SHeiner Kallweit */ 266125e992a4SHeiner Kallweit if (pdev->cfg_size > 0x070f && 266225e992a4SHeiner Kallweit pci_write_config_byte(pdev, 0x070f, val) == PCIBIOS_SUCCESSFUL) 266325e992a4SHeiner Kallweit return; 266425e992a4SHeiner Kallweit 266525e992a4SHeiner Kallweit netdev_notice_once(tp->dev, 266625e992a4SHeiner Kallweit "No native access to PCI extended config space, falling back to CSI\n"); 266725e992a4SHeiner Kallweit csi = rtl_csi_read(tp, 0x070c) & 0x00ffffff; 266825e992a4SHeiner Kallweit rtl_csi_write(tp, 0x070c, csi | val << 24); 266925e992a4SHeiner Kallweit } 267025e992a4SHeiner Kallweit 267125e992a4SHeiner Kallweit static void rtl_set_def_aspm_entry_latency(struct rtl8169_private *tp) 267225e992a4SHeiner Kallweit { 267325e992a4SHeiner Kallweit rtl_csi_access_enable(tp, 0x27); 267425e992a4SHeiner Kallweit } 267525e992a4SHeiner Kallweit 267625e992a4SHeiner Kallweit struct ephy_info { 267725e992a4SHeiner Kallweit unsigned int offset; 267825e992a4SHeiner Kallweit u16 mask; 267925e992a4SHeiner Kallweit u16 bits; 268025e992a4SHeiner Kallweit }; 268125e992a4SHeiner Kallweit 268225e992a4SHeiner Kallweit static void __rtl_ephy_init(struct rtl8169_private *tp, 268325e992a4SHeiner Kallweit const struct ephy_info *e, int len) 268425e992a4SHeiner Kallweit { 268525e992a4SHeiner Kallweit u16 w; 268625e992a4SHeiner Kallweit 268725e992a4SHeiner Kallweit while (len-- > 0) { 268825e992a4SHeiner Kallweit w = (rtl_ephy_read(tp, e->offset) & ~e->mask) | e->bits; 268925e992a4SHeiner Kallweit rtl_ephy_write(tp, e->offset, w); 269025e992a4SHeiner Kallweit e++; 269125e992a4SHeiner Kallweit } 269225e992a4SHeiner Kallweit } 269325e992a4SHeiner Kallweit 269425e992a4SHeiner Kallweit #define rtl_ephy_init(tp, a) __rtl_ephy_init(tp, a, ARRAY_SIZE(a)) 269525e992a4SHeiner Kallweit 269625e992a4SHeiner Kallweit static void rtl_disable_clock_request(struct rtl8169_private *tp) 269725e992a4SHeiner Kallweit { 269825e992a4SHeiner Kallweit pcie_capability_clear_word(tp->pci_dev, PCI_EXP_LNKCTL, 269925e992a4SHeiner Kallweit PCI_EXP_LNKCTL_CLKREQ_EN); 270025e992a4SHeiner Kallweit } 270125e992a4SHeiner Kallweit 270225e992a4SHeiner Kallweit static void rtl_enable_clock_request(struct rtl8169_private *tp) 270325e992a4SHeiner Kallweit { 270425e992a4SHeiner Kallweit pcie_capability_set_word(tp->pci_dev, PCI_EXP_LNKCTL, 270525e992a4SHeiner Kallweit PCI_EXP_LNKCTL_CLKREQ_EN); 270625e992a4SHeiner Kallweit } 270725e992a4SHeiner Kallweit 270825e992a4SHeiner Kallweit static void rtl_pcie_state_l2l3_disable(struct rtl8169_private *tp) 270925e992a4SHeiner Kallweit { 271025e992a4SHeiner Kallweit /* work around an issue when PCI reset occurs during L2/L3 state */ 271125e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Rdy_to_L23); 271225e992a4SHeiner Kallweit } 271325e992a4SHeiner Kallweit 271425e992a4SHeiner Kallweit static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) 271525e992a4SHeiner Kallweit { 271662b1b3b3SHeiner Kallweit /* Don't enable ASPM in the chip if OS can't control ASPM */ 271762b1b3b3SHeiner Kallweit if (enable && tp->aspm_manageable) { 271825e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) | ASPM_en); 271925e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) | ClkReqEn); 272025e992a4SHeiner Kallweit } else { 272125e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn); 272225e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en); 272325e992a4SHeiner Kallweit } 272425e992a4SHeiner Kallweit 272525e992a4SHeiner Kallweit udelay(10); 272625e992a4SHeiner Kallweit } 272725e992a4SHeiner Kallweit 272825e992a4SHeiner Kallweit static void rtl_set_fifo_size(struct rtl8169_private *tp, u16 rx_stat, 272925e992a4SHeiner Kallweit u16 tx_stat, u16 rx_dyn, u16 tx_dyn) 273025e992a4SHeiner Kallweit { 273125e992a4SHeiner Kallweit /* Usage of dynamic vs. static FIFO is controlled by bit 273225e992a4SHeiner Kallweit * TXCFG_AUTO_FIFO. Exact meaning of FIFO values isn't known. 273325e992a4SHeiner Kallweit */ 273425e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, (rx_stat << 16) | rx_dyn); 273525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, (tx_stat << 16) | tx_dyn); 273625e992a4SHeiner Kallweit } 273725e992a4SHeiner Kallweit 273825e992a4SHeiner Kallweit static void rtl8168g_set_pause_thresholds(struct rtl8169_private *tp, 273925e992a4SHeiner Kallweit u8 low, u8 high) 274025e992a4SHeiner Kallweit { 274125e992a4SHeiner Kallweit /* FIFO thresholds for pause flow control */ 274225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, low); 274325e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, high); 274425e992a4SHeiner Kallweit } 274525e992a4SHeiner Kallweit 274694b5ff74SHeiner Kallweit static void rtl_hw_start_8168b(struct rtl8169_private *tp) 274725e992a4SHeiner Kallweit { 274825e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 274925e992a4SHeiner Kallweit } 275025e992a4SHeiner Kallweit 275125e992a4SHeiner Kallweit static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) 275225e992a4SHeiner Kallweit { 275325e992a4SHeiner Kallweit RTL_W8(tp, Config1, RTL_R8(tp, Config1) | Speed_down); 275425e992a4SHeiner Kallweit 275525e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 275625e992a4SHeiner Kallweit 275725e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 275825e992a4SHeiner Kallweit } 275925e992a4SHeiner Kallweit 276025e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) 276125e992a4SHeiner Kallweit { 276225e992a4SHeiner Kallweit static const struct ephy_info e_info_8168cp[] = { 276325e992a4SHeiner Kallweit { 0x01, 0, 0x0001 }, 276425e992a4SHeiner Kallweit { 0x02, 0x0800, 0x1000 }, 276525e992a4SHeiner Kallweit { 0x03, 0, 0x0042 }, 276625e992a4SHeiner Kallweit { 0x06, 0x0080, 0x0000 }, 276725e992a4SHeiner Kallweit { 0x07, 0, 0x2000 } 276825e992a4SHeiner Kallweit }; 276925e992a4SHeiner Kallweit 277025e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 277125e992a4SHeiner Kallweit 277225e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168cp); 277325e992a4SHeiner Kallweit 277425e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 277525e992a4SHeiner Kallweit } 277625e992a4SHeiner Kallweit 277725e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) 277825e992a4SHeiner Kallweit { 277925e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 278025e992a4SHeiner Kallweit 278125e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 278225e992a4SHeiner Kallweit } 278325e992a4SHeiner Kallweit 278425e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) 278525e992a4SHeiner Kallweit { 278625e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 278725e992a4SHeiner Kallweit 278825e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 278925e992a4SHeiner Kallweit 279025e992a4SHeiner Kallweit /* Magic. */ 279125e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, 0x20); 279225e992a4SHeiner Kallweit } 279325e992a4SHeiner Kallweit 279425e992a4SHeiner Kallweit static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) 279525e992a4SHeiner Kallweit { 279625e992a4SHeiner Kallweit static const struct ephy_info e_info_8168c_1[] = { 279725e992a4SHeiner Kallweit { 0x02, 0x0800, 0x1000 }, 279825e992a4SHeiner Kallweit { 0x03, 0, 0x0002 }, 279925e992a4SHeiner Kallweit { 0x06, 0x0080, 0x0000 } 280025e992a4SHeiner Kallweit }; 280125e992a4SHeiner Kallweit 280225e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 280325e992a4SHeiner Kallweit 280425e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); 280525e992a4SHeiner Kallweit 280625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168c_1); 280725e992a4SHeiner Kallweit 280825e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 280925e992a4SHeiner Kallweit } 281025e992a4SHeiner Kallweit 281125e992a4SHeiner Kallweit static void rtl_hw_start_8168c_2(struct rtl8169_private *tp) 281225e992a4SHeiner Kallweit { 281325e992a4SHeiner Kallweit static const struct ephy_info e_info_8168c_2[] = { 281425e992a4SHeiner Kallweit { 0x01, 0, 0x0001 }, 2815a7a92cf8SHeiner Kallweit { 0x03, 0x0400, 0x0020 } 281625e992a4SHeiner Kallweit }; 281725e992a4SHeiner Kallweit 281825e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 281925e992a4SHeiner Kallweit 282025e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168c_2); 282125e992a4SHeiner Kallweit 282225e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 282325e992a4SHeiner Kallweit } 282425e992a4SHeiner Kallweit 282525e992a4SHeiner Kallweit static void rtl_hw_start_8168c_3(struct rtl8169_private *tp) 282625e992a4SHeiner Kallweit { 282725e992a4SHeiner Kallweit rtl_hw_start_8168c_2(tp); 282825e992a4SHeiner Kallweit } 282925e992a4SHeiner Kallweit 283025e992a4SHeiner Kallweit static void rtl_hw_start_8168c_4(struct rtl8169_private *tp) 283125e992a4SHeiner Kallweit { 283225e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 283325e992a4SHeiner Kallweit 283425e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 283525e992a4SHeiner Kallweit } 283625e992a4SHeiner Kallweit 283725e992a4SHeiner Kallweit static void rtl_hw_start_8168d(struct rtl8169_private *tp) 283825e992a4SHeiner Kallweit { 283925e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 284025e992a4SHeiner Kallweit 284125e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 284225e992a4SHeiner Kallweit } 284325e992a4SHeiner Kallweit 284425e992a4SHeiner Kallweit static void rtl_hw_start_8168d_4(struct rtl8169_private *tp) 284525e992a4SHeiner Kallweit { 284625e992a4SHeiner Kallweit static const struct ephy_info e_info_8168d_4[] = { 284725e992a4SHeiner Kallweit { 0x0b, 0x0000, 0x0048 }, 284825e992a4SHeiner Kallweit { 0x19, 0x0020, 0x0050 }, 2849a7a92cf8SHeiner Kallweit { 0x0c, 0x0100, 0x0020 }, 2850a7a92cf8SHeiner Kallweit { 0x10, 0x0004, 0x0000 }, 285125e992a4SHeiner Kallweit }; 285225e992a4SHeiner Kallweit 285325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 285425e992a4SHeiner Kallweit 285525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168d_4); 285625e992a4SHeiner Kallweit 285725e992a4SHeiner Kallweit rtl_enable_clock_request(tp); 285825e992a4SHeiner Kallweit } 285925e992a4SHeiner Kallweit 286025e992a4SHeiner Kallweit static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) 286125e992a4SHeiner Kallweit { 286225e992a4SHeiner Kallweit static const struct ephy_info e_info_8168e_1[] = { 286325e992a4SHeiner Kallweit { 0x00, 0x0200, 0x0100 }, 286425e992a4SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 286525e992a4SHeiner Kallweit { 0x06, 0x0002, 0x0001 }, 286625e992a4SHeiner Kallweit { 0x06, 0x0000, 0x0030 }, 286725e992a4SHeiner Kallweit { 0x07, 0x0000, 0x2000 }, 286825e992a4SHeiner Kallweit { 0x00, 0x0000, 0x0020 }, 286925e992a4SHeiner Kallweit { 0x03, 0x5800, 0x2000 }, 287025e992a4SHeiner Kallweit { 0x03, 0x0000, 0x0001 }, 287125e992a4SHeiner Kallweit { 0x01, 0x0800, 0x1000 }, 287225e992a4SHeiner Kallweit { 0x07, 0x0000, 0x4000 }, 287325e992a4SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 287425e992a4SHeiner Kallweit { 0x19, 0xffff, 0xfe6c }, 287525e992a4SHeiner Kallweit { 0x0a, 0x0000, 0x0040 } 287625e992a4SHeiner Kallweit }; 287725e992a4SHeiner Kallweit 287825e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 287925e992a4SHeiner Kallweit 288025e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168e_1); 288125e992a4SHeiner Kallweit 288225e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 288325e992a4SHeiner Kallweit 288425e992a4SHeiner Kallweit /* Reset tx FIFO pointer */ 288525e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | TXPLA_RST); 288625e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~TXPLA_RST); 288725e992a4SHeiner Kallweit 288825e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 288925e992a4SHeiner Kallweit } 289025e992a4SHeiner Kallweit 289125e992a4SHeiner Kallweit static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) 289225e992a4SHeiner Kallweit { 289325e992a4SHeiner Kallweit static const struct ephy_info e_info_8168e_2[] = { 289425e992a4SHeiner Kallweit { 0x09, 0x0000, 0x0080 }, 2895a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2896a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2897a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 289825e992a4SHeiner Kallweit }; 289925e992a4SHeiner Kallweit 290025e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 290125e992a4SHeiner Kallweit 290225e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168e_2); 290325e992a4SHeiner Kallweit 290425e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 290533b00ca1SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_1111, 0x0000); 290625e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); 290733b00ca1SHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, 0x1f00); 290833b00ca1SHeiner Kallweit rtl_eri_set_bits(tp, 0x1d0, BIT(1)); 290933b00ca1SHeiner Kallweit rtl_reset_packet_filter(tp); 291033b00ca1SHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, BIT(4)); 291125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050); 291225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x07ff0060); 291325e992a4SHeiner Kallweit 291425e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 291525e992a4SHeiner Kallweit 291625e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 291725e992a4SHeiner Kallweit 291825e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 291925e992a4SHeiner Kallweit 292025e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 292125e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN); 292225e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 292325e992a4SHeiner Kallweit 292425e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 292525e992a4SHeiner Kallweit } 292625e992a4SHeiner Kallweit 292725e992a4SHeiner Kallweit static void rtl_hw_start_8168f(struct rtl8169_private *tp) 292825e992a4SHeiner Kallweit { 292925e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 293025e992a4SHeiner Kallweit 293125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 2932d05890c5SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_1111, 0x0000); 293325e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); 293425e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 293554113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, BIT(4)); 2936d05890c5SHeiner Kallweit rtl_eri_set_bits(tp, 0x1d0, BIT(4) | BIT(1)); 293725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050); 293825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060); 293925e992a4SHeiner Kallweit 294025e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 294125e992a4SHeiner Kallweit 294225e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 294325e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 294425e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN); 294525e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 294625e992a4SHeiner Kallweit 294725e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 294825e992a4SHeiner Kallweit } 294925e992a4SHeiner Kallweit 295025e992a4SHeiner Kallweit static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) 295125e992a4SHeiner Kallweit { 295225e992a4SHeiner Kallweit static const struct ephy_info e_info_8168f_1[] = { 295325e992a4SHeiner Kallweit { 0x06, 0x00c0, 0x0020 }, 295425e992a4SHeiner Kallweit { 0x08, 0x0001, 0x0002 }, 295525e992a4SHeiner Kallweit { 0x09, 0x0000, 0x0080 }, 2956a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2957a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2958a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 295925e992a4SHeiner Kallweit }; 296025e992a4SHeiner Kallweit 296125e992a4SHeiner Kallweit rtl_hw_start_8168f(tp); 296225e992a4SHeiner Kallweit 296325e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168f_1); 296425e992a4SHeiner Kallweit 2965d05890c5SHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, 0x1f00); 296625e992a4SHeiner Kallweit } 296725e992a4SHeiner Kallweit 296825e992a4SHeiner Kallweit static void rtl_hw_start_8411(struct rtl8169_private *tp) 296925e992a4SHeiner Kallweit { 297025e992a4SHeiner Kallweit static const struct ephy_info e_info_8168f_1[] = { 297125e992a4SHeiner Kallweit { 0x06, 0x00c0, 0x0020 }, 297225e992a4SHeiner Kallweit { 0x0f, 0xffff, 0x5200 }, 2973a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2974a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2975a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 297625e992a4SHeiner Kallweit }; 297725e992a4SHeiner Kallweit 297825e992a4SHeiner Kallweit rtl_hw_start_8168f(tp); 297925e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 298025e992a4SHeiner Kallweit 298125e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168f_1); 298225e992a4SHeiner Kallweit 298354113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, 0x0c00); 298425e992a4SHeiner Kallweit } 298525e992a4SHeiner Kallweit 298625e992a4SHeiner Kallweit static void rtl_hw_start_8168g(struct rtl8169_private *tp) 298725e992a4SHeiner Kallweit { 298825e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 298925e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x38, 0x48); 299025e992a4SHeiner Kallweit 299125e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 299225e992a4SHeiner Kallweit 299325e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 299425e992a4SHeiner Kallweit rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f); 299525e992a4SHeiner Kallweit 299625e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 299725e992a4SHeiner Kallweit 299825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 299925e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 3000d29d5ff9SHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, 0x1f80); 300125e992a4SHeiner Kallweit 300225e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 300325e992a4SHeiner Kallweit 300454113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x2fc, 0x01, 0x06); 300554113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12)); 300625e992a4SHeiner Kallweit 300725e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 300825e992a4SHeiner Kallweit } 300925e992a4SHeiner Kallweit 301025e992a4SHeiner Kallweit static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) 301125e992a4SHeiner Kallweit { 301225e992a4SHeiner Kallweit static const struct ephy_info e_info_8168g_1[] = { 3013a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 3014a7a92cf8SHeiner Kallweit { 0x0c, 0x3ff0, 0x0820 }, 301525e992a4SHeiner Kallweit { 0x1e, 0x0000, 0x0001 }, 301625e992a4SHeiner Kallweit { 0x19, 0x8000, 0x0000 } 301725e992a4SHeiner Kallweit }; 301825e992a4SHeiner Kallweit 301925e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 302025e992a4SHeiner Kallweit 302125e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 302225e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 302325e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168g_1); 302425e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 302525e992a4SHeiner Kallweit } 302625e992a4SHeiner Kallweit 302725e992a4SHeiner Kallweit static void rtl_hw_start_8168g_2(struct rtl8169_private *tp) 302825e992a4SHeiner Kallweit { 302925e992a4SHeiner Kallweit static const struct ephy_info e_info_8168g_2[] = { 3030a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 3031a7a92cf8SHeiner Kallweit { 0x0c, 0x3ff0, 0x0820 }, 3032a7a92cf8SHeiner Kallweit { 0x19, 0xffff, 0x7c00 }, 3033a7a92cf8SHeiner Kallweit { 0x1e, 0xffff, 0x20eb }, 3034a7a92cf8SHeiner Kallweit { 0x0d, 0xffff, 0x1666 }, 3035a7a92cf8SHeiner Kallweit { 0x00, 0xffff, 0x10a3 }, 3036a7a92cf8SHeiner Kallweit { 0x06, 0xffff, 0xf050 }, 3037a7a92cf8SHeiner Kallweit { 0x04, 0x0000, 0x0010 }, 3038a7a92cf8SHeiner Kallweit { 0x1d, 0x4000, 0x0000 }, 303925e992a4SHeiner Kallweit }; 304025e992a4SHeiner Kallweit 304125e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 304225e992a4SHeiner Kallweit 304325e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 3044ebdcebcbSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 304525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168g_2); 304625e992a4SHeiner Kallweit } 304725e992a4SHeiner Kallweit 304825e992a4SHeiner Kallweit static void rtl_hw_start_8411_2(struct rtl8169_private *tp) 304925e992a4SHeiner Kallweit { 305025e992a4SHeiner Kallweit static const struct ephy_info e_info_8411_2[] = { 3051a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 3052a7a92cf8SHeiner Kallweit { 0x0c, 0x37d0, 0x0820 }, 3053a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x0001 }, 3054a7a92cf8SHeiner Kallweit { 0x19, 0x8021, 0x0000 }, 3055a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 3056a7a92cf8SHeiner Kallweit { 0x0d, 0x0100, 0x0200 }, 3057a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0080 }, 3058a7a92cf8SHeiner Kallweit { 0x06, 0x0000, 0x0010 }, 3059a7a92cf8SHeiner Kallweit { 0x04, 0x0000, 0x0010 }, 3060a7a92cf8SHeiner Kallweit { 0x1d, 0x0000, 0x4000 }, 306125e992a4SHeiner Kallweit }; 306225e992a4SHeiner Kallweit 306325e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 306425e992a4SHeiner Kallweit 306525e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 306625e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 306725e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8411_2); 3068fe4e8db0SHeiner Kallweit 3069fe4e8db0SHeiner Kallweit /* The following Realtek-provided magic fixes an issue with the RX unit 3070fe4e8db0SHeiner Kallweit * getting confused after the PHY having been powered-down. 3071fe4e8db0SHeiner Kallweit */ 3072fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC28, 0x0000); 3073fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2A, 0x0000); 3074fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2C, 0x0000); 3075fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2E, 0x0000); 3076fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC30, 0x0000); 3077fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC32, 0x0000); 3078fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC34, 0x0000); 3079fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC36, 0x0000); 3080fe4e8db0SHeiner Kallweit mdelay(3); 3081fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC26, 0x0000); 3082fe4e8db0SHeiner Kallweit 3083fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF800, 0xE008); 3084fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF802, 0xE00A); 3085fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF804, 0xE00C); 3086fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF806, 0xE00E); 3087fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF808, 0xE027); 3088fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80A, 0xE04F); 3089fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80C, 0xE05E); 3090fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80E, 0xE065); 3091fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF810, 0xC602); 3092fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF812, 0xBE00); 3093fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF814, 0x0000); 3094fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF816, 0xC502); 3095fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF818, 0xBD00); 3096fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81A, 0x074C); 3097fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81C, 0xC302); 3098fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81E, 0xBB00); 3099fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF820, 0x080A); 3100fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF822, 0x6420); 3101fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF824, 0x48C2); 3102fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF826, 0x8C20); 3103fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF828, 0xC516); 3104fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82A, 0x64A4); 3105fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82C, 0x49C0); 3106fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82E, 0xF009); 3107fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF830, 0x74A2); 3108fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF832, 0x8CA5); 3109fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF834, 0x74A0); 3110fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF836, 0xC50E); 3111fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF838, 0x9CA2); 3112fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83A, 0x1C11); 3113fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83C, 0x9CA0); 3114fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83E, 0xE006); 3115fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF840, 0x74F8); 3116fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF842, 0x48C4); 3117fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF844, 0x8CF8); 3118fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF846, 0xC404); 3119fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF848, 0xBC00); 3120fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84A, 0xC403); 3121fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84C, 0xBC00); 3122fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84E, 0x0BF2); 3123fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF850, 0x0C0A); 3124fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF852, 0xE434); 3125fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF854, 0xD3C0); 3126fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF856, 0x49D9); 3127fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF858, 0xF01F); 3128fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85A, 0xC526); 3129fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85C, 0x64A5); 3130fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85E, 0x1400); 3131fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF860, 0xF007); 3132fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF862, 0x0C01); 3133fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF864, 0x8CA5); 3134fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF866, 0x1C15); 3135fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF868, 0xC51B); 3136fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86A, 0x9CA0); 3137fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86C, 0xE013); 3138fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86E, 0xC519); 3139fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF870, 0x74A0); 3140fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF872, 0x48C4); 3141fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF874, 0x8CA0); 3142fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF876, 0xC516); 3143fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF878, 0x74A4); 3144fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87A, 0x48C8); 3145fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87C, 0x48CA); 3146fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87E, 0x9CA4); 3147fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF880, 0xC512); 3148fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF882, 0x1B00); 3149fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF884, 0x9BA0); 3150fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF886, 0x1B1C); 3151fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF888, 0x483F); 3152fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88A, 0x9BA2); 3153fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88C, 0x1B04); 3154fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88E, 0xC508); 3155fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF890, 0x9BA0); 3156fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF892, 0xC505); 3157fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF894, 0xBD00); 3158fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF896, 0xC502); 3159fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF898, 0xBD00); 3160fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89A, 0x0300); 3161fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89C, 0x051E); 3162fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89E, 0xE434); 3163fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A0, 0xE018); 3164fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A2, 0xE092); 3165fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A4, 0xDE20); 3166fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A6, 0xD3C0); 3167fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A8, 0xC50F); 3168fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AA, 0x76A4); 3169fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AC, 0x49E3); 3170fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AE, 0xF007); 3171fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B0, 0x49C0); 3172fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B2, 0xF103); 3173fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B4, 0xC607); 3174fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B6, 0xBE00); 3175fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B8, 0xC606); 3176fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BA, 0xBE00); 3177fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BC, 0xC602); 3178fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BE, 0xBE00); 3179fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C0, 0x0C4C); 3180fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C2, 0x0C28); 3181fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C4, 0x0C2C); 3182fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C6, 0xDC00); 3183fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C8, 0xC707); 3184fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CA, 0x1D00); 3185fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CC, 0x8DE2); 3186fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CE, 0x48C1); 3187fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D0, 0xC502); 3188fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D2, 0xBD00); 3189fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D4, 0x00AA); 3190fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D6, 0xE0C0); 3191fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D8, 0xC502); 3192fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8DA, 0xBD00); 3193fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8DC, 0x0132); 3194fe4e8db0SHeiner Kallweit 3195fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC26, 0x8000); 3196fe4e8db0SHeiner Kallweit 3197fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2A, 0x0743); 3198fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2C, 0x0801); 3199fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2E, 0x0BE9); 3200fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC30, 0x02FD); 3201fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC32, 0x0C25); 3202fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC34, 0x00A9); 3203fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC36, 0x012D); 3204fe4e8db0SHeiner Kallweit 320525e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 320625e992a4SHeiner Kallweit } 320725e992a4SHeiner Kallweit 320825e992a4SHeiner Kallweit static void rtl_hw_start_8168h_1(struct rtl8169_private *tp) 320925e992a4SHeiner Kallweit { 321025e992a4SHeiner Kallweit static const struct ephy_info e_info_8168h_1[] = { 321125e992a4SHeiner Kallweit { 0x1e, 0x0800, 0x0001 }, 321225e992a4SHeiner Kallweit { 0x1d, 0x0000, 0x0800 }, 321325e992a4SHeiner Kallweit { 0x05, 0xffff, 0x2089 }, 321425e992a4SHeiner Kallweit { 0x06, 0xffff, 0x5881 }, 3215a7a92cf8SHeiner Kallweit { 0x04, 0xffff, 0x854a }, 321625e992a4SHeiner Kallweit { 0x01, 0xffff, 0x068b } 321725e992a4SHeiner Kallweit }; 3218ef712edeSHeiner Kallweit int rg_saw_cnt; 321925e992a4SHeiner Kallweit 322025e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 322125e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 322225e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168h_1); 322325e992a4SHeiner Kallweit 322425e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 322525e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x38, 0x48); 322625e992a4SHeiner Kallweit 322725e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 322825e992a4SHeiner Kallweit 322925e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 323025e992a4SHeiner Kallweit 323154113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x1f00); 3232ee1350f9SHeiner Kallweit rtl_eri_set_bits(tp, 0xdc, 0x001c); 323325e992a4SHeiner Kallweit 323425e992a4SHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 323525e992a4SHeiner Kallweit 323625e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 323725e992a4SHeiner Kallweit 323825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 323925e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 324025e992a4SHeiner Kallweit 324125e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 324225e992a4SHeiner Kallweit 324325e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 324425e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 324525e992a4SHeiner Kallweit 324625e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 324725e992a4SHeiner Kallweit 324854113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12)); 324925e992a4SHeiner Kallweit 325025e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 325125e992a4SHeiner Kallweit 32523ab077d2SHeiner Kallweit rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff; 325325e992a4SHeiner Kallweit if (rg_saw_cnt > 0) { 325425e992a4SHeiner Kallweit u16 sw_cnt_1ms_ini; 325525e992a4SHeiner Kallweit 325625e992a4SHeiner Kallweit sw_cnt_1ms_ini = 16000000/rg_saw_cnt; 325725e992a4SHeiner Kallweit sw_cnt_1ms_ini &= 0x0fff; 3258ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini); 325925e992a4SHeiner Kallweit } 326025e992a4SHeiner Kallweit 3261ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070); 3262ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x6000, 0x8008); 3263ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe0d6, 0x01ff, 0x017f); 3264ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f); 326525e992a4SHeiner Kallweit 326625e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0001); 326725e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0000); 326825e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xc094, 0x0000); 326925e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xc09e, 0x0000); 327025e992a4SHeiner Kallweit 327125e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 327225e992a4SHeiner Kallweit } 327325e992a4SHeiner Kallweit 327425e992a4SHeiner Kallweit static void rtl_hw_start_8168ep(struct rtl8169_private *tp) 327525e992a4SHeiner Kallweit { 327625e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp); 327725e992a4SHeiner Kallweit 327825e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 327925e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f); 328025e992a4SHeiner Kallweit 328125e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 328225e992a4SHeiner Kallweit 328325e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 328425e992a4SHeiner Kallweit 328554113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x1f80); 328625e992a4SHeiner Kallweit 328725e992a4SHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 328825e992a4SHeiner Kallweit 328925e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 329025e992a4SHeiner Kallweit 329125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 329225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 329325e992a4SHeiner Kallweit 329425e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 329525e992a4SHeiner Kallweit 329654113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x2fc, 0x01, 0x06); 329725e992a4SHeiner Kallweit 329825e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 329925e992a4SHeiner Kallweit 330025e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 330125e992a4SHeiner Kallweit } 330225e992a4SHeiner Kallweit 330325e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_1(struct rtl8169_private *tp) 330425e992a4SHeiner Kallweit { 330525e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_1[] = { 330625e992a4SHeiner Kallweit { 0x00, 0xffff, 0x10ab }, 330725e992a4SHeiner Kallweit { 0x06, 0xffff, 0xf030 }, 330825e992a4SHeiner Kallweit { 0x08, 0xffff, 0x2006 }, 330925e992a4SHeiner Kallweit { 0x0d, 0xffff, 0x1666 }, 331025e992a4SHeiner Kallweit { 0x0c, 0x3ff0, 0x0000 } 331125e992a4SHeiner Kallweit }; 331225e992a4SHeiner Kallweit 331325e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 331425e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 331525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_1); 331625e992a4SHeiner Kallweit 331725e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 331825e992a4SHeiner Kallweit 331925e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 332025e992a4SHeiner Kallweit } 332125e992a4SHeiner Kallweit 332225e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_2(struct rtl8169_private *tp) 332325e992a4SHeiner Kallweit { 332425e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_2[] = { 332525e992a4SHeiner Kallweit { 0x00, 0xffff, 0x10a3 }, 332625e992a4SHeiner Kallweit { 0x19, 0xffff, 0xfc00 }, 332725e992a4SHeiner Kallweit { 0x1e, 0xffff, 0x20ea } 332825e992a4SHeiner Kallweit }; 332925e992a4SHeiner Kallweit 333025e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 333125e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 333225e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_2); 333325e992a4SHeiner Kallweit 333425e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 333525e992a4SHeiner Kallweit 333625e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 333725e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 333825e992a4SHeiner Kallweit 333925e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 334025e992a4SHeiner Kallweit } 334125e992a4SHeiner Kallweit 334225e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp) 334325e992a4SHeiner Kallweit { 334425e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_3[] = { 3345a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0080 }, 3346a7a92cf8SHeiner Kallweit { 0x0d, 0x0100, 0x0200 }, 3347a7a92cf8SHeiner Kallweit { 0x19, 0x8021, 0x0000 }, 3348a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 334925e992a4SHeiner Kallweit }; 335025e992a4SHeiner Kallweit 335125e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 335225e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 335325e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_3); 335425e992a4SHeiner Kallweit 335525e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 335625e992a4SHeiner Kallweit 335725e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 335825e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 335925e992a4SHeiner Kallweit 3360ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e2, 0x0fff, 0x0271); 3361ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e4, 0x00ff, 0x0000); 3362ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe860, 0x0000, 0x0080); 336325e992a4SHeiner Kallweit 336425e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 336525e992a4SHeiner Kallweit } 336625e992a4SHeiner Kallweit 33671287723aSHeiner Kallweit static void rtl_hw_start_8117(struct rtl8169_private *tp) 33681287723aSHeiner Kallweit { 33691287723aSHeiner Kallweit static const struct ephy_info e_info_8117[] = { 33701287723aSHeiner Kallweit { 0x19, 0x0040, 0x1100 }, 33711287723aSHeiner Kallweit { 0x59, 0x0040, 0x1100 }, 33721287723aSHeiner Kallweit }; 33731287723aSHeiner Kallweit int rg_saw_cnt; 33741287723aSHeiner Kallweit 33751287723aSHeiner Kallweit rtl8168ep_stop_cmac(tp); 33761287723aSHeiner Kallweit 33771287723aSHeiner Kallweit /* disable aspm and clock request before access ephy */ 33781287723aSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 33791287723aSHeiner Kallweit rtl_ephy_init(tp, e_info_8117); 33801287723aSHeiner Kallweit 33811287723aSHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 33821287723aSHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f); 33831287723aSHeiner Kallweit 33841287723aSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 33851287723aSHeiner Kallweit 33861287723aSHeiner Kallweit rtl_reset_packet_filter(tp); 33871287723aSHeiner Kallweit 338854113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x1f90); 33891287723aSHeiner Kallweit 33901287723aSHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 33911287723aSHeiner Kallweit 33921287723aSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 33931287723aSHeiner Kallweit 33941287723aSHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 33951287723aSHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 33961287723aSHeiner Kallweit 33971287723aSHeiner Kallweit rtl8168_config_eee_mac(tp); 33981287723aSHeiner Kallweit 33991287723aSHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 34001287723aSHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 34011287723aSHeiner Kallweit 34021287723aSHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 34031287723aSHeiner Kallweit 340454113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12)); 34051287723aSHeiner Kallweit 34061287723aSHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 34071287723aSHeiner Kallweit 34081287723aSHeiner Kallweit rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff; 34091287723aSHeiner Kallweit if (rg_saw_cnt > 0) { 34101287723aSHeiner Kallweit u16 sw_cnt_1ms_ini; 34111287723aSHeiner Kallweit 34121287723aSHeiner Kallweit sw_cnt_1ms_ini = (16000000 / rg_saw_cnt) & 0x0fff; 34131287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini); 34141287723aSHeiner Kallweit } 34151287723aSHeiner Kallweit 34161287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070); 34171287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xea80, 0x0003); 34181287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x0000, 0x0009); 34191287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f); 34201287723aSHeiner Kallweit 34211287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0001); 34221287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0000); 34231287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc094, 0x0000); 34241287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc09e, 0x0000); 34251287723aSHeiner Kallweit 3426229c1e0dSHeiner Kallweit /* firmware is for MAC only */ 34271c5be5e9SHeiner Kallweit r8169_apply_firmware(tp); 3428229c1e0dSHeiner Kallweit 34291287723aSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 34301287723aSHeiner Kallweit } 34311287723aSHeiner Kallweit 343225e992a4SHeiner Kallweit static void rtl_hw_start_8102e_1(struct rtl8169_private *tp) 343325e992a4SHeiner Kallweit { 343425e992a4SHeiner Kallweit static const struct ephy_info e_info_8102e_1[] = { 343525e992a4SHeiner Kallweit { 0x01, 0, 0x6e65 }, 343625e992a4SHeiner Kallweit { 0x02, 0, 0x091f }, 343725e992a4SHeiner Kallweit { 0x03, 0, 0xc2f9 }, 343825e992a4SHeiner Kallweit { 0x06, 0, 0xafb5 }, 343925e992a4SHeiner Kallweit { 0x07, 0, 0x0e00 }, 344025e992a4SHeiner Kallweit { 0x19, 0, 0xec80 }, 344125e992a4SHeiner Kallweit { 0x01, 0, 0x2e65 }, 344225e992a4SHeiner Kallweit { 0x01, 0, 0x6e65 } 344325e992a4SHeiner Kallweit }; 344425e992a4SHeiner Kallweit u8 cfg1; 344525e992a4SHeiner Kallweit 344625e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 344725e992a4SHeiner Kallweit 344825e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, FIX_NAK_1); 344925e992a4SHeiner Kallweit 345025e992a4SHeiner Kallweit RTL_W8(tp, Config1, 345125e992a4SHeiner Kallweit LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable); 345225e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 345325e992a4SHeiner Kallweit 345425e992a4SHeiner Kallweit cfg1 = RTL_R8(tp, Config1); 345525e992a4SHeiner Kallweit if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) 345625e992a4SHeiner Kallweit RTL_W8(tp, Config1, cfg1 & ~LEDS0); 345725e992a4SHeiner Kallweit 345825e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8102e_1); 345925e992a4SHeiner Kallweit } 346025e992a4SHeiner Kallweit 346125e992a4SHeiner Kallweit static void rtl_hw_start_8102e_2(struct rtl8169_private *tp) 346225e992a4SHeiner Kallweit { 346325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 346425e992a4SHeiner Kallweit 346525e992a4SHeiner Kallweit RTL_W8(tp, Config1, MEMMAP | IOMAP | VPD | PMEnable); 346625e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 346725e992a4SHeiner Kallweit } 346825e992a4SHeiner Kallweit 346925e992a4SHeiner Kallweit static void rtl_hw_start_8102e_3(struct rtl8169_private *tp) 347025e992a4SHeiner Kallweit { 347125e992a4SHeiner Kallweit rtl_hw_start_8102e_2(tp); 347225e992a4SHeiner Kallweit 347325e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x03, 0xc2f9); 347425e992a4SHeiner Kallweit } 347525e992a4SHeiner Kallweit 347625e992a4SHeiner Kallweit static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) 347725e992a4SHeiner Kallweit { 347825e992a4SHeiner Kallweit static const struct ephy_info e_info_8105e_1[] = { 347925e992a4SHeiner Kallweit { 0x07, 0, 0x4000 }, 348025e992a4SHeiner Kallweit { 0x19, 0, 0x0200 }, 348125e992a4SHeiner Kallweit { 0x19, 0, 0x0020 }, 348225e992a4SHeiner Kallweit { 0x1e, 0, 0x2000 }, 348325e992a4SHeiner Kallweit { 0x03, 0, 0x0001 }, 348425e992a4SHeiner Kallweit { 0x19, 0, 0x0100 }, 348525e992a4SHeiner Kallweit { 0x19, 0, 0x0004 }, 348625e992a4SHeiner Kallweit { 0x0a, 0, 0x0020 } 348725e992a4SHeiner Kallweit }; 348825e992a4SHeiner Kallweit 348925e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 349025e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 349125e992a4SHeiner Kallweit 349225e992a4SHeiner Kallweit /* Disable Early Tally Counter */ 349325e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) & ~0x010000); 349425e992a4SHeiner Kallweit 349525e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET); 349625e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 349725e992a4SHeiner Kallweit 349825e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8105e_1); 349925e992a4SHeiner Kallweit 350025e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 350125e992a4SHeiner Kallweit } 350225e992a4SHeiner Kallweit 350325e992a4SHeiner Kallweit static void rtl_hw_start_8105e_2(struct rtl8169_private *tp) 350425e992a4SHeiner Kallweit { 350525e992a4SHeiner Kallweit rtl_hw_start_8105e_1(tp); 350625e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x1e, rtl_ephy_read(tp, 0x1e) | 0x8000); 350725e992a4SHeiner Kallweit } 350825e992a4SHeiner Kallweit 350925e992a4SHeiner Kallweit static void rtl_hw_start_8402(struct rtl8169_private *tp) 351025e992a4SHeiner Kallweit { 351125e992a4SHeiner Kallweit static const struct ephy_info e_info_8402[] = { 351225e992a4SHeiner Kallweit { 0x19, 0xffff, 0xff64 }, 351325e992a4SHeiner Kallweit { 0x1e, 0, 0x4000 } 351425e992a4SHeiner Kallweit }; 351525e992a4SHeiner Kallweit 351625e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 351725e992a4SHeiner Kallweit 351825e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 351925e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 352025e992a4SHeiner Kallweit 352125e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 352225e992a4SHeiner Kallweit 352325e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8402); 352425e992a4SHeiner Kallweit 352525e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x00, 0x00, 0x02, 0x06); 352625e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 352725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 352825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 352954113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x0d4, 0x0e00, 0xff00); 353025e992a4SHeiner Kallweit 35316d7a631eSHeiner Kallweit /* disable EEE */ 35326d7a631eSHeiner Kallweit rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000); 35336d7a631eSHeiner Kallweit 353425e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 353525e992a4SHeiner Kallweit } 353625e992a4SHeiner Kallweit 353725e992a4SHeiner Kallweit static void rtl_hw_start_8106(struct rtl8169_private *tp) 353825e992a4SHeiner Kallweit { 353925e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 354025e992a4SHeiner Kallweit 354125e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 354225e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 354325e992a4SHeiner Kallweit 354425e992a4SHeiner Kallweit RTL_W32(tp, MISC, (RTL_R32(tp, MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN); 354525e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET); 354625e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 354725e992a4SHeiner Kallweit 35488d46f620SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000); 35498d46f620SHeiner Kallweit 35506d7a631eSHeiner Kallweit /* disable EEE */ 35516d7a631eSHeiner Kallweit rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000); 35526d7a631eSHeiner Kallweit 355325e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 355425e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 355525e992a4SHeiner Kallweit } 355625e992a4SHeiner Kallweit 3557f1bce4adSHeiner Kallweit DECLARE_RTL_COND(rtl_mac_ocp_e00e_cond) 3558f1bce4adSHeiner Kallweit { 3559f1bce4adSHeiner Kallweit return r8168_mac_ocp_read(tp, 0xe00e) & BIT(13); 3560f1bce4adSHeiner Kallweit } 3561f1bce4adSHeiner Kallweit 3562f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_common(struct rtl8169_private *tp) 3563f1bce4adSHeiner Kallweit { 3564f1bce4adSHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 3565f1bce4adSHeiner Kallweit 3566f1bce4adSHeiner Kallweit RTL_W16(tp, 0x382, 0x221b); 3567f1bce4adSHeiner Kallweit RTL_W8(tp, 0x4500, 0); 3568f1bce4adSHeiner Kallweit RTL_W16(tp, 0x4800, 0); 3569f1bce4adSHeiner Kallweit 3570f1bce4adSHeiner Kallweit /* disable UPS */ 3571f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd40a, 0x0010, 0x0000); 3572f1bce4adSHeiner Kallweit 3573f1bce4adSHeiner Kallweit RTL_W8(tp, Config1, RTL_R8(tp, Config1) & ~0x10); 3574f1bce4adSHeiner Kallweit 3575f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc140, 0xffff); 3576f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc142, 0xffff); 3577f1bce4adSHeiner Kallweit 3578f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e2, 0x0fff, 0x03a9); 3579f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e4, 0x00ff, 0x0000); 3580f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe860, 0x0000, 0x0080); 3581f1bce4adSHeiner Kallweit 3582f1bce4adSHeiner Kallweit /* disable new tx descriptor format */ 3583f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000); 3584f1bce4adSHeiner Kallweit 3585f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400); 3586f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0020); 3587f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b4, 0x0000, 0x000c); 3588f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb6a, 0x00ff, 0x0033); 3589f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb50, 0x03e0, 0x0040); 3590f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); 3591f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); 3592f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403); 3593f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0067); 3594f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0ac, 0x0080, 0x1f00); 3595f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f); 3596f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe84c, 0x0000, 0x00c0); 3597f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000); 3598f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb54, 0x0000, 0x0001); 3599f1bce4adSHeiner Kallweit udelay(1); 3600f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb54, 0x0001, 0x0000); 3601f1bce4adSHeiner Kallweit RTL_W16(tp, 0x1880, RTL_R16(tp, 0x1880) & ~0x0030); 3602f1bce4adSHeiner Kallweit 3603f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe098, 0xc302); 3604f1bce4adSHeiner Kallweit 3605d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10); 3606f1bce4adSHeiner Kallweit 3607b3a42e3aSHeiner Kallweit rtl8125_config_eee_mac(tp); 3608b3a42e3aSHeiner Kallweit 3609f1bce4adSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 3610f1bce4adSHeiner Kallweit udelay(10); 3611f1bce4adSHeiner Kallweit } 3612f1bce4adSHeiner Kallweit 3613f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_1(struct rtl8169_private *tp) 3614f1bce4adSHeiner Kallweit { 3615f1bce4adSHeiner Kallweit static const struct ephy_info e_info_8125_1[] = { 3616f1bce4adSHeiner Kallweit { 0x01, 0xffff, 0xa812 }, 3617f1bce4adSHeiner Kallweit { 0x09, 0xffff, 0x520c }, 3618f1bce4adSHeiner Kallweit { 0x04, 0xffff, 0xd000 }, 3619f1bce4adSHeiner Kallweit { 0x0d, 0xffff, 0xf702 }, 3620f1bce4adSHeiner Kallweit { 0x0a, 0xffff, 0x8653 }, 3621f1bce4adSHeiner Kallweit { 0x06, 0xffff, 0x001e }, 3622f1bce4adSHeiner Kallweit { 0x08, 0xffff, 0x3595 }, 3623f1bce4adSHeiner Kallweit { 0x20, 0xffff, 0x9455 }, 3624f1bce4adSHeiner Kallweit { 0x21, 0xffff, 0x99ff }, 3625f1bce4adSHeiner Kallweit { 0x02, 0xffff, 0x6046 }, 3626f1bce4adSHeiner Kallweit { 0x29, 0xffff, 0xfe00 }, 3627f1bce4adSHeiner Kallweit { 0x23, 0xffff, 0xab62 }, 3628f1bce4adSHeiner Kallweit 3629f1bce4adSHeiner Kallweit { 0x41, 0xffff, 0xa80c }, 3630f1bce4adSHeiner Kallweit { 0x49, 0xffff, 0x520c }, 3631f1bce4adSHeiner Kallweit { 0x44, 0xffff, 0xd000 }, 3632f1bce4adSHeiner Kallweit { 0x4d, 0xffff, 0xf702 }, 3633f1bce4adSHeiner Kallweit { 0x4a, 0xffff, 0x8653 }, 3634f1bce4adSHeiner Kallweit { 0x46, 0xffff, 0x001e }, 3635f1bce4adSHeiner Kallweit { 0x48, 0xffff, 0x3595 }, 3636f1bce4adSHeiner Kallweit { 0x60, 0xffff, 0x9455 }, 3637f1bce4adSHeiner Kallweit { 0x61, 0xffff, 0x99ff }, 3638f1bce4adSHeiner Kallweit { 0x42, 0xffff, 0x6046 }, 3639f1bce4adSHeiner Kallweit { 0x69, 0xffff, 0xfe00 }, 3640f1bce4adSHeiner Kallweit { 0x63, 0xffff, 0xab62 }, 3641f1bce4adSHeiner Kallweit }; 3642f1bce4adSHeiner Kallweit 3643f1bce4adSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 3644f1bce4adSHeiner Kallweit 3645f1bce4adSHeiner Kallweit /* disable aspm and clock request before access ephy */ 3646f1bce4adSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 3647f1bce4adSHeiner Kallweit rtl_ephy_init(tp, e_info_8125_1); 3648f1bce4adSHeiner Kallweit 3649f1bce4adSHeiner Kallweit rtl_hw_start_8125_common(tp); 3650f1bce4adSHeiner Kallweit } 3651f1bce4adSHeiner Kallweit 3652f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_2(struct rtl8169_private *tp) 3653f1bce4adSHeiner Kallweit { 3654f1bce4adSHeiner Kallweit static const struct ephy_info e_info_8125_2[] = { 3655f1bce4adSHeiner Kallweit { 0x04, 0xffff, 0xd000 }, 3656f1bce4adSHeiner Kallweit { 0x0a, 0xffff, 0x8653 }, 3657f1bce4adSHeiner Kallweit { 0x23, 0xffff, 0xab66 }, 3658f1bce4adSHeiner Kallweit { 0x20, 0xffff, 0x9455 }, 3659f1bce4adSHeiner Kallweit { 0x21, 0xffff, 0x99ff }, 3660f1bce4adSHeiner Kallweit { 0x29, 0xffff, 0xfe04 }, 3661f1bce4adSHeiner Kallweit 3662f1bce4adSHeiner Kallweit { 0x44, 0xffff, 0xd000 }, 3663f1bce4adSHeiner Kallweit { 0x4a, 0xffff, 0x8653 }, 3664f1bce4adSHeiner Kallweit { 0x63, 0xffff, 0xab66 }, 3665f1bce4adSHeiner Kallweit { 0x60, 0xffff, 0x9455 }, 3666f1bce4adSHeiner Kallweit { 0x61, 0xffff, 0x99ff }, 3667f1bce4adSHeiner Kallweit { 0x69, 0xffff, 0xfe04 }, 3668f1bce4adSHeiner Kallweit }; 3669f1bce4adSHeiner Kallweit 3670f1bce4adSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 3671f1bce4adSHeiner Kallweit 3672f1bce4adSHeiner Kallweit /* disable aspm and clock request before access ephy */ 3673f1bce4adSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 3674f1bce4adSHeiner Kallweit rtl_ephy_init(tp, e_info_8125_2); 3675f1bce4adSHeiner Kallweit 3676f1bce4adSHeiner Kallweit rtl_hw_start_8125_common(tp); 3677f1bce4adSHeiner Kallweit } 3678f1bce4adSHeiner Kallweit 367925e992a4SHeiner Kallweit static void rtl_hw_config(struct rtl8169_private *tp) 368025e992a4SHeiner Kallweit { 368125e992a4SHeiner Kallweit static const rtl_generic_fct hw_configs[] = { 368225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_07] = rtl_hw_start_8102e_1, 368325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_08] = rtl_hw_start_8102e_3, 368425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_09] = rtl_hw_start_8102e_2, 368525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_10] = NULL, 368694b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b, 368794b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_12] = rtl_hw_start_8168b, 368825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_13] = NULL, 368925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_14] = NULL, 369025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_15] = NULL, 369125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_16] = NULL, 369294b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b, 369325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1, 369425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_19] = rtl_hw_start_8168c_1, 369525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_20] = rtl_hw_start_8168c_2, 369625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_21] = rtl_hw_start_8168c_3, 369725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_22] = rtl_hw_start_8168c_4, 369825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_23] = rtl_hw_start_8168cp_2, 369925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_24] = rtl_hw_start_8168cp_3, 370025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_25] = rtl_hw_start_8168d, 370125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_26] = rtl_hw_start_8168d, 370225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_27] = rtl_hw_start_8168d, 370325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_28] = rtl_hw_start_8168d_4, 370425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_29] = rtl_hw_start_8105e_1, 370525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_30] = rtl_hw_start_8105e_2, 37060a413e6bSHeiner Kallweit [RTL_GIGA_MAC_VER_31] = rtl_hw_start_8168d, 370725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_32] = rtl_hw_start_8168e_1, 370825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_33] = rtl_hw_start_8168e_1, 370925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_34] = rtl_hw_start_8168e_2, 371025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_35] = rtl_hw_start_8168f_1, 371125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_36] = rtl_hw_start_8168f_1, 371225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_37] = rtl_hw_start_8402, 371325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_38] = rtl_hw_start_8411, 371425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_39] = rtl_hw_start_8106, 371525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_40] = rtl_hw_start_8168g_1, 371625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_41] = rtl_hw_start_8168g_1, 371725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_42] = rtl_hw_start_8168g_2, 371825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_43] = rtl_hw_start_8168g_2, 371925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_44] = rtl_hw_start_8411_2, 372025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_45] = rtl_hw_start_8168h_1, 372125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_46] = rtl_hw_start_8168h_1, 372225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_47] = rtl_hw_start_8168h_1, 372325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_48] = rtl_hw_start_8168h_1, 372425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_49] = rtl_hw_start_8168ep_1, 372525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_50] = rtl_hw_start_8168ep_2, 372625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3, 37271287723aSHeiner Kallweit [RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117, 3728f1bce4adSHeiner Kallweit [RTL_GIGA_MAC_VER_60] = rtl_hw_start_8125_1, 3729f1bce4adSHeiner Kallweit [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125_2, 373025e992a4SHeiner Kallweit }; 373125e992a4SHeiner Kallweit 373225e992a4SHeiner Kallweit if (hw_configs[tp->mac_version]) 373325e992a4SHeiner Kallweit hw_configs[tp->mac_version](tp); 373425e992a4SHeiner Kallweit } 373525e992a4SHeiner Kallweit 3736f1bce4adSHeiner Kallweit static void rtl_hw_start_8125(struct rtl8169_private *tp) 3737f1bce4adSHeiner Kallweit { 3738f1bce4adSHeiner Kallweit int i; 3739f1bce4adSHeiner Kallweit 3740f1bce4adSHeiner Kallweit /* disable interrupt coalescing */ 3741f1bce4adSHeiner Kallweit for (i = 0xa00; i < 0xb00; i += 4) 3742f1bce4adSHeiner Kallweit RTL_W32(tp, i, 0); 3743f1bce4adSHeiner Kallweit 3744f1bce4adSHeiner Kallweit rtl_hw_config(tp); 3745f1bce4adSHeiner Kallweit } 3746f1bce4adSHeiner Kallweit 374725e992a4SHeiner Kallweit static void rtl_hw_start_8168(struct rtl8169_private *tp) 374825e992a4SHeiner Kallweit { 3749272b2265SHeiner Kallweit if (rtl_is_8168evl_up(tp)) 3750272b2265SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, EarlySize); 3751272b2265SHeiner Kallweit else 375225e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, TxPacketMax); 375325e992a4SHeiner Kallweit 375425e992a4SHeiner Kallweit rtl_hw_config(tp); 3755bcf2b868SHeiner Kallweit 3756bcf2b868SHeiner Kallweit /* disable interrupt coalescing */ 3757bcf2b868SHeiner Kallweit RTL_W16(tp, IntrMitigate, 0x0000); 375825e992a4SHeiner Kallweit } 375925e992a4SHeiner Kallweit 37606c19156eSHeiner Kallweit static void rtl_hw_start_8169(struct rtl8169_private *tp) 37616c19156eSHeiner Kallweit { 37626c19156eSHeiner Kallweit RTL_W8(tp, EarlyTxThres, NoEarlyTx); 37636c19156eSHeiner Kallweit 37646c19156eSHeiner Kallweit tp->cp_cmd |= PCIMulRW; 37656c19156eSHeiner Kallweit 37666c19156eSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_02 || 376709e65335SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_03) 376809e65335SHeiner Kallweit tp->cp_cmd |= EnAnaPLL; 37696c19156eSHeiner Kallweit 37706c19156eSHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 37716c19156eSHeiner Kallweit 3772ef891284SHeiner Kallweit rtl8169_set_magic_reg(tp); 37736c19156eSHeiner Kallweit 3774bcf2b868SHeiner Kallweit /* disable interrupt coalescing */ 3775bcf2b868SHeiner Kallweit RTL_W16(tp, IntrMitigate, 0x0000); 37766c19156eSHeiner Kallweit } 37776c19156eSHeiner Kallweit 37786c19156eSHeiner Kallweit static void rtl_hw_start(struct rtl8169_private *tp) 37796c19156eSHeiner Kallweit { 37806c19156eSHeiner Kallweit rtl_unlock_config_regs(tp); 37816c19156eSHeiner Kallweit 37826c19156eSHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 37836c19156eSHeiner Kallweit 37846c19156eSHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 37856c19156eSHeiner Kallweit rtl_hw_start_8169(tp); 3786f1bce4adSHeiner Kallweit else if (rtl_is_8125(tp)) 3787f1bce4adSHeiner Kallweit rtl_hw_start_8125(tp); 37886c19156eSHeiner Kallweit else 37896c19156eSHeiner Kallweit rtl_hw_start_8168(tp); 37906c19156eSHeiner Kallweit 37916c19156eSHeiner Kallweit rtl_set_rx_max_size(tp); 37926c19156eSHeiner Kallweit rtl_set_rx_tx_desc_registers(tp); 37936c19156eSHeiner Kallweit rtl_lock_config_regs(tp); 37946c19156eSHeiner Kallweit 37959db0ac57SHeiner Kallweit rtl_jumbo_config(tp); 37964ebcb113SHeiner Kallweit 37976c19156eSHeiner Kallweit /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ 3798711463f8SHeiner Kallweit rtl_pci_commit(tp); 3799711463f8SHeiner Kallweit 38006c19156eSHeiner Kallweit RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); 38016c19156eSHeiner Kallweit rtl_init_rxcfg(tp); 38026c19156eSHeiner Kallweit rtl_set_tx_config_registers(tp); 380310478283SHeiner Kallweit rtl_set_rx_config_features(tp, tp->dev->features); 38046c19156eSHeiner Kallweit rtl_set_rx_mode(tp->dev); 38056c19156eSHeiner Kallweit rtl_irq_enable(tp); 38066c19156eSHeiner Kallweit } 38076c19156eSHeiner Kallweit 380825e992a4SHeiner Kallweit static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) 380925e992a4SHeiner Kallweit { 381025e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 381125e992a4SHeiner Kallweit 381225e992a4SHeiner Kallweit dev->mtu = new_mtu; 381325e992a4SHeiner Kallweit netdev_update_features(dev); 38149db0ac57SHeiner Kallweit rtl_jumbo_config(tp); 381525e992a4SHeiner Kallweit 381625e992a4SHeiner Kallweit return 0; 381725e992a4SHeiner Kallweit } 381825e992a4SHeiner Kallweit 3819e2e5fb8dSHeiner Kallweit static void rtl8169_mark_to_asic(struct RxDesc *desc) 382025e992a4SHeiner Kallweit { 382125e992a4SHeiner Kallweit u32 eor = le32_to_cpu(desc->opts1) & RingEnd; 382225e992a4SHeiner Kallweit 3823047521d7SHeiner Kallweit desc->opts2 = 0; 382425e992a4SHeiner Kallweit /* Force memory writes to complete before releasing descriptor */ 382525e992a4SHeiner Kallweit dma_wmb(); 3826e2e5fb8dSHeiner Kallweit WRITE_ONCE(desc->opts1, cpu_to_le32(DescOwn | eor | R8169_RX_BUF_SIZE)); 382725e992a4SHeiner Kallweit } 382825e992a4SHeiner Kallweit 382932879f00SHeiner Kallweit static struct page *rtl8169_alloc_rx_data(struct rtl8169_private *tp, 383025e992a4SHeiner Kallweit struct RxDesc *desc) 383125e992a4SHeiner Kallweit { 383225e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 383325e992a4SHeiner Kallweit int node = dev_to_node(d); 383432879f00SHeiner Kallweit dma_addr_t mapping; 383532879f00SHeiner Kallweit struct page *data; 383625e992a4SHeiner Kallweit 383732879f00SHeiner Kallweit data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); 383825e992a4SHeiner Kallweit if (!data) 383925e992a4SHeiner Kallweit return NULL; 384025e992a4SHeiner Kallweit 384132879f00SHeiner Kallweit mapping = dma_map_page(d, data, 0, R8169_RX_BUF_SIZE, DMA_FROM_DEVICE); 384225e992a4SHeiner Kallweit if (unlikely(dma_mapping_error(d, mapping))) { 384393882c6fSHeiner Kallweit netdev_err(tp->dev, "Failed to map RX DMA!\n"); 384432879f00SHeiner Kallweit __free_pages(data, get_order(R8169_RX_BUF_SIZE)); 384532879f00SHeiner Kallweit return NULL; 384625e992a4SHeiner Kallweit } 384725e992a4SHeiner Kallweit 384825e992a4SHeiner Kallweit desc->addr = cpu_to_le64(mapping); 384925e992a4SHeiner Kallweit rtl8169_mark_to_asic(desc); 385025e992a4SHeiner Kallweit 385132879f00SHeiner Kallweit return data; 385225e992a4SHeiner Kallweit } 385325e992a4SHeiner Kallweit 385425e992a4SHeiner Kallweit static void rtl8169_rx_clear(struct rtl8169_private *tp) 385525e992a4SHeiner Kallweit { 385625e992a4SHeiner Kallweit unsigned int i; 385725e992a4SHeiner Kallweit 3858eb2e7f09SHeiner Kallweit for (i = 0; i < NUM_RX_DESC && tp->Rx_databuff[i]; i++) { 3859eb2e7f09SHeiner Kallweit dma_unmap_page(tp_to_dev(tp), 3860eb2e7f09SHeiner Kallweit le64_to_cpu(tp->RxDescArray[i].addr), 3861eb2e7f09SHeiner Kallweit R8169_RX_BUF_SIZE, DMA_FROM_DEVICE); 3862eb2e7f09SHeiner Kallweit __free_pages(tp->Rx_databuff[i], get_order(R8169_RX_BUF_SIZE)); 3863eb2e7f09SHeiner Kallweit tp->Rx_databuff[i] = NULL; 38649d3679feSHeiner Kallweit tp->RxDescArray[i].addr = 0; 38659d3679feSHeiner Kallweit tp->RxDescArray[i].opts1 = 0; 386625e992a4SHeiner Kallweit } 386725e992a4SHeiner Kallweit } 386825e992a4SHeiner Kallweit 386925e992a4SHeiner Kallweit static int rtl8169_rx_fill(struct rtl8169_private *tp) 387025e992a4SHeiner Kallweit { 387125e992a4SHeiner Kallweit unsigned int i; 387225e992a4SHeiner Kallweit 387325e992a4SHeiner Kallweit for (i = 0; i < NUM_RX_DESC; i++) { 387432879f00SHeiner Kallweit struct page *data; 387525e992a4SHeiner Kallweit 387625e992a4SHeiner Kallweit data = rtl8169_alloc_rx_data(tp, tp->RxDescArray + i); 387725e992a4SHeiner Kallweit if (!data) { 3878e4b5c7a5SHeiner Kallweit rtl8169_rx_clear(tp); 3879e4b5c7a5SHeiner Kallweit return -ENOMEM; 388025e992a4SHeiner Kallweit } 388125e992a4SHeiner Kallweit tp->Rx_databuff[i] = data; 388225e992a4SHeiner Kallweit } 388325e992a4SHeiner Kallweit 38842ac1fa43SHeiner Kallweit /* mark as last descriptor in the ring */ 38852ac1fa43SHeiner Kallweit tp->RxDescArray[NUM_RX_DESC - 1].opts1 |= cpu_to_le32(RingEnd); 388625e992a4SHeiner Kallweit 3887e4b5c7a5SHeiner Kallweit return 0; 388825e992a4SHeiner Kallweit } 388925e992a4SHeiner Kallweit 389025e992a4SHeiner Kallweit static int rtl8169_init_ring(struct rtl8169_private *tp) 389125e992a4SHeiner Kallweit { 389225e992a4SHeiner Kallweit rtl8169_init_ring_indexes(tp); 389325e992a4SHeiner Kallweit 389425e992a4SHeiner Kallweit memset(tp->tx_skb, 0, sizeof(tp->tx_skb)); 389525e992a4SHeiner Kallweit memset(tp->Rx_databuff, 0, sizeof(tp->Rx_databuff)); 389625e992a4SHeiner Kallweit 389725e992a4SHeiner Kallweit return rtl8169_rx_fill(tp); 389825e992a4SHeiner Kallweit } 389925e992a4SHeiner Kallweit 390022d352c5SHeiner Kallweit static void rtl8169_unmap_tx_skb(struct rtl8169_private *tp, unsigned int entry) 390125e992a4SHeiner Kallweit { 390222d352c5SHeiner Kallweit struct ring_info *tx_skb = tp->tx_skb + entry; 390322d352c5SHeiner Kallweit struct TxDesc *desc = tp->TxDescArray + entry; 390425e992a4SHeiner Kallweit 390522d352c5SHeiner Kallweit dma_unmap_single(tp_to_dev(tp), le64_to_cpu(desc->addr), tx_skb->len, 390622d352c5SHeiner Kallweit DMA_TO_DEVICE); 39076a41f2b2SHeiner Kallweit memset(desc, 0, sizeof(*desc)); 39086a41f2b2SHeiner Kallweit memset(tx_skb, 0, sizeof(*tx_skb)); 390925e992a4SHeiner Kallweit } 391025e992a4SHeiner Kallweit 391125e992a4SHeiner Kallweit static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, 391225e992a4SHeiner Kallweit unsigned int n) 391325e992a4SHeiner Kallweit { 391425e992a4SHeiner Kallweit unsigned int i; 391525e992a4SHeiner Kallweit 391625e992a4SHeiner Kallweit for (i = 0; i < n; i++) { 391725e992a4SHeiner Kallweit unsigned int entry = (start + i) % NUM_TX_DESC; 391825e992a4SHeiner Kallweit struct ring_info *tx_skb = tp->tx_skb + entry; 391925e992a4SHeiner Kallweit unsigned int len = tx_skb->len; 392025e992a4SHeiner Kallweit 392125e992a4SHeiner Kallweit if (len) { 392225e992a4SHeiner Kallweit struct sk_buff *skb = tx_skb->skb; 392325e992a4SHeiner Kallweit 392422d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 39256a41f2b2SHeiner Kallweit if (skb) 392625e992a4SHeiner Kallweit dev_consume_skb_any(skb); 392725e992a4SHeiner Kallweit } 392825e992a4SHeiner Kallweit } 392925e992a4SHeiner Kallweit } 393025e992a4SHeiner Kallweit 393125e992a4SHeiner Kallweit static void rtl8169_tx_clear(struct rtl8169_private *tp) 393225e992a4SHeiner Kallweit { 393325e992a4SHeiner Kallweit rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); 393425e992a4SHeiner Kallweit netdev_reset_queue(tp->dev); 393525e992a4SHeiner Kallweit } 393625e992a4SHeiner Kallweit 39370c28a63aSHeiner Kallweit static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down) 3938bac75d85SHeiner Kallweit { 39390c28a63aSHeiner Kallweit napi_disable(&tp->napi); 39400c28a63aSHeiner Kallweit 3941bac75d85SHeiner Kallweit /* Give a racing hard_start_xmit a few cycles to complete. */ 39427190aeecSHeiner Kallweit synchronize_net(); 3943bac75d85SHeiner Kallweit 3944bac75d85SHeiner Kallweit /* Disable interrupts */ 3945bac75d85SHeiner Kallweit rtl8169_irq_mask_and_ack(tp); 3946bac75d85SHeiner Kallweit 3947bac75d85SHeiner Kallweit rtl_rx_close(tp); 3948bac75d85SHeiner Kallweit 394912006848SHeiner Kallweit if (going_down && tp->dev->wol_enabled) 395012006848SHeiner Kallweit goto no_reset; 395112006848SHeiner Kallweit 3952bac75d85SHeiner Kallweit switch (tp->mac_version) { 3953bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 3954bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 3955bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 3956bac75d85SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_npq_cond, 20, 2000); 3957bac75d85SHeiner Kallweit break; 3958bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38: 3959bac75d85SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); 3960bac75d85SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); 3961bac75d85SHeiner Kallweit break; 3962bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61: 3963bac75d85SHeiner Kallweit rtl_enable_rxdvgate(tp); 3964bac75d85SHeiner Kallweit fsleep(2000); 3965bac75d85SHeiner Kallweit break; 3966bac75d85SHeiner Kallweit default: 3967bac75d85SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); 3968bac75d85SHeiner Kallweit fsleep(100); 3969bac75d85SHeiner Kallweit break; 3970bac75d85SHeiner Kallweit } 3971bac75d85SHeiner Kallweit 3972bac75d85SHeiner Kallweit rtl_hw_reset(tp); 397312006848SHeiner Kallweit no_reset: 3974bac75d85SHeiner Kallweit rtl8169_tx_clear(tp); 3975bac75d85SHeiner Kallweit rtl8169_init_ring_indexes(tp); 3976bac75d85SHeiner Kallweit } 3977bac75d85SHeiner Kallweit 397825e992a4SHeiner Kallweit static void rtl_reset_work(struct rtl8169_private *tp) 397925e992a4SHeiner Kallweit { 398025e992a4SHeiner Kallweit int i; 398125e992a4SHeiner Kallweit 3982476c4f5dSHeiner Kallweit netif_stop_queue(tp->dev); 398325e992a4SHeiner Kallweit 39840c28a63aSHeiner Kallweit rtl8169_cleanup(tp, false); 398525e992a4SHeiner Kallweit 398625e992a4SHeiner Kallweit for (i = 0; i < NUM_RX_DESC; i++) 398725e992a4SHeiner Kallweit rtl8169_mark_to_asic(tp->RxDescArray + i); 398825e992a4SHeiner Kallweit 398925e992a4SHeiner Kallweit napi_enable(&tp->napi); 399025e992a4SHeiner Kallweit rtl_hw_start(tp); 399125e992a4SHeiner Kallweit } 399225e992a4SHeiner Kallweit 39930290bd29SMichael S. Tsirkin static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue) 399425e992a4SHeiner Kallweit { 399525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 399625e992a4SHeiner Kallweit 399725e992a4SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 399825e992a4SHeiner Kallweit } 399925e992a4SHeiner Kallweit 4000b8447abcSHeiner Kallweit static int rtl8169_tx_map(struct rtl8169_private *tp, const u32 *opts, u32 len, 4001b8447abcSHeiner Kallweit void *addr, unsigned int entry, bool desc_own) 400225e992a4SHeiner Kallweit { 4003b8447abcSHeiner Kallweit struct TxDesc *txd = tp->TxDescArray + entry; 4004b8447abcSHeiner Kallweit struct device *d = tp_to_dev(tp); 4005b8447abcSHeiner Kallweit dma_addr_t mapping; 4006b8447abcSHeiner Kallweit u32 opts1; 4007b8447abcSHeiner Kallweit int ret; 400825e992a4SHeiner Kallweit 4009b8447abcSHeiner Kallweit mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE); 4010b8447abcSHeiner Kallweit ret = dma_mapping_error(d, mapping); 4011b8447abcSHeiner Kallweit if (unlikely(ret)) { 4012b8447abcSHeiner Kallweit if (net_ratelimit()) 401393882c6fSHeiner Kallweit netdev_err(tp->dev, "Failed to map TX data!\n"); 4014b8447abcSHeiner Kallweit return ret; 4015b8447abcSHeiner Kallweit } 4016b8447abcSHeiner Kallweit 4017b8447abcSHeiner Kallweit txd->addr = cpu_to_le64(mapping); 4018b8447abcSHeiner Kallweit txd->opts2 = cpu_to_le32(opts[1]); 4019b8447abcSHeiner Kallweit 4020b8447abcSHeiner Kallweit opts1 = opts[0] | len; 402125e992a4SHeiner Kallweit if (entry == NUM_TX_DESC - 1) 4022b8447abcSHeiner Kallweit opts1 |= RingEnd; 4023b8447abcSHeiner Kallweit if (desc_own) 4024b8447abcSHeiner Kallweit opts1 |= DescOwn; 4025b8447abcSHeiner Kallweit txd->opts1 = cpu_to_le32(opts1); 402625e992a4SHeiner Kallweit 4027b8447abcSHeiner Kallweit tp->tx_skb[entry].len = len; 4028b8447abcSHeiner Kallweit 4029b8447abcSHeiner Kallweit return 0; 403025e992a4SHeiner Kallweit } 403125e992a4SHeiner Kallweit 403225e992a4SHeiner Kallweit static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, 4033b8447abcSHeiner Kallweit const u32 *opts, unsigned int entry) 403425e992a4SHeiner Kallweit { 403525e992a4SHeiner Kallweit struct skb_shared_info *info = skb_shinfo(skb); 4036b8447abcSHeiner Kallweit unsigned int cur_frag; 403725e992a4SHeiner Kallweit 403825e992a4SHeiner Kallweit for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { 403925e992a4SHeiner Kallweit const skb_frag_t *frag = info->frags + cur_frag; 4040b8447abcSHeiner Kallweit void *addr = skb_frag_address(frag); 4041b8447abcSHeiner Kallweit u32 len = skb_frag_size(frag); 404225e992a4SHeiner Kallweit 404325e992a4SHeiner Kallweit entry = (entry + 1) % NUM_TX_DESC; 404425e992a4SHeiner Kallweit 4045b8447abcSHeiner Kallweit if (unlikely(rtl8169_tx_map(tp, opts, len, addr, entry, true))) 404625e992a4SHeiner Kallweit goto err_out; 404725e992a4SHeiner Kallweit } 404825e992a4SHeiner Kallweit 40499020845fSHeiner Kallweit return 0; 405025e992a4SHeiner Kallweit 405125e992a4SHeiner Kallweit err_out: 405225e992a4SHeiner Kallweit rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag); 405325e992a4SHeiner Kallweit return -EIO; 405425e992a4SHeiner Kallweit } 405525e992a4SHeiner Kallweit 405625e992a4SHeiner Kallweit static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) 405725e992a4SHeiner Kallweit { 405825e992a4SHeiner Kallweit return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; 405925e992a4SHeiner Kallweit } 406025e992a4SHeiner Kallweit 406125e992a4SHeiner Kallweit static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts) 406225e992a4SHeiner Kallweit { 406325e992a4SHeiner Kallweit u32 mss = skb_shinfo(skb)->gso_size; 406425e992a4SHeiner Kallweit 406525e992a4SHeiner Kallweit if (mss) { 406625e992a4SHeiner Kallweit opts[0] |= TD_LSO; 40674abc3c04SHeiner Kallweit opts[0] |= mss << TD0_MSS_SHIFT; 406825e992a4SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 406925e992a4SHeiner Kallweit const struct iphdr *ip = ip_hdr(skb); 407025e992a4SHeiner Kallweit 407125e992a4SHeiner Kallweit if (ip->protocol == IPPROTO_TCP) 407225e992a4SHeiner Kallweit opts[0] |= TD0_IP_CS | TD0_TCP_CS; 407325e992a4SHeiner Kallweit else if (ip->protocol == IPPROTO_UDP) 407425e992a4SHeiner Kallweit opts[0] |= TD0_IP_CS | TD0_UDP_CS; 407525e992a4SHeiner Kallweit else 407625e992a4SHeiner Kallweit WARN_ON_ONCE(1); 407725e992a4SHeiner Kallweit } 407825e992a4SHeiner Kallweit } 407925e992a4SHeiner Kallweit 408025e992a4SHeiner Kallweit static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, 408125e992a4SHeiner Kallweit struct sk_buff *skb, u32 *opts) 408225e992a4SHeiner Kallweit { 408325e992a4SHeiner Kallweit u32 transport_offset = (u32)skb_transport_offset(skb); 40840623b98bSHeiner Kallweit struct skb_shared_info *shinfo = skb_shinfo(skb); 40850623b98bSHeiner Kallweit u32 mss = shinfo->gso_size; 408625e992a4SHeiner Kallweit 408725e992a4SHeiner Kallweit if (mss) { 40880623b98bSHeiner Kallweit if (shinfo->gso_type & SKB_GSO_TCPV4) { 408925e992a4SHeiner Kallweit opts[0] |= TD1_GTSENV4; 40900623b98bSHeiner Kallweit } else if (shinfo->gso_type & SKB_GSO_TCPV6) { 40918b19c68cSHeiner Kallweit if (skb_cow_head(skb, 0)) 409225e992a4SHeiner Kallweit return false; 409325e992a4SHeiner Kallweit 40948b19c68cSHeiner Kallweit tcp_v6_gso_csum_prep(skb); 409525e992a4SHeiner Kallweit opts[0] |= TD1_GTSENV6; 40960623b98bSHeiner Kallweit } else { 409725e992a4SHeiner Kallweit WARN_ON_ONCE(1); 409825e992a4SHeiner Kallweit } 409925e992a4SHeiner Kallweit 410025e992a4SHeiner Kallweit opts[0] |= transport_offset << GTTCPHO_SHIFT; 41014abc3c04SHeiner Kallweit opts[1] |= mss << TD1_MSS_SHIFT; 410225e992a4SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 410325e992a4SHeiner Kallweit u8 ip_protocol; 410425e992a4SHeiner Kallweit 410525e992a4SHeiner Kallweit switch (vlan_get_protocol(skb)) { 410625e992a4SHeiner Kallweit case htons(ETH_P_IP): 410725e992a4SHeiner Kallweit opts[1] |= TD1_IPv4_CS; 410825e992a4SHeiner Kallweit ip_protocol = ip_hdr(skb)->protocol; 410925e992a4SHeiner Kallweit break; 411025e992a4SHeiner Kallweit 411125e992a4SHeiner Kallweit case htons(ETH_P_IPV6): 411225e992a4SHeiner Kallweit opts[1] |= TD1_IPv6_CS; 411325e992a4SHeiner Kallweit ip_protocol = ipv6_hdr(skb)->nexthdr; 411425e992a4SHeiner Kallweit break; 411525e992a4SHeiner Kallweit 411625e992a4SHeiner Kallweit default: 411725e992a4SHeiner Kallweit ip_protocol = IPPROTO_RAW; 411825e992a4SHeiner Kallweit break; 411925e992a4SHeiner Kallweit } 412025e992a4SHeiner Kallweit 412125e992a4SHeiner Kallweit if (ip_protocol == IPPROTO_TCP) 412225e992a4SHeiner Kallweit opts[1] |= TD1_TCP_CS; 412325e992a4SHeiner Kallweit else if (ip_protocol == IPPROTO_UDP) 412425e992a4SHeiner Kallweit opts[1] |= TD1_UDP_CS; 412525e992a4SHeiner Kallweit else 412625e992a4SHeiner Kallweit WARN_ON_ONCE(1); 412725e992a4SHeiner Kallweit 412825e992a4SHeiner Kallweit opts[1] |= transport_offset << TCPHO_SHIFT; 412925e992a4SHeiner Kallweit } else { 413025e992a4SHeiner Kallweit if (unlikely(rtl_test_hw_pad_bug(tp, skb))) 413125e992a4SHeiner Kallweit return !eth_skb_pad(skb); 413225e992a4SHeiner Kallweit } 413325e992a4SHeiner Kallweit 413425e992a4SHeiner Kallweit return true; 413525e992a4SHeiner Kallweit } 413625e992a4SHeiner Kallweit 413725e992a4SHeiner Kallweit static bool rtl_tx_slots_avail(struct rtl8169_private *tp, 413825e992a4SHeiner Kallweit unsigned int nr_frags) 413925e992a4SHeiner Kallweit { 414025e992a4SHeiner Kallweit unsigned int slots_avail = tp->dirty_tx + NUM_TX_DESC - tp->cur_tx; 414125e992a4SHeiner Kallweit 414225e992a4SHeiner Kallweit /* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ 414325e992a4SHeiner Kallweit return slots_avail > nr_frags; 414425e992a4SHeiner Kallweit } 414525e992a4SHeiner Kallweit 414625e992a4SHeiner Kallweit /* Versions RTL8102e and from RTL8168c onwards support csum_v2 */ 414725e992a4SHeiner Kallweit static bool rtl_chip_supports_csum_v2(struct rtl8169_private *tp) 414825e992a4SHeiner Kallweit { 414925e992a4SHeiner Kallweit switch (tp->mac_version) { 415025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 415125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17: 415225e992a4SHeiner Kallweit return false; 415325e992a4SHeiner Kallweit default: 415425e992a4SHeiner Kallweit return true; 415525e992a4SHeiner Kallweit } 415625e992a4SHeiner Kallweit } 415725e992a4SHeiner Kallweit 4158f1bce4adSHeiner Kallweit static void rtl8169_doorbell(struct rtl8169_private *tp) 4159f1bce4adSHeiner Kallweit { 4160f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 4161f1bce4adSHeiner Kallweit RTL_W16(tp, TxPoll_8125, BIT(0)); 4162f1bce4adSHeiner Kallweit else 4163f1bce4adSHeiner Kallweit RTL_W8(tp, TxPoll, NPQ); 4164f1bce4adSHeiner Kallweit } 4165f1bce4adSHeiner Kallweit 416625e992a4SHeiner Kallweit static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, 416725e992a4SHeiner Kallweit struct net_device *dev) 416825e992a4SHeiner Kallweit { 41699020845fSHeiner Kallweit unsigned int frags = skb_shinfo(skb)->nr_frags; 417025e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 417125e992a4SHeiner Kallweit unsigned int entry = tp->cur_tx % NUM_TX_DESC; 4172b8447abcSHeiner Kallweit struct TxDesc *txd_first, *txd_last; 4173b8447abcSHeiner Kallweit bool stop_queue, door_bell; 4174b8447abcSHeiner Kallweit u32 opts[2]; 4175b8447abcSHeiner Kallweit 4176b8447abcSHeiner Kallweit txd_first = tp->TxDescArray + entry; 417725e992a4SHeiner Kallweit 41789020845fSHeiner Kallweit if (unlikely(!rtl_tx_slots_avail(tp, frags))) { 417993882c6fSHeiner Kallweit if (net_ratelimit()) 418093882c6fSHeiner Kallweit netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); 418125e992a4SHeiner Kallweit goto err_stop_0; 418225e992a4SHeiner Kallweit } 418325e992a4SHeiner Kallweit 4184b8447abcSHeiner Kallweit if (unlikely(le32_to_cpu(txd_first->opts1) & DescOwn)) 418525e992a4SHeiner Kallweit goto err_stop_0; 418625e992a4SHeiner Kallweit 4187355f948aSHeiner Kallweit opts[1] = rtl8169_tx_vlan_tag(skb); 4188b8447abcSHeiner Kallweit opts[0] = 0; 418925e992a4SHeiner Kallweit 4190b8447abcSHeiner Kallweit if (!rtl_chip_supports_csum_v2(tp)) 419125e992a4SHeiner Kallweit rtl8169_tso_csum_v1(skb, opts); 4192b8447abcSHeiner Kallweit else if (!rtl8169_tso_csum_v2(tp, skb, opts)) 419325e992a4SHeiner Kallweit goto err_dma_0; 419425e992a4SHeiner Kallweit 4195b8447abcSHeiner Kallweit if (unlikely(rtl8169_tx_map(tp, opts, skb_headlen(skb), skb->data, 4196b8447abcSHeiner Kallweit entry, false))) 4197b8447abcSHeiner Kallweit goto err_dma_0; 419825e992a4SHeiner Kallweit 4199b8447abcSHeiner Kallweit if (frags) { 4200b8447abcSHeiner Kallweit if (rtl8169_xmit_frags(tp, skb, opts, entry)) 42019020845fSHeiner Kallweit goto err_dma_1; 4202b8447abcSHeiner Kallweit entry = (entry + frags) % NUM_TX_DESC; 420325e992a4SHeiner Kallweit } 420425e992a4SHeiner Kallweit 4205b8447abcSHeiner Kallweit txd_last = tp->TxDescArray + entry; 4206b8447abcSHeiner Kallweit txd_last->opts1 |= cpu_to_le32(LastFrag); 4207b8447abcSHeiner Kallweit tp->tx_skb[entry].skb = skb; 420825e992a4SHeiner Kallweit 420925e992a4SHeiner Kallweit skb_tx_timestamp(skb); 421025e992a4SHeiner Kallweit 421125e992a4SHeiner Kallweit /* Force memory writes to complete before releasing descriptor */ 421225e992a4SHeiner Kallweit dma_wmb(); 421325e992a4SHeiner Kallweit 4214ef143585SHeiner Kallweit door_bell = __netdev_sent_queue(dev, skb->len, netdev_xmit_more()); 4215ef143585SHeiner Kallweit 4216b8447abcSHeiner Kallweit txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag); 421725e992a4SHeiner Kallweit 4218794867eeSHeiner Kallweit /* rtl_tx needs to see descriptor changes before updated tp->cur_tx */ 4219794867eeSHeiner Kallweit smp_wmb(); 422025e992a4SHeiner Kallweit 422125e992a4SHeiner Kallweit tp->cur_tx += frags + 1; 422225e992a4SHeiner Kallweit 4223ef143585SHeiner Kallweit stop_queue = !rtl_tx_slots_avail(tp, MAX_SKB_FRAGS); 4224ef143585SHeiner Kallweit if (unlikely(stop_queue)) { 422525e992a4SHeiner Kallweit /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must 422625e992a4SHeiner Kallweit * not miss a ring update when it notices a stopped queue. 422725e992a4SHeiner Kallweit */ 422825e992a4SHeiner Kallweit smp_wmb(); 422925e992a4SHeiner Kallweit netif_stop_queue(dev); 42304773f9bdSHeiner Kallweit door_bell = true; 4231ef143585SHeiner Kallweit } 4232ef143585SHeiner Kallweit 4233ef143585SHeiner Kallweit if (door_bell) 4234f1bce4adSHeiner Kallweit rtl8169_doorbell(tp); 4235ef143585SHeiner Kallweit 4236ef143585SHeiner Kallweit if (unlikely(stop_queue)) { 423725e992a4SHeiner Kallweit /* Sync with rtl_tx: 423825e992a4SHeiner Kallweit * - publish queue status and cur_tx ring index (write barrier) 423925e992a4SHeiner Kallweit * - refresh dirty_tx ring index (read barrier). 424025e992a4SHeiner Kallweit * May the current thread have a pessimistic view of the ring 424125e992a4SHeiner Kallweit * status and forget to wake up queue, a racing rtl_tx thread 424225e992a4SHeiner Kallweit * can't. 424325e992a4SHeiner Kallweit */ 424425e992a4SHeiner Kallweit smp_mb(); 424525e992a4SHeiner Kallweit if (rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) 424625e992a4SHeiner Kallweit netif_start_queue(dev); 424725e992a4SHeiner Kallweit } 424825e992a4SHeiner Kallweit 424925e992a4SHeiner Kallweit return NETDEV_TX_OK; 425025e992a4SHeiner Kallweit 425125e992a4SHeiner Kallweit err_dma_1: 425222d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 425325e992a4SHeiner Kallweit err_dma_0: 425425e992a4SHeiner Kallweit dev_kfree_skb_any(skb); 425525e992a4SHeiner Kallweit dev->stats.tx_dropped++; 425625e992a4SHeiner Kallweit return NETDEV_TX_OK; 425725e992a4SHeiner Kallweit 425825e992a4SHeiner Kallweit err_stop_0: 425925e992a4SHeiner Kallweit netif_stop_queue(dev); 426025e992a4SHeiner Kallweit dev->stats.tx_dropped++; 426125e992a4SHeiner Kallweit return NETDEV_TX_BUSY; 426225e992a4SHeiner Kallweit } 426325e992a4SHeiner Kallweit 4264773235f4SHeiner Kallweit static unsigned int rtl_last_frag_len(struct sk_buff *skb) 4265773235f4SHeiner Kallweit { 4266773235f4SHeiner Kallweit struct skb_shared_info *info = skb_shinfo(skb); 4267773235f4SHeiner Kallweit unsigned int nr_frags = info->nr_frags; 4268773235f4SHeiner Kallweit 4269773235f4SHeiner Kallweit if (!nr_frags) 4270773235f4SHeiner Kallweit return UINT_MAX; 4271773235f4SHeiner Kallweit 4272773235f4SHeiner Kallweit return skb_frag_size(info->frags + nr_frags - 1); 4273773235f4SHeiner Kallweit } 4274773235f4SHeiner Kallweit 4275773235f4SHeiner Kallweit /* Workaround for hw issues with TSO on RTL8168evl */ 4276773235f4SHeiner Kallweit static netdev_features_t rtl8168evl_fix_tso(struct sk_buff *skb, 4277773235f4SHeiner Kallweit netdev_features_t features) 4278773235f4SHeiner Kallweit { 4279773235f4SHeiner Kallweit /* IPv4 header has options field */ 4280773235f4SHeiner Kallweit if (vlan_get_protocol(skb) == htons(ETH_P_IP) && 4281773235f4SHeiner Kallweit ip_hdrlen(skb) > sizeof(struct iphdr)) 4282773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4283773235f4SHeiner Kallweit 4284773235f4SHeiner Kallweit /* IPv4 TCP header has options field */ 4285773235f4SHeiner Kallweit else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 && 4286773235f4SHeiner Kallweit tcp_hdrlen(skb) > sizeof(struct tcphdr)) 4287773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4288773235f4SHeiner Kallweit 4289773235f4SHeiner Kallweit else if (rtl_last_frag_len(skb) <= 6) 4290773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4291773235f4SHeiner Kallweit 4292773235f4SHeiner Kallweit return features; 4293773235f4SHeiner Kallweit } 4294773235f4SHeiner Kallweit 4295e64e0c89SHeiner Kallweit static netdev_features_t rtl8169_features_check(struct sk_buff *skb, 4296e64e0c89SHeiner Kallweit struct net_device *dev, 4297e64e0c89SHeiner Kallweit netdev_features_t features) 4298e64e0c89SHeiner Kallweit { 4299e64e0c89SHeiner Kallweit int transport_offset = skb_transport_offset(skb); 4300e64e0c89SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 4301e64e0c89SHeiner Kallweit 4302e64e0c89SHeiner Kallweit if (skb_is_gso(skb)) { 4303773235f4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34) 4304773235f4SHeiner Kallweit features = rtl8168evl_fix_tso(skb, features); 4305773235f4SHeiner Kallweit 4306e64e0c89SHeiner Kallweit if (transport_offset > GTTCPHO_MAX && 4307e64e0c89SHeiner Kallweit rtl_chip_supports_csum_v2(tp)) 4308e64e0c89SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4309e64e0c89SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 4310e64e0c89SHeiner Kallweit if (skb->len < ETH_ZLEN) { 4311e64e0c89SHeiner Kallweit switch (tp->mac_version) { 4312e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_11: 4313e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 4314e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 4315e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_34: 4316e64e0c89SHeiner Kallweit features &= ~NETIF_F_CSUM_MASK; 4317e64e0c89SHeiner Kallweit break; 4318e64e0c89SHeiner Kallweit default: 4319e64e0c89SHeiner Kallweit break; 4320e64e0c89SHeiner Kallweit } 4321e64e0c89SHeiner Kallweit } 4322e64e0c89SHeiner Kallweit 4323e64e0c89SHeiner Kallweit if (transport_offset > TCPHO_MAX && 4324e64e0c89SHeiner Kallweit rtl_chip_supports_csum_v2(tp)) 4325e64e0c89SHeiner Kallweit features &= ~NETIF_F_CSUM_MASK; 4326e64e0c89SHeiner Kallweit } 4327e64e0c89SHeiner Kallweit 4328e64e0c89SHeiner Kallweit return vlan_features_check(skb, features); 4329e64e0c89SHeiner Kallweit } 4330e64e0c89SHeiner Kallweit 433125e992a4SHeiner Kallweit static void rtl8169_pcierr_interrupt(struct net_device *dev) 433225e992a4SHeiner Kallweit { 433325e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 433425e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 43352864a883SHeiner Kallweit int pci_status_errs; 43362864a883SHeiner Kallweit u16 pci_cmd; 433725e992a4SHeiner Kallweit 433825e992a4SHeiner Kallweit pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); 433925e992a4SHeiner Kallweit 43402864a883SHeiner Kallweit pci_status_errs = pci_status_get_and_clear_errors(pdev); 43412864a883SHeiner Kallweit 434293882c6fSHeiner Kallweit if (net_ratelimit()) 434393882c6fSHeiner Kallweit netdev_err(dev, "PCI error (cmd = 0x%04x, status_errs = 0x%04x)\n", 43442864a883SHeiner Kallweit pci_cmd, pci_status_errs); 434525e992a4SHeiner Kallweit /* 434625e992a4SHeiner Kallweit * The recovery sequence below admits a very elaborated explanation: 434725e992a4SHeiner Kallweit * - it seems to work; 434825e992a4SHeiner Kallweit * - I did not see what else could be done; 434925e992a4SHeiner Kallweit * - it makes iop3xx happy. 435025e992a4SHeiner Kallweit * 435125e992a4SHeiner Kallweit * Feel free to adjust to your needs. 435225e992a4SHeiner Kallweit */ 435325e992a4SHeiner Kallweit if (pdev->broken_parity_status) 435425e992a4SHeiner Kallweit pci_cmd &= ~PCI_COMMAND_PARITY; 435525e992a4SHeiner Kallweit else 435625e992a4SHeiner Kallweit pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY; 435725e992a4SHeiner Kallweit 435825e992a4SHeiner Kallweit pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); 435925e992a4SHeiner Kallweit 436025e992a4SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 436125e992a4SHeiner Kallweit } 436225e992a4SHeiner Kallweit 436325e992a4SHeiner Kallweit static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, 436425e992a4SHeiner Kallweit int budget) 436525e992a4SHeiner Kallweit { 436625e992a4SHeiner Kallweit unsigned int dirty_tx, tx_left, bytes_compl = 0, pkts_compl = 0; 436725e992a4SHeiner Kallweit 436825e992a4SHeiner Kallweit dirty_tx = tp->dirty_tx; 436925e992a4SHeiner Kallweit smp_rmb(); 437025e992a4SHeiner Kallweit 4371a0e6650bSHeiner Kallweit for (tx_left = tp->cur_tx - dirty_tx; tx_left > 0; tx_left--) { 437225e992a4SHeiner Kallweit unsigned int entry = dirty_tx % NUM_TX_DESC; 437322d352c5SHeiner Kallweit struct sk_buff *skb = tp->tx_skb[entry].skb; 437425e992a4SHeiner Kallweit u32 status; 437525e992a4SHeiner Kallweit 437625e992a4SHeiner Kallweit status = le32_to_cpu(tp->TxDescArray[entry].opts1); 437725e992a4SHeiner Kallweit if (status & DescOwn) 437825e992a4SHeiner Kallweit break; 437925e992a4SHeiner Kallweit 438022d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 438122d352c5SHeiner Kallweit 43826a41f2b2SHeiner Kallweit if (skb) { 438325e992a4SHeiner Kallweit pkts_compl++; 43846a41f2b2SHeiner Kallweit bytes_compl += skb->len; 43856a41f2b2SHeiner Kallweit napi_consume_skb(skb, budget); 438625e992a4SHeiner Kallweit } 438725e992a4SHeiner Kallweit dirty_tx++; 438825e992a4SHeiner Kallweit } 438925e992a4SHeiner Kallweit 439025e992a4SHeiner Kallweit if (tp->dirty_tx != dirty_tx) { 439125e992a4SHeiner Kallweit netdev_completed_queue(dev, pkts_compl, bytes_compl); 439225e992a4SHeiner Kallweit 439325e992a4SHeiner Kallweit u64_stats_update_begin(&tp->tx_stats.syncp); 439425e992a4SHeiner Kallweit tp->tx_stats.packets += pkts_compl; 439525e992a4SHeiner Kallweit tp->tx_stats.bytes += bytes_compl; 439625e992a4SHeiner Kallweit u64_stats_update_end(&tp->tx_stats.syncp); 439725e992a4SHeiner Kallweit 439825e992a4SHeiner Kallweit tp->dirty_tx = dirty_tx; 439925e992a4SHeiner Kallweit /* Sync with rtl8169_start_xmit: 440025e992a4SHeiner Kallweit * - publish dirty_tx ring index (write barrier) 440125e992a4SHeiner Kallweit * - refresh cur_tx ring index and queue status (read barrier) 440225e992a4SHeiner Kallweit * May the current thread miss the stopped queue condition, 440325e992a4SHeiner Kallweit * a racing xmit thread can only have a right view of the 440425e992a4SHeiner Kallweit * ring status. 440525e992a4SHeiner Kallweit */ 440625e992a4SHeiner Kallweit smp_mb(); 440725e992a4SHeiner Kallweit if (netif_queue_stopped(dev) && 440825e992a4SHeiner Kallweit rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) { 440925e992a4SHeiner Kallweit netif_wake_queue(dev); 441025e992a4SHeiner Kallweit } 441125e992a4SHeiner Kallweit /* 441225e992a4SHeiner Kallweit * 8168 hack: TxPoll requests are lost when the Tx packets are 441325e992a4SHeiner Kallweit * too close. Let's kick an extra TxPoll request when a burst 441425e992a4SHeiner Kallweit * of start_xmit activity is detected (if it is not detected, 441525e992a4SHeiner Kallweit * it is slow enough). -- FR 441625e992a4SHeiner Kallweit */ 441725e992a4SHeiner Kallweit if (tp->cur_tx != dirty_tx) 4418f1bce4adSHeiner Kallweit rtl8169_doorbell(tp); 441925e992a4SHeiner Kallweit } 442025e992a4SHeiner Kallweit } 442125e992a4SHeiner Kallweit 442225e992a4SHeiner Kallweit static inline int rtl8169_fragmented_frame(u32 status) 442325e992a4SHeiner Kallweit { 442425e992a4SHeiner Kallweit return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); 442525e992a4SHeiner Kallweit } 442625e992a4SHeiner Kallweit 442725e992a4SHeiner Kallweit static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) 442825e992a4SHeiner Kallweit { 442925e992a4SHeiner Kallweit u32 status = opts1 & RxProtoMask; 443025e992a4SHeiner Kallweit 443125e992a4SHeiner Kallweit if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || 443225e992a4SHeiner Kallweit ((status == RxProtoUDP) && !(opts1 & UDPFail))) 443325e992a4SHeiner Kallweit skb->ip_summed = CHECKSUM_UNNECESSARY; 443425e992a4SHeiner Kallweit else 443525e992a4SHeiner Kallweit skb_checksum_none_assert(skb); 443625e992a4SHeiner Kallweit } 443725e992a4SHeiner Kallweit 443825e992a4SHeiner Kallweit static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget) 443925e992a4SHeiner Kallweit { 4440588c7e5cSHeiner Kallweit unsigned int cur_rx, rx_left, count; 4441588c7e5cSHeiner Kallweit struct device *d = tp_to_dev(tp); 444225e992a4SHeiner Kallweit 444325e992a4SHeiner Kallweit cur_rx = tp->cur_rx; 444425e992a4SHeiner Kallweit 444525e992a4SHeiner Kallweit for (rx_left = min(budget, NUM_RX_DESC); rx_left > 0; rx_left--, cur_rx++) { 4446588c7e5cSHeiner Kallweit unsigned int pkt_size, entry = cur_rx % NUM_RX_DESC; 444725e992a4SHeiner Kallweit struct RxDesc *desc = tp->RxDescArray + entry; 4448588c7e5cSHeiner Kallweit struct sk_buff *skb; 4449588c7e5cSHeiner Kallweit const void *rx_buf; 4450588c7e5cSHeiner Kallweit dma_addr_t addr; 445125e992a4SHeiner Kallweit u32 status; 445225e992a4SHeiner Kallweit 445325e992a4SHeiner Kallweit status = le32_to_cpu(desc->opts1); 445425e992a4SHeiner Kallweit if (status & DescOwn) 445525e992a4SHeiner Kallweit break; 445625e992a4SHeiner Kallweit 445725e992a4SHeiner Kallweit /* This barrier is needed to keep us from reading 445825e992a4SHeiner Kallweit * any other fields out of the Rx descriptor until 445925e992a4SHeiner Kallweit * we know the status of DescOwn 446025e992a4SHeiner Kallweit */ 446125e992a4SHeiner Kallweit dma_rmb(); 446225e992a4SHeiner Kallweit 446325e992a4SHeiner Kallweit if (unlikely(status & RxRES)) { 446493882c6fSHeiner Kallweit if (net_ratelimit()) 446593882c6fSHeiner Kallweit netdev_warn(dev, "Rx ERROR. status = %08x\n", 446625e992a4SHeiner Kallweit status); 446725e992a4SHeiner Kallweit dev->stats.rx_errors++; 446825e992a4SHeiner Kallweit if (status & (RxRWT | RxRUNT)) 446925e992a4SHeiner Kallweit dev->stats.rx_length_errors++; 447025e992a4SHeiner Kallweit if (status & RxCRC) 447125e992a4SHeiner Kallweit dev->stats.rx_crc_errors++; 447225e992a4SHeiner Kallweit 4473588c7e5cSHeiner Kallweit if (!(dev->features & NETIF_F_RXALL)) 4474588c7e5cSHeiner Kallweit goto release_descriptor; 4475588c7e5cSHeiner Kallweit else if (status & RxRWT || !(status & (RxRUNT | RxCRC))) 4476588c7e5cSHeiner Kallweit goto release_descriptor; 4477588c7e5cSHeiner Kallweit } 4478588c7e5cSHeiner Kallweit 4479fcd4e608SHeiner Kallweit pkt_size = status & GENMASK(13, 0); 448025e992a4SHeiner Kallweit if (likely(!(dev->features & NETIF_F_RXFCS))) 4481fcd4e608SHeiner Kallweit pkt_size -= ETH_FCS_LEN; 4482588c7e5cSHeiner Kallweit 4483588c7e5cSHeiner Kallweit /* The driver does not support incoming fragmented frames. 4484588c7e5cSHeiner Kallweit * They are seen as a symptom of over-mtu sized frames. 448525e992a4SHeiner Kallweit */ 448625e992a4SHeiner Kallweit if (unlikely(rtl8169_fragmented_frame(status))) { 448725e992a4SHeiner Kallweit dev->stats.rx_dropped++; 448825e992a4SHeiner Kallweit dev->stats.rx_length_errors++; 448925e992a4SHeiner Kallweit goto release_descriptor; 449025e992a4SHeiner Kallweit } 449125e992a4SHeiner Kallweit 4492fcd4e608SHeiner Kallweit skb = napi_alloc_skb(&tp->napi, pkt_size); 4493fcd4e608SHeiner Kallweit if (unlikely(!skb)) { 449425e992a4SHeiner Kallweit dev->stats.rx_dropped++; 449525e992a4SHeiner Kallweit goto release_descriptor; 449625e992a4SHeiner Kallweit } 449725e992a4SHeiner Kallweit 4498588c7e5cSHeiner Kallweit addr = le64_to_cpu(desc->addr); 4499588c7e5cSHeiner Kallweit rx_buf = page_address(tp->Rx_databuff[entry]); 4500588c7e5cSHeiner Kallweit 4501588c7e5cSHeiner Kallweit dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); 450232879f00SHeiner Kallweit prefetch(rx_buf); 450332879f00SHeiner Kallweit skb_copy_to_linear_data(skb, rx_buf, pkt_size); 4504fcd4e608SHeiner Kallweit skb->tail += pkt_size; 4505fcd4e608SHeiner Kallweit skb->len = pkt_size; 4506588c7e5cSHeiner Kallweit dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE); 4507d4ed7463SHeiner Kallweit 450825e992a4SHeiner Kallweit rtl8169_rx_csum(skb, status); 450925e992a4SHeiner Kallweit skb->protocol = eth_type_trans(skb, dev); 451025e992a4SHeiner Kallweit 451125e992a4SHeiner Kallweit rtl8169_rx_vlan_tag(desc, skb); 451225e992a4SHeiner Kallweit 451325e992a4SHeiner Kallweit if (skb->pkt_type == PACKET_MULTICAST) 451425e992a4SHeiner Kallweit dev->stats.multicast++; 451525e992a4SHeiner Kallweit 451625e992a4SHeiner Kallweit napi_gro_receive(&tp->napi, skb); 451725e992a4SHeiner Kallweit 451825e992a4SHeiner Kallweit u64_stats_update_begin(&tp->rx_stats.syncp); 451925e992a4SHeiner Kallweit tp->rx_stats.packets++; 452025e992a4SHeiner Kallweit tp->rx_stats.bytes += pkt_size; 452125e992a4SHeiner Kallweit u64_stats_update_end(&tp->rx_stats.syncp); 4522588c7e5cSHeiner Kallweit 452325e992a4SHeiner Kallweit release_descriptor: 452425e992a4SHeiner Kallweit rtl8169_mark_to_asic(desc); 452525e992a4SHeiner Kallweit } 452625e992a4SHeiner Kallweit 452725e992a4SHeiner Kallweit count = cur_rx - tp->cur_rx; 452825e992a4SHeiner Kallweit tp->cur_rx = cur_rx; 452925e992a4SHeiner Kallweit 453025e992a4SHeiner Kallweit return count; 453125e992a4SHeiner Kallweit } 453225e992a4SHeiner Kallweit 453325e992a4SHeiner Kallweit static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) 453425e992a4SHeiner Kallweit { 453525e992a4SHeiner Kallweit struct rtl8169_private *tp = dev_instance; 4536c1d532d2SHeiner Kallweit u32 status = rtl_get_events(tp); 453725e992a4SHeiner Kallweit 4538c1d532d2SHeiner Kallweit if (!tp->irq_enabled || (status & 0xffff) == 0xffff || 4539c1d532d2SHeiner Kallweit !(status & tp->irq_mask)) 454025e992a4SHeiner Kallweit return IRQ_NONE; 454125e992a4SHeiner Kallweit 454225e992a4SHeiner Kallweit if (unlikely(status & SYSErr)) { 454325e992a4SHeiner Kallweit rtl8169_pcierr_interrupt(tp->dev); 454425e992a4SHeiner Kallweit goto out; 454525e992a4SHeiner Kallweit } 454625e992a4SHeiner Kallweit 454725e992a4SHeiner Kallweit if (status & LinkChg) 454825e992a4SHeiner Kallweit phy_mac_interrupt(tp->phydev); 454925e992a4SHeiner Kallweit 455025e992a4SHeiner Kallweit if (unlikely(status & RxFIFOOver && 455125e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_11)) { 455225e992a4SHeiner Kallweit netif_stop_queue(tp->dev); 45536b02e407SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 455425e992a4SHeiner Kallweit } 455525e992a4SHeiner Kallweit 455625e992a4SHeiner Kallweit rtl_irq_disable(tp); 455725e992a4SHeiner Kallweit napi_schedule_irqoff(&tp->napi); 455825e992a4SHeiner Kallweit out: 455925e992a4SHeiner Kallweit rtl_ack_events(tp, status); 456025e992a4SHeiner Kallweit 456125e992a4SHeiner Kallweit return IRQ_HANDLED; 456225e992a4SHeiner Kallweit } 456325e992a4SHeiner Kallweit 456425e992a4SHeiner Kallweit static void rtl_task(struct work_struct *work) 456525e992a4SHeiner Kallweit { 456625e992a4SHeiner Kallweit struct rtl8169_private *tp = 456725e992a4SHeiner Kallweit container_of(work, struct rtl8169_private, wk.work); 456825e992a4SHeiner Kallweit 456925e992a4SHeiner Kallweit rtl_lock_work(tp); 457025e992a4SHeiner Kallweit 4571e18958c6SHeiner Kallweit if (!netif_running(tp->dev) || 457225e992a4SHeiner Kallweit !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) 457325e992a4SHeiner Kallweit goto out_unlock; 457425e992a4SHeiner Kallweit 4575476c4f5dSHeiner Kallweit if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) { 4576e18958c6SHeiner Kallweit rtl_reset_work(tp); 4577476c4f5dSHeiner Kallweit netif_wake_queue(tp->dev); 4578476c4f5dSHeiner Kallweit } 457925e992a4SHeiner Kallweit out_unlock: 458025e992a4SHeiner Kallweit rtl_unlock_work(tp); 458125e992a4SHeiner Kallweit } 458225e992a4SHeiner Kallweit 458325e992a4SHeiner Kallweit static int rtl8169_poll(struct napi_struct *napi, int budget) 458425e992a4SHeiner Kallweit { 458525e992a4SHeiner Kallweit struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); 458625e992a4SHeiner Kallweit struct net_device *dev = tp->dev; 458725e992a4SHeiner Kallweit int work_done; 458825e992a4SHeiner Kallweit 458925e992a4SHeiner Kallweit work_done = rtl_rx(dev, tp, (u32) budget); 459025e992a4SHeiner Kallweit 459125e992a4SHeiner Kallweit rtl_tx(dev, tp, budget); 459225e992a4SHeiner Kallweit 459325e992a4SHeiner Kallweit if (work_done < budget) { 459425e992a4SHeiner Kallweit napi_complete_done(napi, work_done); 459525e992a4SHeiner Kallweit rtl_irq_enable(tp); 459625e992a4SHeiner Kallweit } 459725e992a4SHeiner Kallweit 459825e992a4SHeiner Kallweit return work_done; 459925e992a4SHeiner Kallweit } 460025e992a4SHeiner Kallweit 460125e992a4SHeiner Kallweit static void r8169_phylink_handler(struct net_device *ndev) 460225e992a4SHeiner Kallweit { 460325e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(ndev); 460425e992a4SHeiner Kallweit 460525e992a4SHeiner Kallweit if (netif_carrier_ok(ndev)) { 460625e992a4SHeiner Kallweit rtl_link_chg_patch(tp); 460725e992a4SHeiner Kallweit pm_request_resume(&tp->pci_dev->dev); 460825e992a4SHeiner Kallweit } else { 460925e992a4SHeiner Kallweit pm_runtime_idle(&tp->pci_dev->dev); 461025e992a4SHeiner Kallweit } 461125e992a4SHeiner Kallweit 461225e992a4SHeiner Kallweit if (net_ratelimit()) 461325e992a4SHeiner Kallweit phy_print_status(tp->phydev); 461425e992a4SHeiner Kallweit } 461525e992a4SHeiner Kallweit 461625e992a4SHeiner Kallweit static int r8169_phy_connect(struct rtl8169_private *tp) 461725e992a4SHeiner Kallweit { 461825e992a4SHeiner Kallweit struct phy_device *phydev = tp->phydev; 461925e992a4SHeiner Kallweit phy_interface_t phy_mode; 462025e992a4SHeiner Kallweit int ret; 462125e992a4SHeiner Kallweit 462225e992a4SHeiner Kallweit phy_mode = tp->supports_gmii ? PHY_INTERFACE_MODE_GMII : 462325e992a4SHeiner Kallweit PHY_INTERFACE_MODE_MII; 462425e992a4SHeiner Kallweit 462525e992a4SHeiner Kallweit ret = phy_connect_direct(tp->dev, phydev, r8169_phylink_handler, 462625e992a4SHeiner Kallweit phy_mode); 462725e992a4SHeiner Kallweit if (ret) 462825e992a4SHeiner Kallweit return ret; 462925e992a4SHeiner Kallweit 463066058b1cSHeiner Kallweit if (!tp->supports_gmii) 463125e992a4SHeiner Kallweit phy_set_max_speed(phydev, SPEED_100); 463225e992a4SHeiner Kallweit 463325e992a4SHeiner Kallweit phy_support_asym_pause(phydev); 463425e992a4SHeiner Kallweit 463525e992a4SHeiner Kallweit phy_attached_info(phydev); 463625e992a4SHeiner Kallweit 463725e992a4SHeiner Kallweit return 0; 463825e992a4SHeiner Kallweit } 463925e992a4SHeiner Kallweit 46408ac8e8c6SHeiner Kallweit static void rtl8169_down(struct rtl8169_private *tp) 464125e992a4SHeiner Kallweit { 46428ac8e8c6SHeiner Kallweit rtl_lock_work(tp); 46438ac8e8c6SHeiner Kallweit 46448ac8e8c6SHeiner Kallweit /* Clear all task flags */ 46458ac8e8c6SHeiner Kallweit bitmap_zero(tp->wk.flags, RTL_FLAG_MAX); 464625e992a4SHeiner Kallweit 464725e992a4SHeiner Kallweit phy_stop(tp->phydev); 464825e992a4SHeiner Kallweit 4649a2ee8472SHeiner Kallweit rtl8169_update_counters(tp); 4650a2ee8472SHeiner Kallweit 46510c28a63aSHeiner Kallweit rtl8169_cleanup(tp, true); 465225e992a4SHeiner Kallweit 465325e992a4SHeiner Kallweit rtl_pll_power_down(tp); 46548ac8e8c6SHeiner Kallweit 46558ac8e8c6SHeiner Kallweit rtl_unlock_work(tp); 465625e992a4SHeiner Kallweit } 465725e992a4SHeiner Kallweit 465825e992a4SHeiner Kallweit static int rtl8169_close(struct net_device *dev) 465925e992a4SHeiner Kallweit { 466025e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 466125e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 466225e992a4SHeiner Kallweit 466325e992a4SHeiner Kallweit pm_runtime_get_sync(&pdev->dev); 466425e992a4SHeiner Kallweit 46658ac8e8c6SHeiner Kallweit netif_stop_queue(dev); 46668ac8e8c6SHeiner Kallweit rtl8169_down(tp); 46678ac8e8c6SHeiner Kallweit rtl8169_rx_clear(tp); 466825e992a4SHeiner Kallweit 466925e992a4SHeiner Kallweit cancel_work_sync(&tp->wk.work); 467025e992a4SHeiner Kallweit 467125e992a4SHeiner Kallweit phy_disconnect(tp->phydev); 467225e992a4SHeiner Kallweit 467325e992a4SHeiner Kallweit pci_free_irq(pdev, 0, tp); 467425e992a4SHeiner Kallweit 467525e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, 467625e992a4SHeiner Kallweit tp->RxPhyAddr); 467725e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, 467825e992a4SHeiner Kallweit tp->TxPhyAddr); 467925e992a4SHeiner Kallweit tp->TxDescArray = NULL; 468025e992a4SHeiner Kallweit tp->RxDescArray = NULL; 468125e992a4SHeiner Kallweit 468225e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev); 468325e992a4SHeiner Kallweit 468425e992a4SHeiner Kallweit return 0; 468525e992a4SHeiner Kallweit } 468625e992a4SHeiner Kallweit 468725e992a4SHeiner Kallweit #ifdef CONFIG_NET_POLL_CONTROLLER 468825e992a4SHeiner Kallweit static void rtl8169_netpoll(struct net_device *dev) 468925e992a4SHeiner Kallweit { 469025e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 469125e992a4SHeiner Kallweit 469225e992a4SHeiner Kallweit rtl8169_interrupt(pci_irq_vector(tp->pci_dev, 0), tp); 469325e992a4SHeiner Kallweit } 469425e992a4SHeiner Kallweit #endif 469525e992a4SHeiner Kallweit 469625e992a4SHeiner Kallweit static int rtl_open(struct net_device *dev) 469725e992a4SHeiner Kallweit { 469825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 469925e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 470025e992a4SHeiner Kallweit int retval = -ENOMEM; 470125e992a4SHeiner Kallweit 470225e992a4SHeiner Kallweit pm_runtime_get_sync(&pdev->dev); 470325e992a4SHeiner Kallweit 470425e992a4SHeiner Kallweit /* 470525e992a4SHeiner Kallweit * Rx and Tx descriptors needs 256 bytes alignment. 470625e992a4SHeiner Kallweit * dma_alloc_coherent provides more. 470725e992a4SHeiner Kallweit */ 470825e992a4SHeiner Kallweit tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES, 470925e992a4SHeiner Kallweit &tp->TxPhyAddr, GFP_KERNEL); 471025e992a4SHeiner Kallweit if (!tp->TxDescArray) 471125e992a4SHeiner Kallweit goto err_pm_runtime_put; 471225e992a4SHeiner Kallweit 471325e992a4SHeiner Kallweit tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES, 471425e992a4SHeiner Kallweit &tp->RxPhyAddr, GFP_KERNEL); 471525e992a4SHeiner Kallweit if (!tp->RxDescArray) 471625e992a4SHeiner Kallweit goto err_free_tx_0; 471725e992a4SHeiner Kallweit 471825e992a4SHeiner Kallweit retval = rtl8169_init_ring(tp); 471925e992a4SHeiner Kallweit if (retval < 0) 472025e992a4SHeiner Kallweit goto err_free_rx_1; 472125e992a4SHeiner Kallweit 472225e992a4SHeiner Kallweit rtl_request_firmware(tp); 472325e992a4SHeiner Kallweit 472425e992a4SHeiner Kallweit retval = pci_request_irq(pdev, 0, rtl8169_interrupt, NULL, tp, 472525e992a4SHeiner Kallweit dev->name); 472625e992a4SHeiner Kallweit if (retval < 0) 472725e992a4SHeiner Kallweit goto err_release_fw_2; 472825e992a4SHeiner Kallweit 472925e992a4SHeiner Kallweit retval = r8169_phy_connect(tp); 473025e992a4SHeiner Kallweit if (retval) 473125e992a4SHeiner Kallweit goto err_free_irq; 473225e992a4SHeiner Kallweit 473325e992a4SHeiner Kallweit rtl_lock_work(tp); 473425e992a4SHeiner Kallweit 473525e992a4SHeiner Kallweit set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); 473625e992a4SHeiner Kallweit 473725e992a4SHeiner Kallweit napi_enable(&tp->napi); 473825e992a4SHeiner Kallweit 4739b5aed0b3SHeiner Kallweit rtl8169_init_phy(tp); 474025e992a4SHeiner Kallweit 474125e992a4SHeiner Kallweit rtl_pll_power_up(tp); 474225e992a4SHeiner Kallweit 474325e992a4SHeiner Kallweit rtl_hw_start(tp); 474425e992a4SHeiner Kallweit 4745d56f58ceSHeiner Kallweit rtl8169_init_counter_offsets(tp); 474625e992a4SHeiner Kallweit 474725e992a4SHeiner Kallweit phy_start(tp->phydev); 474825e992a4SHeiner Kallweit netif_start_queue(dev); 474925e992a4SHeiner Kallweit 475025e992a4SHeiner Kallweit rtl_unlock_work(tp); 475125e992a4SHeiner Kallweit 475225e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev); 475325e992a4SHeiner Kallweit out: 475425e992a4SHeiner Kallweit return retval; 475525e992a4SHeiner Kallweit 475625e992a4SHeiner Kallweit err_free_irq: 475725e992a4SHeiner Kallweit pci_free_irq(pdev, 0, tp); 475825e992a4SHeiner Kallweit err_release_fw_2: 475925e992a4SHeiner Kallweit rtl_release_firmware(tp); 476025e992a4SHeiner Kallweit rtl8169_rx_clear(tp); 476125e992a4SHeiner Kallweit err_free_rx_1: 476225e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, 476325e992a4SHeiner Kallweit tp->RxPhyAddr); 476425e992a4SHeiner Kallweit tp->RxDescArray = NULL; 476525e992a4SHeiner Kallweit err_free_tx_0: 476625e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, 476725e992a4SHeiner Kallweit tp->TxPhyAddr); 476825e992a4SHeiner Kallweit tp->TxDescArray = NULL; 476925e992a4SHeiner Kallweit err_pm_runtime_put: 477025e992a4SHeiner Kallweit pm_runtime_put_noidle(&pdev->dev); 477125e992a4SHeiner Kallweit goto out; 477225e992a4SHeiner Kallweit } 477325e992a4SHeiner Kallweit 477425e992a4SHeiner Kallweit static void 477525e992a4SHeiner Kallweit rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 477625e992a4SHeiner Kallweit { 477725e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 477825e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 477925e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 478025e992a4SHeiner Kallweit unsigned int start; 478125e992a4SHeiner Kallweit 478225e992a4SHeiner Kallweit pm_runtime_get_noresume(&pdev->dev); 478325e992a4SHeiner Kallweit 4784314a9cbbSHeiner Kallweit netdev_stats_to_stats64(stats, &dev->stats); 4785314a9cbbSHeiner Kallweit 478625e992a4SHeiner Kallweit do { 478725e992a4SHeiner Kallweit start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp); 478825e992a4SHeiner Kallweit stats->rx_packets = tp->rx_stats.packets; 478925e992a4SHeiner Kallweit stats->rx_bytes = tp->rx_stats.bytes; 479025e992a4SHeiner Kallweit } while (u64_stats_fetch_retry_irq(&tp->rx_stats.syncp, start)); 479125e992a4SHeiner Kallweit 479225e992a4SHeiner Kallweit do { 479325e992a4SHeiner Kallweit start = u64_stats_fetch_begin_irq(&tp->tx_stats.syncp); 479425e992a4SHeiner Kallweit stats->tx_packets = tp->tx_stats.packets; 479525e992a4SHeiner Kallweit stats->tx_bytes = tp->tx_stats.bytes; 479625e992a4SHeiner Kallweit } while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start)); 479725e992a4SHeiner Kallweit 479825e992a4SHeiner Kallweit /* 4799ed72a9bbSCorentin Musard * Fetch additional counter values missing in stats collected by driver 480025e992a4SHeiner Kallweit * from tally counters. 480125e992a4SHeiner Kallweit */ 480225e992a4SHeiner Kallweit if (pm_runtime_active(&pdev->dev)) 480325e992a4SHeiner Kallweit rtl8169_update_counters(tp); 480425e992a4SHeiner Kallweit 480525e992a4SHeiner Kallweit /* 480625e992a4SHeiner Kallweit * Subtract values fetched during initalization. 480725e992a4SHeiner Kallweit * See rtl8169_init_counter_offsets for a description why we do that. 480825e992a4SHeiner Kallweit */ 480925e992a4SHeiner Kallweit stats->tx_errors = le64_to_cpu(counters->tx_errors) - 481025e992a4SHeiner Kallweit le64_to_cpu(tp->tc_offset.tx_errors); 481125e992a4SHeiner Kallweit stats->collisions = le32_to_cpu(counters->tx_multi_collision) - 481225e992a4SHeiner Kallweit le32_to_cpu(tp->tc_offset.tx_multi_collision); 481325e992a4SHeiner Kallweit stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) - 481425e992a4SHeiner Kallweit le16_to_cpu(tp->tc_offset.tx_aborted); 48150da3359aSHeiner Kallweit stats->rx_missed_errors = le16_to_cpu(counters->rx_missed) - 48160da3359aSHeiner Kallweit le16_to_cpu(tp->tc_offset.rx_missed); 481725e992a4SHeiner Kallweit 481825e992a4SHeiner Kallweit pm_runtime_put_noidle(&pdev->dev); 481925e992a4SHeiner Kallweit } 482025e992a4SHeiner Kallweit 482127dc36aeSHeiner Kallweit static void rtl8169_net_suspend(struct rtl8169_private *tp) 482225e992a4SHeiner Kallweit { 482327dc36aeSHeiner Kallweit netif_device_detach(tp->dev); 4824476c4f5dSHeiner Kallweit 4825476c4f5dSHeiner Kallweit if (netif_running(tp->dev)) 48268ac8e8c6SHeiner Kallweit rtl8169_down(tp); 482725e992a4SHeiner Kallweit } 482825e992a4SHeiner Kallweit 482925e992a4SHeiner Kallweit #ifdef CONFIG_PM 483025e992a4SHeiner Kallweit 483167ee63efSHeiner Kallweit static int __maybe_unused rtl8169_suspend(struct device *device) 483225e992a4SHeiner Kallweit { 483327dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device); 483425e992a4SHeiner Kallweit 483527dc36aeSHeiner Kallweit rtl8169_net_suspend(tp); 483625e992a4SHeiner Kallweit 483725e992a4SHeiner Kallweit return 0; 483825e992a4SHeiner Kallweit } 483925e992a4SHeiner Kallweit 484027dc36aeSHeiner Kallweit static void __rtl8169_resume(struct rtl8169_private *tp) 484125e992a4SHeiner Kallweit { 484225e992a4SHeiner Kallweit rtl_pll_power_up(tp); 4843b5aed0b3SHeiner Kallweit rtl8169_init_phy(tp); 484425e992a4SHeiner Kallweit 484525e992a4SHeiner Kallweit phy_start(tp->phydev); 484625e992a4SHeiner Kallweit 484725e992a4SHeiner Kallweit rtl_lock_work(tp); 484825e992a4SHeiner Kallweit napi_enable(&tp->napi); 484925e992a4SHeiner Kallweit set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); 485025e992a4SHeiner Kallweit rtl_reset_work(tp); 485125e992a4SHeiner Kallweit rtl_unlock_work(tp); 485225e992a4SHeiner Kallweit } 485325e992a4SHeiner Kallweit 485467ee63efSHeiner Kallweit static int __maybe_unused rtl8169_resume(struct device *device) 485525e992a4SHeiner Kallweit { 485627dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device); 485725e992a4SHeiner Kallweit 485827dc36aeSHeiner Kallweit rtl_rar_set(tp, tp->dev->dev_addr); 485925e992a4SHeiner Kallweit 486027dc36aeSHeiner Kallweit if (netif_running(tp->dev)) 486127dc36aeSHeiner Kallweit __rtl8169_resume(tp); 486225e992a4SHeiner Kallweit 4863476c4f5dSHeiner Kallweit netif_device_attach(tp->dev); 4864476c4f5dSHeiner Kallweit 486525e992a4SHeiner Kallweit return 0; 486625e992a4SHeiner Kallweit } 486725e992a4SHeiner Kallweit 486825e992a4SHeiner Kallweit static int rtl8169_runtime_suspend(struct device *device) 486925e992a4SHeiner Kallweit { 487027dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device); 487125e992a4SHeiner Kallweit 4872476c4f5dSHeiner Kallweit if (!tp->TxDescArray) { 4873476c4f5dSHeiner Kallweit netif_device_detach(tp->dev); 487425e992a4SHeiner Kallweit return 0; 4875476c4f5dSHeiner Kallweit } 487625e992a4SHeiner Kallweit 487725e992a4SHeiner Kallweit rtl_lock_work(tp); 487801bd753dSHeiner Kallweit __rtl8169_set_wol(tp, WAKE_PHY); 487925e992a4SHeiner Kallweit rtl_unlock_work(tp); 488025e992a4SHeiner Kallweit 488127dc36aeSHeiner Kallweit rtl8169_net_suspend(tp); 488225e992a4SHeiner Kallweit 488325e992a4SHeiner Kallweit return 0; 488425e992a4SHeiner Kallweit } 488525e992a4SHeiner Kallweit 488625e992a4SHeiner Kallweit static int rtl8169_runtime_resume(struct device *device) 488725e992a4SHeiner Kallweit { 488827dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device); 488925e992a4SHeiner Kallweit 489027dc36aeSHeiner Kallweit rtl_rar_set(tp, tp->dev->dev_addr); 489125e992a4SHeiner Kallweit 489225e992a4SHeiner Kallweit rtl_lock_work(tp); 489325e992a4SHeiner Kallweit __rtl8169_set_wol(tp, tp->saved_wolopts); 489425e992a4SHeiner Kallweit rtl_unlock_work(tp); 489525e992a4SHeiner Kallweit 4896e9882208SHeiner Kallweit if (tp->TxDescArray) 489727dc36aeSHeiner Kallweit __rtl8169_resume(tp); 489825e992a4SHeiner Kallweit 4899476c4f5dSHeiner Kallweit netif_device_attach(tp->dev); 4900476c4f5dSHeiner Kallweit 490125e992a4SHeiner Kallweit return 0; 490225e992a4SHeiner Kallweit } 490325e992a4SHeiner Kallweit 490425e992a4SHeiner Kallweit static int rtl8169_runtime_idle(struct device *device) 490525e992a4SHeiner Kallweit { 490627dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device); 490725e992a4SHeiner Kallweit 490827dc36aeSHeiner Kallweit if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev)) 490925e992a4SHeiner Kallweit pm_schedule_suspend(device, 10000); 491025e992a4SHeiner Kallweit 491125e992a4SHeiner Kallweit return -EBUSY; 491225e992a4SHeiner Kallweit } 491325e992a4SHeiner Kallweit 491425e992a4SHeiner Kallweit static const struct dev_pm_ops rtl8169_pm_ops = { 491567ee63efSHeiner Kallweit SET_SYSTEM_SLEEP_PM_OPS(rtl8169_suspend, rtl8169_resume) 491667ee63efSHeiner Kallweit SET_RUNTIME_PM_OPS(rtl8169_runtime_suspend, rtl8169_runtime_resume, 491767ee63efSHeiner Kallweit rtl8169_runtime_idle) 491825e992a4SHeiner Kallweit }; 491925e992a4SHeiner Kallweit 492067ee63efSHeiner Kallweit #endif /* CONFIG_PM */ 492125e992a4SHeiner Kallweit 492225e992a4SHeiner Kallweit static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp) 492325e992a4SHeiner Kallweit { 492425e992a4SHeiner Kallweit /* WoL fails with 8168b when the receiver is disabled. */ 492525e992a4SHeiner Kallweit switch (tp->mac_version) { 492625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_11: 492725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 492825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 492925e992a4SHeiner Kallweit pci_clear_master(tp->pci_dev); 493025e992a4SHeiner Kallweit 493125e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, CmdRxEnb); 4932711463f8SHeiner Kallweit rtl_pci_commit(tp); 493325e992a4SHeiner Kallweit break; 493425e992a4SHeiner Kallweit default: 493525e992a4SHeiner Kallweit break; 493625e992a4SHeiner Kallweit } 493725e992a4SHeiner Kallweit } 493825e992a4SHeiner Kallweit 493925e992a4SHeiner Kallweit static void rtl_shutdown(struct pci_dev *pdev) 494025e992a4SHeiner Kallweit { 494127dc36aeSHeiner Kallweit struct rtl8169_private *tp = pci_get_drvdata(pdev); 494225e992a4SHeiner Kallweit 494327dc36aeSHeiner Kallweit rtl8169_net_suspend(tp); 494425e992a4SHeiner Kallweit 494525e992a4SHeiner Kallweit /* Restore original MAC address */ 494627dc36aeSHeiner Kallweit rtl_rar_set(tp, tp->dev->perm_addr); 494725e992a4SHeiner Kallweit 494825e992a4SHeiner Kallweit if (system_state == SYSTEM_POWER_OFF) { 494925e992a4SHeiner Kallweit if (tp->saved_wolopts) { 495025e992a4SHeiner Kallweit rtl_wol_suspend_quirk(tp); 495125e992a4SHeiner Kallweit rtl_wol_shutdown_quirk(tp); 495225e992a4SHeiner Kallweit } 495325e992a4SHeiner Kallweit 495425e992a4SHeiner Kallweit pci_wake_from_d3(pdev, true); 495525e992a4SHeiner Kallweit pci_set_power_state(pdev, PCI_D3hot); 495625e992a4SHeiner Kallweit } 495725e992a4SHeiner Kallweit } 495825e992a4SHeiner Kallweit 495925e992a4SHeiner Kallweit static void rtl_remove_one(struct pci_dev *pdev) 496025e992a4SHeiner Kallweit { 496127dc36aeSHeiner Kallweit struct rtl8169_private *tp = pci_get_drvdata(pdev); 496225e992a4SHeiner Kallweit 496312b1bc75SHeiner Kallweit if (pci_dev_run_wake(pdev)) 496412b1bc75SHeiner Kallweit pm_runtime_get_noresume(&pdev->dev); 496525e992a4SHeiner Kallweit 496627dc36aeSHeiner Kallweit unregister_netdev(tp->dev); 496725e992a4SHeiner Kallweit 496812b1bc75SHeiner Kallweit if (r8168_check_dash(tp)) 496912b1bc75SHeiner Kallweit rtl8168_driver_stop(tp); 497025e992a4SHeiner Kallweit 497112b1bc75SHeiner Kallweit rtl_release_firmware(tp); 497225e992a4SHeiner Kallweit 497325e992a4SHeiner Kallweit /* restore original MAC address */ 497427dc36aeSHeiner Kallweit rtl_rar_set(tp, tp->dev->perm_addr); 497525e992a4SHeiner Kallweit } 497625e992a4SHeiner Kallweit 497725e992a4SHeiner Kallweit static const struct net_device_ops rtl_netdev_ops = { 497825e992a4SHeiner Kallweit .ndo_open = rtl_open, 497925e992a4SHeiner Kallweit .ndo_stop = rtl8169_close, 498025e992a4SHeiner Kallweit .ndo_get_stats64 = rtl8169_get_stats64, 498125e992a4SHeiner Kallweit .ndo_start_xmit = rtl8169_start_xmit, 4982e64e0c89SHeiner Kallweit .ndo_features_check = rtl8169_features_check, 498325e992a4SHeiner Kallweit .ndo_tx_timeout = rtl8169_tx_timeout, 498425e992a4SHeiner Kallweit .ndo_validate_addr = eth_validate_addr, 498525e992a4SHeiner Kallweit .ndo_change_mtu = rtl8169_change_mtu, 498625e992a4SHeiner Kallweit .ndo_fix_features = rtl8169_fix_features, 498725e992a4SHeiner Kallweit .ndo_set_features = rtl8169_set_features, 498825e992a4SHeiner Kallweit .ndo_set_mac_address = rtl_set_mac_address, 49893231e5d2SHeiner Kallweit .ndo_do_ioctl = phy_do_ioctl_running, 499025e992a4SHeiner Kallweit .ndo_set_rx_mode = rtl_set_rx_mode, 499125e992a4SHeiner Kallweit #ifdef CONFIG_NET_POLL_CONTROLLER 499225e992a4SHeiner Kallweit .ndo_poll_controller = rtl8169_netpoll, 499325e992a4SHeiner Kallweit #endif 499425e992a4SHeiner Kallweit 499525e992a4SHeiner Kallweit }; 499625e992a4SHeiner Kallweit 4997ec9a4088SHeiner Kallweit static void rtl_set_irq_mask(struct rtl8169_private *tp) 4998ec9a4088SHeiner Kallweit { 49992045e158SHeiner Kallweit tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg; 5000ec9a4088SHeiner Kallweit 5001ec9a4088SHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 5002ec9a4088SHeiner Kallweit tp->irq_mask |= SYSErr | RxOverflow | RxFIFOOver; 5003ec9a4088SHeiner Kallweit else if (tp->mac_version == RTL_GIGA_MAC_VER_11) 5004ec9a4088SHeiner Kallweit /* special workaround needed */ 5005ec9a4088SHeiner Kallweit tp->irq_mask |= RxFIFOOver; 5006ec9a4088SHeiner Kallweit else 5007ec9a4088SHeiner Kallweit tp->irq_mask |= RxOverflow; 5008ec9a4088SHeiner Kallweit } 5009ec9a4088SHeiner Kallweit 501025e992a4SHeiner Kallweit static int rtl_alloc_irq(struct rtl8169_private *tp) 501125e992a4SHeiner Kallweit { 501225e992a4SHeiner Kallweit unsigned int flags; 501325e992a4SHeiner Kallweit 5014003bd5b4SHeiner Kallweit switch (tp->mac_version) { 5015003bd5b4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 501625e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 501725e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable); 501825e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 5019003bd5b4SHeiner Kallweit /* fall through */ 5020f13bc681SHeiner Kallweit case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_17: 502125e992a4SHeiner Kallweit flags = PCI_IRQ_LEGACY; 5022003bd5b4SHeiner Kallweit break; 5023003bd5b4SHeiner Kallweit default: 502425e992a4SHeiner Kallweit flags = PCI_IRQ_ALL_TYPES; 5025003bd5b4SHeiner Kallweit break; 502625e992a4SHeiner Kallweit } 502725e992a4SHeiner Kallweit 502825e992a4SHeiner Kallweit return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags); 502925e992a4SHeiner Kallweit } 503025e992a4SHeiner Kallweit 503125e992a4SHeiner Kallweit static void rtl_read_mac_address(struct rtl8169_private *tp, 503225e992a4SHeiner Kallweit u8 mac_addr[ETH_ALEN]) 503325e992a4SHeiner Kallweit { 503425e992a4SHeiner Kallweit /* Get MAC address */ 50359e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp) && tp->mac_version != RTL_GIGA_MAC_VER_34) { 50369e9f33baSHeiner Kallweit u32 value = rtl_eri_read(tp, 0xe0); 50379e9f33baSHeiner Kallweit 503825e992a4SHeiner Kallweit mac_addr[0] = (value >> 0) & 0xff; 503925e992a4SHeiner Kallweit mac_addr[1] = (value >> 8) & 0xff; 504025e992a4SHeiner Kallweit mac_addr[2] = (value >> 16) & 0xff; 504125e992a4SHeiner Kallweit mac_addr[3] = (value >> 24) & 0xff; 504225e992a4SHeiner Kallweit 504325e992a4SHeiner Kallweit value = rtl_eri_read(tp, 0xe4); 504425e992a4SHeiner Kallweit mac_addr[4] = (value >> 0) & 0xff; 504525e992a4SHeiner Kallweit mac_addr[5] = (value >> 8) & 0xff; 5046f1bce4adSHeiner Kallweit } else if (rtl_is_8125(tp)) { 5047f1bce4adSHeiner Kallweit rtl_read_mac_from_reg(tp, mac_addr, MAC0_BKP); 504825e992a4SHeiner Kallweit } 504925e992a4SHeiner Kallweit } 505025e992a4SHeiner Kallweit 505125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_link_list_ready_cond) 505225e992a4SHeiner Kallweit { 505325e992a4SHeiner Kallweit return RTL_R8(tp, MCU) & LINK_LIST_RDY; 505425e992a4SHeiner Kallweit } 505525e992a4SHeiner Kallweit 5056e031ce80SHeiner Kallweit static void r8168g_wait_ll_share_fifo_ready(struct rtl8169_private *tp) 5057e031ce80SHeiner Kallweit { 5058e031ce80SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42); 5059e031ce80SHeiner Kallweit } 5060e031ce80SHeiner Kallweit 506125e992a4SHeiner Kallweit static int r8169_mdio_read_reg(struct mii_bus *mii_bus, int phyaddr, int phyreg) 506225e992a4SHeiner Kallweit { 506325e992a4SHeiner Kallweit struct rtl8169_private *tp = mii_bus->priv; 506425e992a4SHeiner Kallweit 506525e992a4SHeiner Kallweit if (phyaddr > 0) 506625e992a4SHeiner Kallweit return -ENODEV; 506725e992a4SHeiner Kallweit 506825e992a4SHeiner Kallweit return rtl_readphy(tp, phyreg); 506925e992a4SHeiner Kallweit } 507025e992a4SHeiner Kallweit 507125e992a4SHeiner Kallweit static int r8169_mdio_write_reg(struct mii_bus *mii_bus, int phyaddr, 507225e992a4SHeiner Kallweit int phyreg, u16 val) 507325e992a4SHeiner Kallweit { 507425e992a4SHeiner Kallweit struct rtl8169_private *tp = mii_bus->priv; 507525e992a4SHeiner Kallweit 507625e992a4SHeiner Kallweit if (phyaddr > 0) 507725e992a4SHeiner Kallweit return -ENODEV; 507825e992a4SHeiner Kallweit 507925e992a4SHeiner Kallweit rtl_writephy(tp, phyreg, val); 508025e992a4SHeiner Kallweit 508125e992a4SHeiner Kallweit return 0; 508225e992a4SHeiner Kallweit } 508325e992a4SHeiner Kallweit 508425e992a4SHeiner Kallweit static int r8169_mdio_register(struct rtl8169_private *tp) 508525e992a4SHeiner Kallweit { 508625e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 508725e992a4SHeiner Kallweit struct mii_bus *new_bus; 508825e992a4SHeiner Kallweit int ret; 508925e992a4SHeiner Kallweit 509025e992a4SHeiner Kallweit new_bus = devm_mdiobus_alloc(&pdev->dev); 509125e992a4SHeiner Kallweit if (!new_bus) 509225e992a4SHeiner Kallweit return -ENOMEM; 509325e992a4SHeiner Kallweit 509425e992a4SHeiner Kallweit new_bus->name = "r8169"; 509525e992a4SHeiner Kallweit new_bus->priv = tp; 509625e992a4SHeiner Kallweit new_bus->parent = &pdev->dev; 509725e992a4SHeiner Kallweit new_bus->irq[0] = PHY_IGNORE_INTERRUPT; 509825e992a4SHeiner Kallweit snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x", pci_dev_id(pdev)); 509925e992a4SHeiner Kallweit 510025e992a4SHeiner Kallweit new_bus->read = r8169_mdio_read_reg; 510125e992a4SHeiner Kallweit new_bus->write = r8169_mdio_write_reg; 510225e992a4SHeiner Kallweit 51030785dad4SHeiner Kallweit ret = devm_mdiobus_register(new_bus); 510425e992a4SHeiner Kallweit if (ret) 510525e992a4SHeiner Kallweit return ret; 510625e992a4SHeiner Kallweit 510725e992a4SHeiner Kallweit tp->phydev = mdiobus_get_phy(new_bus, 0); 510825e992a4SHeiner Kallweit if (!tp->phydev) { 510925e992a4SHeiner Kallweit return -ENODEV; 51102e8c339bSHeiner Kallweit } else if (!tp->phydev->drv) { 51112e8c339bSHeiner Kallweit /* Most chip versions fail with the genphy driver. 51122e8c339bSHeiner Kallweit * Therefore ensure that the dedicated PHY driver is loaded. 51132e8c339bSHeiner Kallweit */ 51140c2006b2SHeiner Kallweit dev_err(&pdev->dev, "no dedicated PHY driver found for PHY ID 0x%08x, maybe realtek.ko needs to be added to initramfs?\n", 51150c2006b2SHeiner Kallweit tp->phydev->phy_id); 51162e8c339bSHeiner Kallweit return -EUNATCH; 511725e992a4SHeiner Kallweit } 511825e992a4SHeiner Kallweit 511925e992a4SHeiner Kallweit /* PHY will be woken up in rtl_open() */ 512025e992a4SHeiner Kallweit phy_suspend(tp->phydev); 512125e992a4SHeiner Kallweit 512225e992a4SHeiner Kallweit return 0; 512325e992a4SHeiner Kallweit } 512425e992a4SHeiner Kallweit 512525e992a4SHeiner Kallweit static void rtl_hw_init_8168g(struct rtl8169_private *tp) 512625e992a4SHeiner Kallweit { 51279617886fSHeiner Kallweit rtl_enable_rxdvgate(tp); 512825e992a4SHeiner Kallweit 512925e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); 513025e992a4SHeiner Kallweit msleep(1); 513125e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 513225e992a4SHeiner Kallweit 5133ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, BIT(14), 0); 5134e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp); 513525e992a4SHeiner Kallweit 5136ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, 0, BIT(15)); 5137e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp); 513825e992a4SHeiner Kallweit } 513925e992a4SHeiner Kallweit 5140f1bce4adSHeiner Kallweit static void rtl_hw_init_8125(struct rtl8169_private *tp) 5141f1bce4adSHeiner Kallweit { 51429617886fSHeiner Kallweit rtl_enable_rxdvgate(tp); 5143f1bce4adSHeiner Kallweit 5144f1bce4adSHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); 5145f1bce4adSHeiner Kallweit msleep(1); 5146f1bce4adSHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 5147f1bce4adSHeiner Kallweit 5148f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, BIT(14), 0); 5149e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp); 5150f1bce4adSHeiner Kallweit 5151f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc0aa, 0x07d0); 5152f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc0a6, 0x0150); 5153f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc01e, 0x5555); 5154e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp); 5155f1bce4adSHeiner Kallweit } 5156f1bce4adSHeiner Kallweit 515725e992a4SHeiner Kallweit static void rtl_hw_initialize(struct rtl8169_private *tp) 515825e992a4SHeiner Kallweit { 515925e992a4SHeiner Kallweit switch (tp->mac_version) { 51601287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 516125e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp); 516225e992a4SHeiner Kallweit /* fall through */ 516325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: 516425e992a4SHeiner Kallweit rtl_hw_init_8168g(tp); 516525e992a4SHeiner Kallweit break; 5166f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: 5167f1bce4adSHeiner Kallweit rtl_hw_init_8125(tp); 5168f1bce4adSHeiner Kallweit break; 516925e992a4SHeiner Kallweit default: 517025e992a4SHeiner Kallweit break; 517125e992a4SHeiner Kallweit } 517225e992a4SHeiner Kallweit } 517325e992a4SHeiner Kallweit 517425e992a4SHeiner Kallweit static int rtl_jumbo_max(struct rtl8169_private *tp) 517525e992a4SHeiner Kallweit { 517625e992a4SHeiner Kallweit /* Non-GBit versions don't support jumbo frames */ 517725e992a4SHeiner Kallweit if (!tp->supports_gmii) 5178a8ec173aSHeiner Kallweit return 0; 517925e992a4SHeiner Kallweit 518025e992a4SHeiner Kallweit switch (tp->mac_version) { 518125e992a4SHeiner Kallweit /* RTL8169 */ 518225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 518325e992a4SHeiner Kallweit return JUMBO_7K; 518425e992a4SHeiner Kallweit /* RTL8168b */ 518525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_11: 518625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 518725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 518825e992a4SHeiner Kallweit return JUMBO_4K; 518925e992a4SHeiner Kallweit /* RTL8168c */ 519025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: 519125e992a4SHeiner Kallweit return JUMBO_6K; 519225e992a4SHeiner Kallweit default: 519325e992a4SHeiner Kallweit return JUMBO_9K; 519425e992a4SHeiner Kallweit } 519525e992a4SHeiner Kallweit } 519625e992a4SHeiner Kallweit 519725e992a4SHeiner Kallweit static void rtl_disable_clk(void *data) 519825e992a4SHeiner Kallweit { 519925e992a4SHeiner Kallweit clk_disable_unprepare(data); 520025e992a4SHeiner Kallweit } 520125e992a4SHeiner Kallweit 520225e992a4SHeiner Kallweit static int rtl_get_ether_clk(struct rtl8169_private *tp) 520325e992a4SHeiner Kallweit { 520425e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 520525e992a4SHeiner Kallweit struct clk *clk; 520625e992a4SHeiner Kallweit int rc; 520725e992a4SHeiner Kallweit 520825e992a4SHeiner Kallweit clk = devm_clk_get(d, "ether_clk"); 520925e992a4SHeiner Kallweit if (IS_ERR(clk)) { 521025e992a4SHeiner Kallweit rc = PTR_ERR(clk); 521125e992a4SHeiner Kallweit if (rc == -ENOENT) 521225e992a4SHeiner Kallweit /* clk-core allows NULL (for suspend / resume) */ 521325e992a4SHeiner Kallweit rc = 0; 521425e992a4SHeiner Kallweit else if (rc != -EPROBE_DEFER) 521525e992a4SHeiner Kallweit dev_err(d, "failed to get clk: %d\n", rc); 521625e992a4SHeiner Kallweit } else { 521725e992a4SHeiner Kallweit tp->clk = clk; 521825e992a4SHeiner Kallweit rc = clk_prepare_enable(clk); 521925e992a4SHeiner Kallweit if (rc) 522025e992a4SHeiner Kallweit dev_err(d, "failed to enable clk: %d\n", rc); 522125e992a4SHeiner Kallweit else 522225e992a4SHeiner Kallweit rc = devm_add_action_or_reset(d, rtl_disable_clk, clk); 522325e992a4SHeiner Kallweit } 522425e992a4SHeiner Kallweit 522525e992a4SHeiner Kallweit return rc; 522625e992a4SHeiner Kallweit } 522725e992a4SHeiner Kallweit 5228c782e204SHeiner Kallweit static void rtl_init_mac_address(struct rtl8169_private *tp) 5229c782e204SHeiner Kallweit { 5230c782e204SHeiner Kallweit struct net_device *dev = tp->dev; 5231c782e204SHeiner Kallweit u8 *mac_addr = dev->dev_addr; 5232ce37115eSHeiner Kallweit int rc; 5233c782e204SHeiner Kallweit 5234c782e204SHeiner Kallweit rc = eth_platform_get_mac_address(tp_to_dev(tp), mac_addr); 5235c782e204SHeiner Kallweit if (!rc) 5236c782e204SHeiner Kallweit goto done; 5237c782e204SHeiner Kallweit 5238c782e204SHeiner Kallweit rtl_read_mac_address(tp, mac_addr); 5239c782e204SHeiner Kallweit if (is_valid_ether_addr(mac_addr)) 5240c782e204SHeiner Kallweit goto done; 5241c782e204SHeiner Kallweit 5242ce37115eSHeiner Kallweit rtl_read_mac_from_reg(tp, mac_addr, MAC0); 5243c782e204SHeiner Kallweit if (is_valid_ether_addr(mac_addr)) 5244c782e204SHeiner Kallweit goto done; 5245c782e204SHeiner Kallweit 5246c782e204SHeiner Kallweit eth_hw_addr_random(dev); 5247c782e204SHeiner Kallweit dev_warn(tp_to_dev(tp), "can't read MAC address, setting random one\n"); 5248c782e204SHeiner Kallweit done: 5249c782e204SHeiner Kallweit rtl_rar_set(tp, mac_addr); 5250c782e204SHeiner Kallweit } 5251c782e204SHeiner Kallweit 525225e992a4SHeiner Kallweit static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 525325e992a4SHeiner Kallweit { 525425e992a4SHeiner Kallweit struct rtl8169_private *tp; 5255f1f9ca28SHeiner Kallweit int jumbo_max, region, rc; 5256f1f9ca28SHeiner Kallweit enum mac_version chipset; 525725e992a4SHeiner Kallweit struct net_device *dev; 5258f1f9ca28SHeiner Kallweit u16 xid; 525925e992a4SHeiner Kallweit 526025e992a4SHeiner Kallweit dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp)); 526125e992a4SHeiner Kallweit if (!dev) 526225e992a4SHeiner Kallweit return -ENOMEM; 526325e992a4SHeiner Kallweit 526425e992a4SHeiner Kallweit SET_NETDEV_DEV(dev, &pdev->dev); 526525e992a4SHeiner Kallweit dev->netdev_ops = &rtl_netdev_ops; 526625e992a4SHeiner Kallweit tp = netdev_priv(dev); 526725e992a4SHeiner Kallweit tp->dev = dev; 526825e992a4SHeiner Kallweit tp->pci_dev = pdev; 5269145a40e8SHeiner Kallweit tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; 52707ec3f872SHeiner Kallweit tp->eee_adv = -1; 52710360c046SHeiner Kallweit tp->ocp_base = OCP_STD_PHY_BASE; 527225e992a4SHeiner Kallweit 527325e992a4SHeiner Kallweit /* Get the *optional* external "ether_clk" used on some boards */ 527425e992a4SHeiner Kallweit rc = rtl_get_ether_clk(tp); 527525e992a4SHeiner Kallweit if (rc) 527625e992a4SHeiner Kallweit return rc; 527725e992a4SHeiner Kallweit 527825e992a4SHeiner Kallweit /* Disable ASPM completely as that cause random device stop working 527925e992a4SHeiner Kallweit * problems as well as full system hangs for some PCIe devices users. 528025e992a4SHeiner Kallweit */ 528162b1b3b3SHeiner Kallweit rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | 528262b1b3b3SHeiner Kallweit PCIE_LINK_STATE_L1); 528362b1b3b3SHeiner Kallweit tp->aspm_manageable = !rc; 528425e992a4SHeiner Kallweit 528525e992a4SHeiner Kallweit /* enable device (incl. PCI PM wakeup and hotplug setup) */ 528625e992a4SHeiner Kallweit rc = pcim_enable_device(pdev); 528725e992a4SHeiner Kallweit if (rc < 0) { 528825e992a4SHeiner Kallweit dev_err(&pdev->dev, "enable failure\n"); 528925e992a4SHeiner Kallweit return rc; 529025e992a4SHeiner Kallweit } 529125e992a4SHeiner Kallweit 529225e992a4SHeiner Kallweit if (pcim_set_mwi(pdev) < 0) 529325e992a4SHeiner Kallweit dev_info(&pdev->dev, "Mem-Wr-Inval unavailable\n"); 529425e992a4SHeiner Kallweit 529525e992a4SHeiner Kallweit /* use first MMIO region */ 529625e992a4SHeiner Kallweit region = ffs(pci_select_bars(pdev, IORESOURCE_MEM)) - 1; 529725e992a4SHeiner Kallweit if (region < 0) { 529825e992a4SHeiner Kallweit dev_err(&pdev->dev, "no MMIO resource found\n"); 529925e992a4SHeiner Kallweit return -ENODEV; 530025e992a4SHeiner Kallweit } 530125e992a4SHeiner Kallweit 530225e992a4SHeiner Kallweit /* check for weird/broken PCI region reporting */ 530325e992a4SHeiner Kallweit if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) { 530425e992a4SHeiner Kallweit dev_err(&pdev->dev, "Invalid PCI region size(s), aborting\n"); 530525e992a4SHeiner Kallweit return -ENODEV; 530625e992a4SHeiner Kallweit } 530725e992a4SHeiner Kallweit 530825e992a4SHeiner Kallweit rc = pcim_iomap_regions(pdev, BIT(region), MODULENAME); 530925e992a4SHeiner Kallweit if (rc < 0) { 531025e992a4SHeiner Kallweit dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); 531125e992a4SHeiner Kallweit return rc; 531225e992a4SHeiner Kallweit } 531325e992a4SHeiner Kallweit 531425e992a4SHeiner Kallweit tp->mmio_addr = pcim_iomap_table(pdev)[region]; 531525e992a4SHeiner Kallweit 5316f1f9ca28SHeiner Kallweit xid = (RTL_R32(tp, TxConfig) >> 20) & 0xfcf; 5317f1f9ca28SHeiner Kallweit 531825e992a4SHeiner Kallweit /* Identify chip attached to board */ 5319f1f9ca28SHeiner Kallweit chipset = rtl8169_get_mac_version(xid, tp->supports_gmii); 5320f1f9ca28SHeiner Kallweit if (chipset == RTL_GIGA_MAC_NONE) { 5321f1f9ca28SHeiner Kallweit dev_err(&pdev->dev, "unknown chip XID %03x\n", xid); 532225e992a4SHeiner Kallweit return -ENODEV; 5323f1f9ca28SHeiner Kallweit } 5324f1f9ca28SHeiner Kallweit 5325f1f9ca28SHeiner Kallweit tp->mac_version = chipset; 532625e992a4SHeiner Kallweit 5327975e8505SHeiner Kallweit tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; 532825e992a4SHeiner Kallweit 532925e992a4SHeiner Kallweit if (sizeof(dma_addr_t) > 4 && tp->mac_version >= RTL_GIGA_MAC_VER_18 && 53303c18cbe3SHeiner Kallweit !dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) 533125e992a4SHeiner Kallweit dev->features |= NETIF_F_HIGHDMA; 533225e992a4SHeiner Kallweit 533325e992a4SHeiner Kallweit rtl_init_rxcfg(tp); 533425e992a4SHeiner Kallweit 533525e992a4SHeiner Kallweit rtl8169_irq_mask_and_ack(tp); 533625e992a4SHeiner Kallweit 533725e992a4SHeiner Kallweit rtl_hw_initialize(tp); 533825e992a4SHeiner Kallweit 533925e992a4SHeiner Kallweit rtl_hw_reset(tp); 534025e992a4SHeiner Kallweit 534125e992a4SHeiner Kallweit pci_set_master(pdev); 534225e992a4SHeiner Kallweit 534325e992a4SHeiner Kallweit rc = rtl_alloc_irq(tp); 534425e992a4SHeiner Kallweit if (rc < 0) { 534525e992a4SHeiner Kallweit dev_err(&pdev->dev, "Can't allocate interrupt\n"); 534625e992a4SHeiner Kallweit return rc; 534725e992a4SHeiner Kallweit } 534825e992a4SHeiner Kallweit 534925e992a4SHeiner Kallweit mutex_init(&tp->wk.mutex); 535025e992a4SHeiner Kallweit INIT_WORK(&tp->wk.work, rtl_task); 535125e992a4SHeiner Kallweit u64_stats_init(&tp->rx_stats.syncp); 535225e992a4SHeiner Kallweit u64_stats_init(&tp->tx_stats.syncp); 535325e992a4SHeiner Kallweit 5354c782e204SHeiner Kallweit rtl_init_mac_address(tp); 535525e992a4SHeiner Kallweit 535625e992a4SHeiner Kallweit dev->ethtool_ops = &rtl8169_ethtool_ops; 535725e992a4SHeiner Kallweit 535825e992a4SHeiner Kallweit netif_napi_add(dev, &tp->napi, rtl8169_poll, NAPI_POLL_WEIGHT); 535925e992a4SHeiner Kallweit 536095099c56SHeiner Kallweit dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | 536195099c56SHeiner Kallweit NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; 5362a9b3d568SHeiner Kallweit dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; 536325e992a4SHeiner Kallweit dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; 536425e992a4SHeiner Kallweit 536525e992a4SHeiner Kallweit /* 536625e992a4SHeiner Kallweit * Pretend we are using VLANs; This bypasses a nasty bug where 536725e992a4SHeiner Kallweit * Interrupts stop flowing on high load on 8110SCd controllers. 536825e992a4SHeiner Kallweit */ 536925e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05) 537025e992a4SHeiner Kallweit /* Disallow toggling */ 537125e992a4SHeiner Kallweit dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX; 537225e992a4SHeiner Kallweit 537395099c56SHeiner Kallweit if (rtl_chip_supports_csum_v2(tp)) 537495099c56SHeiner Kallweit dev->hw_features |= NETIF_F_IPV6_CSUM; 537595099c56SHeiner Kallweit 537695099c56SHeiner Kallweit dev->features |= dev->hw_features; 537795099c56SHeiner Kallweit 537895099c56SHeiner Kallweit /* There has been a number of reports that using SG/TSO results in 537995099c56SHeiner Kallweit * tx timeouts. However for a lot of people SG/TSO works fine. 538095099c56SHeiner Kallweit * Therefore disable both features by default, but allow users to 538195099c56SHeiner Kallweit * enable them. Use at own risk! 538295099c56SHeiner Kallweit */ 53830170d594SHeiner Kallweit if (rtl_chip_supports_csum_v2(tp)) { 538495099c56SHeiner Kallweit dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; 53850170d594SHeiner Kallweit dev->gso_max_size = RTL_GSO_MAX_SIZE_V2; 53860170d594SHeiner Kallweit dev->gso_max_segs = RTL_GSO_MAX_SEGS_V2; 53870170d594SHeiner Kallweit } else { 538895099c56SHeiner Kallweit dev->hw_features |= NETIF_F_SG | NETIF_F_TSO; 53890170d594SHeiner Kallweit dev->gso_max_size = RTL_GSO_MAX_SIZE_V1; 53900170d594SHeiner Kallweit dev->gso_max_segs = RTL_GSO_MAX_SEGS_V1; 53910170d594SHeiner Kallweit } 539225e992a4SHeiner Kallweit 539325e992a4SHeiner Kallweit dev->hw_features |= NETIF_F_RXALL; 539425e992a4SHeiner Kallweit dev->hw_features |= NETIF_F_RXFCS; 539525e992a4SHeiner Kallweit 5396145192f8SHeiner Kallweit /* configure chip for default features */ 5397145192f8SHeiner Kallweit rtl8169_set_features(dev, dev->features); 5398145192f8SHeiner Kallweit 539925e992a4SHeiner Kallweit jumbo_max = rtl_jumbo_max(tp); 5400a8ec173aSHeiner Kallweit if (jumbo_max) 540125e992a4SHeiner Kallweit dev->max_mtu = jumbo_max; 540225e992a4SHeiner Kallweit 5403ec9a4088SHeiner Kallweit rtl_set_irq_mask(tp); 54049fa0a8e1SHeiner Kallweit 540525e992a4SHeiner Kallweit tp->fw_name = rtl_chip_infos[chipset].fw_name; 540625e992a4SHeiner Kallweit 540725e992a4SHeiner Kallweit tp->counters = dmam_alloc_coherent (&pdev->dev, sizeof(*tp->counters), 540825e992a4SHeiner Kallweit &tp->counters_phys_addr, 540925e992a4SHeiner Kallweit GFP_KERNEL); 541025e992a4SHeiner Kallweit if (!tp->counters) 541125e992a4SHeiner Kallweit return -ENOMEM; 541225e992a4SHeiner Kallweit 541327dc36aeSHeiner Kallweit pci_set_drvdata(pdev, tp); 541425e992a4SHeiner Kallweit 541525e992a4SHeiner Kallweit rc = r8169_mdio_register(tp); 541625e992a4SHeiner Kallweit if (rc) 541725e992a4SHeiner Kallweit return rc; 541825e992a4SHeiner Kallweit 541925e992a4SHeiner Kallweit /* chip gets powered up in rtl_open() */ 542025e992a4SHeiner Kallweit rtl_pll_power_down(tp); 542125e992a4SHeiner Kallweit 542225e992a4SHeiner Kallweit rc = register_netdev(dev); 542325e992a4SHeiner Kallweit if (rc) 54240785dad4SHeiner Kallweit return rc; 542525e992a4SHeiner Kallweit 542693882c6fSHeiner Kallweit netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n", 5427f1f9ca28SHeiner Kallweit rtl_chip_infos[chipset].name, dev->dev_addr, xid, 542825e992a4SHeiner Kallweit pci_irq_vector(pdev, 0)); 542925e992a4SHeiner Kallweit 5430a8ec173aSHeiner Kallweit if (jumbo_max) 543193882c6fSHeiner Kallweit netdev_info(dev, "jumbo features [frames: %d bytes, tx checksumming: %s]\n", 543225e992a4SHeiner Kallweit jumbo_max, tp->mac_version <= RTL_GIGA_MAC_VER_06 ? 543325e992a4SHeiner Kallweit "ok" : "ko"); 543425e992a4SHeiner Kallweit 5435a38b7fbfSHeiner Kallweit if (r8168_check_dash(tp)) { 5436a38b7fbfSHeiner Kallweit netdev_info(dev, "DASH enabled\n"); 543725e992a4SHeiner Kallweit rtl8168_driver_start(tp); 5438a38b7fbfSHeiner Kallweit } 543925e992a4SHeiner Kallweit 544025e992a4SHeiner Kallweit if (pci_dev_run_wake(pdev)) 544125e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev); 544225e992a4SHeiner Kallweit 544325e992a4SHeiner Kallweit return 0; 544425e992a4SHeiner Kallweit } 544525e992a4SHeiner Kallweit 544625e992a4SHeiner Kallweit static struct pci_driver rtl8169_pci_driver = { 544725e992a4SHeiner Kallweit .name = MODULENAME, 544825e992a4SHeiner Kallweit .id_table = rtl8169_pci_tbl, 544925e992a4SHeiner Kallweit .probe = rtl_init_one, 545025e992a4SHeiner Kallweit .remove = rtl_remove_one, 545125e992a4SHeiner Kallweit .shutdown = rtl_shutdown, 545267ee63efSHeiner Kallweit #ifdef CONFIG_PM 545367ee63efSHeiner Kallweit .driver.pm = &rtl8169_pm_ops, 545467ee63efSHeiner Kallweit #endif 545525e992a4SHeiner Kallweit }; 545625e992a4SHeiner Kallweit 545725e992a4SHeiner Kallweit module_pci_driver(rtl8169_pci_driver); 5458