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 53225e992a4SHeiner Kallweit #define RsvdMask 0x3fffc000 53325e992a4SHeiner Kallweit 5340170d594SHeiner Kallweit #define RTL_GSO_MAX_SIZE_V1 32000 5350170d594SHeiner Kallweit #define RTL_GSO_MAX_SEGS_V1 24 5360170d594SHeiner Kallweit #define RTL_GSO_MAX_SIZE_V2 64000 5370170d594SHeiner Kallweit #define RTL_GSO_MAX_SEGS_V2 64 5380170d594SHeiner Kallweit 53925e992a4SHeiner Kallweit struct TxDesc { 54025e992a4SHeiner Kallweit __le32 opts1; 54125e992a4SHeiner Kallweit __le32 opts2; 54225e992a4SHeiner Kallweit __le64 addr; 54325e992a4SHeiner Kallweit }; 54425e992a4SHeiner Kallweit 54525e992a4SHeiner Kallweit struct RxDesc { 54625e992a4SHeiner Kallweit __le32 opts1; 54725e992a4SHeiner Kallweit __le32 opts2; 54825e992a4SHeiner Kallweit __le64 addr; 54925e992a4SHeiner Kallweit }; 55025e992a4SHeiner Kallweit 55125e992a4SHeiner Kallweit struct ring_info { 55225e992a4SHeiner Kallweit struct sk_buff *skb; 55325e992a4SHeiner Kallweit u32 len; 55425e992a4SHeiner Kallweit }; 55525e992a4SHeiner Kallweit 55625e992a4SHeiner Kallweit struct rtl8169_counters { 55725e992a4SHeiner Kallweit __le64 tx_packets; 55825e992a4SHeiner Kallweit __le64 rx_packets; 55925e992a4SHeiner Kallweit __le64 tx_errors; 56025e992a4SHeiner Kallweit __le32 rx_errors; 56125e992a4SHeiner Kallweit __le16 rx_missed; 56225e992a4SHeiner Kallweit __le16 align_errors; 56325e992a4SHeiner Kallweit __le32 tx_one_collision; 56425e992a4SHeiner Kallweit __le32 tx_multi_collision; 56525e992a4SHeiner Kallweit __le64 rx_unicast; 56625e992a4SHeiner Kallweit __le64 rx_broadcast; 56725e992a4SHeiner Kallweit __le32 rx_multicast; 56825e992a4SHeiner Kallweit __le16 tx_aborted; 56925e992a4SHeiner Kallweit __le16 tx_underun; 57025e992a4SHeiner Kallweit }; 57125e992a4SHeiner Kallweit 57225e992a4SHeiner Kallweit struct rtl8169_tc_offsets { 57325e992a4SHeiner Kallweit bool inited; 57425e992a4SHeiner Kallweit __le64 tx_errors; 57525e992a4SHeiner Kallweit __le32 tx_multi_collision; 57625e992a4SHeiner Kallweit __le16 tx_aborted; 5770da3359aSHeiner Kallweit __le16 rx_missed; 57825e992a4SHeiner Kallweit }; 57925e992a4SHeiner Kallweit 58025e992a4SHeiner Kallweit enum rtl_flag { 58125e992a4SHeiner Kallweit RTL_FLAG_TASK_ENABLED = 0, 58225e992a4SHeiner Kallweit RTL_FLAG_TASK_RESET_PENDING, 58325e992a4SHeiner Kallweit RTL_FLAG_MAX 58425e992a4SHeiner Kallweit }; 58525e992a4SHeiner Kallweit 58625e992a4SHeiner Kallweit struct rtl8169_stats { 58725e992a4SHeiner Kallweit u64 packets; 58825e992a4SHeiner Kallweit u64 bytes; 58925e992a4SHeiner Kallweit struct u64_stats_sync syncp; 59025e992a4SHeiner Kallweit }; 59125e992a4SHeiner Kallweit 59225e992a4SHeiner Kallweit struct rtl8169_private { 59325e992a4SHeiner Kallweit void __iomem *mmio_addr; /* memory map physical address */ 59425e992a4SHeiner Kallweit struct pci_dev *pci_dev; 59525e992a4SHeiner Kallweit struct net_device *dev; 59625e992a4SHeiner Kallweit struct phy_device *phydev; 59725e992a4SHeiner Kallweit struct napi_struct napi; 59825e992a4SHeiner Kallweit enum mac_version mac_version; 59925e992a4SHeiner Kallweit u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ 60025e992a4SHeiner Kallweit u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ 60125e992a4SHeiner Kallweit u32 dirty_tx; 60225e992a4SHeiner Kallweit struct rtl8169_stats rx_stats; 60325e992a4SHeiner Kallweit struct rtl8169_stats tx_stats; 60425e992a4SHeiner Kallweit struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ 60525e992a4SHeiner Kallweit struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ 60625e992a4SHeiner Kallweit dma_addr_t TxPhyAddr; 60725e992a4SHeiner Kallweit dma_addr_t RxPhyAddr; 60832879f00SHeiner Kallweit struct page *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */ 60925e992a4SHeiner Kallweit struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ 61025e992a4SHeiner Kallweit u16 cp_cmd; 611c1d532d2SHeiner Kallweit u32 irq_mask; 61225e992a4SHeiner Kallweit struct clk *clk; 61325e992a4SHeiner Kallweit 61425e992a4SHeiner Kallweit struct { 61525e992a4SHeiner Kallweit DECLARE_BITMAP(flags, RTL_FLAG_MAX); 61625e992a4SHeiner Kallweit struct mutex mutex; 61725e992a4SHeiner Kallweit struct work_struct work; 61825e992a4SHeiner Kallweit } wk; 61925e992a4SHeiner Kallweit 62025e992a4SHeiner Kallweit unsigned irq_enabled:1; 62125e992a4SHeiner Kallweit unsigned supports_gmii:1; 62262b1b3b3SHeiner Kallweit unsigned aspm_manageable:1; 62325e992a4SHeiner Kallweit dma_addr_t counters_phys_addr; 62425e992a4SHeiner Kallweit struct rtl8169_counters *counters; 62525e992a4SHeiner Kallweit struct rtl8169_tc_offsets tc_offset; 62625e992a4SHeiner Kallweit u32 saved_wolopts; 6277ec3f872SHeiner Kallweit int eee_adv; 62825e992a4SHeiner Kallweit 62925e992a4SHeiner Kallweit const char *fw_name; 6308197f9d2SHeiner Kallweit struct rtl_fw *rtl_fw; 63125e992a4SHeiner Kallweit 63225e992a4SHeiner Kallweit u32 ocp_base; 63325e992a4SHeiner Kallweit }; 63425e992a4SHeiner Kallweit 63525e992a4SHeiner Kallweit typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); 63625e992a4SHeiner Kallweit 63725e992a4SHeiner Kallweit MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); 63825e992a4SHeiner Kallweit MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); 63925e992a4SHeiner Kallweit MODULE_SOFTDEP("pre: realtek"); 64025e992a4SHeiner Kallweit MODULE_LICENSE("GPL"); 64125e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168D_1); 64225e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168D_2); 64325e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_1); 64425e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_2); 64525e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_3); 64625e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8105E_1); 64725e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168F_1); 64825e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168F_2); 64925e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8402_1); 65025e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8411_1); 65125e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8411_2); 65225e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8106E_1); 65325e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8106E_2); 65425e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168G_2); 65525e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168G_3); 65625e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168H_1); 65725e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168H_2); 658229c1e0dSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168FP_3); 65925e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8107E_1); 66025e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8107E_2); 66102bf642bSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8125A_3); 66225e992a4SHeiner Kallweit 66325e992a4SHeiner Kallweit static inline struct device *tp_to_dev(struct rtl8169_private *tp) 66425e992a4SHeiner Kallweit { 66525e992a4SHeiner Kallweit return &tp->pci_dev->dev; 66625e992a4SHeiner Kallweit } 66725e992a4SHeiner Kallweit 66825e992a4SHeiner Kallweit static void rtl_lock_work(struct rtl8169_private *tp) 66925e992a4SHeiner Kallweit { 67025e992a4SHeiner Kallweit mutex_lock(&tp->wk.mutex); 67125e992a4SHeiner Kallweit } 67225e992a4SHeiner Kallweit 67325e992a4SHeiner Kallweit static void rtl_unlock_work(struct rtl8169_private *tp) 67425e992a4SHeiner Kallweit { 67525e992a4SHeiner Kallweit mutex_unlock(&tp->wk.mutex); 67625e992a4SHeiner Kallweit } 67725e992a4SHeiner Kallweit 67825e992a4SHeiner Kallweit static void rtl_lock_config_regs(struct rtl8169_private *tp) 67925e992a4SHeiner Kallweit { 68025e992a4SHeiner Kallweit RTL_W8(tp, Cfg9346, Cfg9346_Lock); 68125e992a4SHeiner Kallweit } 68225e992a4SHeiner Kallweit 68325e992a4SHeiner Kallweit static void rtl_unlock_config_regs(struct rtl8169_private *tp) 68425e992a4SHeiner Kallweit { 68525e992a4SHeiner Kallweit RTL_W8(tp, Cfg9346, Cfg9346_Unlock); 68625e992a4SHeiner Kallweit } 68725e992a4SHeiner Kallweit 688711463f8SHeiner Kallweit static void rtl_pci_commit(struct rtl8169_private *tp) 689711463f8SHeiner Kallweit { 690711463f8SHeiner Kallweit /* Read an arbitrary register to commit a preceding PCI write */ 691711463f8SHeiner Kallweit RTL_R8(tp, ChipCmd); 692711463f8SHeiner Kallweit } 693711463f8SHeiner Kallweit 694f1bce4adSHeiner Kallweit static bool rtl_is_8125(struct rtl8169_private *tp) 695f1bce4adSHeiner Kallweit { 696f1bce4adSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_60; 697f1bce4adSHeiner Kallweit } 698f1bce4adSHeiner Kallweit 6999e9f33baSHeiner Kallweit static bool rtl_is_8168evl_up(struct rtl8169_private *tp) 7009e9f33baSHeiner Kallweit { 7019e9f33baSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_34 && 702c623305bSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_39 && 7031287723aSHeiner Kallweit tp->mac_version <= RTL_GIGA_MAC_VER_52; 7049e9f33baSHeiner Kallweit } 7059e9f33baSHeiner Kallweit 7062e779ddbSHeiner Kallweit static bool rtl_supports_eee(struct rtl8169_private *tp) 7072e779ddbSHeiner Kallweit { 7082e779ddbSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_34 && 7092e779ddbSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_37 && 7102e779ddbSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_39; 7112e779ddbSHeiner Kallweit } 7122e779ddbSHeiner Kallweit 713ce37115eSHeiner Kallweit static void rtl_read_mac_from_reg(struct rtl8169_private *tp, u8 *mac, int reg) 714ce37115eSHeiner Kallweit { 715ce37115eSHeiner Kallweit int i; 716ce37115eSHeiner Kallweit 717ce37115eSHeiner Kallweit for (i = 0; i < ETH_ALEN; i++) 718ce37115eSHeiner Kallweit mac[i] = RTL_R8(tp, reg + i); 719ce37115eSHeiner Kallweit } 720ce37115eSHeiner Kallweit 72125e992a4SHeiner Kallweit struct rtl_cond { 72225e992a4SHeiner Kallweit bool (*check)(struct rtl8169_private *); 72325e992a4SHeiner Kallweit const char *msg; 72425e992a4SHeiner Kallweit }; 72525e992a4SHeiner Kallweit 72625e992a4SHeiner Kallweit static bool rtl_loop_wait(struct rtl8169_private *tp, const struct rtl_cond *c, 727d6836ef0SHeiner Kallweit unsigned long usecs, int n, bool high) 72825e992a4SHeiner Kallweit { 72925e992a4SHeiner Kallweit int i; 73025e992a4SHeiner Kallweit 73125e992a4SHeiner Kallweit for (i = 0; i < n; i++) { 73225e992a4SHeiner Kallweit if (c->check(tp) == high) 73325e992a4SHeiner Kallweit return true; 734d6836ef0SHeiner Kallweit fsleep(usecs); 73525e992a4SHeiner Kallweit } 73693882c6fSHeiner Kallweit 73793882c6fSHeiner Kallweit if (net_ratelimit()) 738d6836ef0SHeiner Kallweit netdev_err(tp->dev, "%s == %d (loop: %d, delay: %lu).\n", 739d6836ef0SHeiner Kallweit c->msg, !high, n, usecs); 74025e992a4SHeiner Kallweit return false; 74125e992a4SHeiner Kallweit } 74225e992a4SHeiner Kallweit 743d6836ef0SHeiner Kallweit static bool rtl_loop_wait_high(struct rtl8169_private *tp, 74425e992a4SHeiner Kallweit const struct rtl_cond *c, 745d6836ef0SHeiner Kallweit unsigned long d, int n) 74625e992a4SHeiner Kallweit { 747d6836ef0SHeiner Kallweit return rtl_loop_wait(tp, c, d, n, true); 74825e992a4SHeiner Kallweit } 74925e992a4SHeiner Kallweit 750d6836ef0SHeiner Kallweit static bool rtl_loop_wait_low(struct rtl8169_private *tp, 75125e992a4SHeiner Kallweit const struct rtl_cond *c, 752d6836ef0SHeiner Kallweit unsigned long d, int n) 75325e992a4SHeiner Kallweit { 754d6836ef0SHeiner Kallweit return rtl_loop_wait(tp, c, d, n, false); 75525e992a4SHeiner Kallweit } 75625e992a4SHeiner Kallweit 75725e992a4SHeiner Kallweit #define DECLARE_RTL_COND(name) \ 75825e992a4SHeiner Kallweit static bool name ## _check(struct rtl8169_private *); \ 75925e992a4SHeiner Kallweit \ 76025e992a4SHeiner Kallweit static const struct rtl_cond name = { \ 76125e992a4SHeiner Kallweit .check = name ## _check, \ 76225e992a4SHeiner Kallweit .msg = #name \ 76325e992a4SHeiner Kallweit }; \ 76425e992a4SHeiner Kallweit \ 76525e992a4SHeiner Kallweit static bool name ## _check(struct rtl8169_private *tp) 76625e992a4SHeiner Kallweit 76725e992a4SHeiner Kallweit static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg) 76825e992a4SHeiner Kallweit { 76925e992a4SHeiner Kallweit if (reg & 0xffff0001) { 77093882c6fSHeiner Kallweit if (net_ratelimit()) 77193882c6fSHeiner Kallweit netdev_err(tp->dev, "Invalid ocp reg %x!\n", reg); 77225e992a4SHeiner Kallweit return true; 77325e992a4SHeiner Kallweit } 77425e992a4SHeiner Kallweit return false; 77525e992a4SHeiner Kallweit } 77625e992a4SHeiner Kallweit 77725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocp_gphy_cond) 77825e992a4SHeiner Kallweit { 77925e992a4SHeiner Kallweit return RTL_R32(tp, GPHY_OCP) & OCPAR_FLAG; 78025e992a4SHeiner Kallweit } 78125e992a4SHeiner Kallweit 78225e992a4SHeiner Kallweit static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) 78325e992a4SHeiner Kallweit { 78425e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 78525e992a4SHeiner Kallweit return; 78625e992a4SHeiner Kallweit 78725e992a4SHeiner Kallweit RTL_W32(tp, GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); 78825e992a4SHeiner Kallweit 789d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10); 79025e992a4SHeiner Kallweit } 79125e992a4SHeiner Kallweit 7929b994b4aSHeiner Kallweit static int r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) 79325e992a4SHeiner Kallweit { 79425e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 79525e992a4SHeiner Kallweit return 0; 79625e992a4SHeiner Kallweit 79725e992a4SHeiner Kallweit RTL_W32(tp, GPHY_OCP, reg << 15); 79825e992a4SHeiner Kallweit 799d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ? 8009b994b4aSHeiner Kallweit (RTL_R32(tp, GPHY_OCP) & 0xffff) : -ETIMEDOUT; 80125e992a4SHeiner Kallweit } 80225e992a4SHeiner Kallweit 80325e992a4SHeiner Kallweit static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) 80425e992a4SHeiner Kallweit { 80525e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 80625e992a4SHeiner Kallweit return; 80725e992a4SHeiner Kallweit 80825e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, OCPAR_FLAG | (reg << 15) | data); 80925e992a4SHeiner Kallweit } 81025e992a4SHeiner Kallweit 81125e992a4SHeiner Kallweit static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) 81225e992a4SHeiner Kallweit { 81325e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 81425e992a4SHeiner Kallweit return 0; 81525e992a4SHeiner Kallweit 81625e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, reg << 15); 81725e992a4SHeiner Kallweit 81825e992a4SHeiner Kallweit return RTL_R32(tp, OCPDR); 81925e992a4SHeiner Kallweit } 82025e992a4SHeiner Kallweit 821ef712edeSHeiner Kallweit static void r8168_mac_ocp_modify(struct rtl8169_private *tp, u32 reg, u16 mask, 822ef712edeSHeiner Kallweit u16 set) 823ef712edeSHeiner Kallweit { 824ef712edeSHeiner Kallweit u16 data = r8168_mac_ocp_read(tp, reg); 825ef712edeSHeiner Kallweit 826ef712edeSHeiner Kallweit r8168_mac_ocp_write(tp, reg, (data & ~mask) | set); 827ef712edeSHeiner Kallweit } 828ef712edeSHeiner Kallweit 82925e992a4SHeiner Kallweit static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) 83025e992a4SHeiner Kallweit { 83125e992a4SHeiner Kallweit if (reg == 0x1f) { 83225e992a4SHeiner Kallweit tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE; 83325e992a4SHeiner Kallweit return; 83425e992a4SHeiner Kallweit } 83525e992a4SHeiner Kallweit 83625e992a4SHeiner Kallweit if (tp->ocp_base != OCP_STD_PHY_BASE) 83725e992a4SHeiner Kallweit reg -= 0x10; 83825e992a4SHeiner Kallweit 83925e992a4SHeiner Kallweit r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value); 84025e992a4SHeiner Kallweit } 84125e992a4SHeiner Kallweit 84225e992a4SHeiner Kallweit static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) 84325e992a4SHeiner Kallweit { 8449c6850feSHeiner Kallweit if (reg == 0x1f) 8459c6850feSHeiner Kallweit return tp->ocp_base == OCP_STD_PHY_BASE ? 0 : tp->ocp_base >> 4; 8469c6850feSHeiner Kallweit 84725e992a4SHeiner Kallweit if (tp->ocp_base != OCP_STD_PHY_BASE) 84825e992a4SHeiner Kallweit reg -= 0x10; 84925e992a4SHeiner Kallweit 85025e992a4SHeiner Kallweit return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); 85125e992a4SHeiner Kallweit } 85225e992a4SHeiner Kallweit 85325e992a4SHeiner Kallweit static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value) 85425e992a4SHeiner Kallweit { 85525e992a4SHeiner Kallweit if (reg == 0x1f) { 85625e992a4SHeiner Kallweit tp->ocp_base = value << 4; 85725e992a4SHeiner Kallweit return; 85825e992a4SHeiner Kallweit } 85925e992a4SHeiner Kallweit 86025e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, tp->ocp_base + reg, value); 86125e992a4SHeiner Kallweit } 86225e992a4SHeiner Kallweit 86325e992a4SHeiner Kallweit static int mac_mcu_read(struct rtl8169_private *tp, int reg) 86425e992a4SHeiner Kallweit { 86525e992a4SHeiner Kallweit return r8168_mac_ocp_read(tp, tp->ocp_base + reg); 86625e992a4SHeiner Kallweit } 86725e992a4SHeiner Kallweit 86825e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_phyar_cond) 86925e992a4SHeiner Kallweit { 87025e992a4SHeiner Kallweit return RTL_R32(tp, PHYAR) & 0x80000000; 87125e992a4SHeiner Kallweit } 87225e992a4SHeiner Kallweit 87325e992a4SHeiner Kallweit static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value) 87425e992a4SHeiner Kallweit { 87525e992a4SHeiner Kallweit RTL_W32(tp, PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff)); 87625e992a4SHeiner Kallweit 877d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_phyar_cond, 25, 20); 87825e992a4SHeiner Kallweit /* 87925e992a4SHeiner Kallweit * According to hardware specs a 20us delay is required after write 88025e992a4SHeiner Kallweit * complete indication, but before sending next command. 88125e992a4SHeiner Kallweit */ 88225e992a4SHeiner Kallweit udelay(20); 88325e992a4SHeiner Kallweit } 88425e992a4SHeiner Kallweit 88525e992a4SHeiner Kallweit static int r8169_mdio_read(struct rtl8169_private *tp, int reg) 88625e992a4SHeiner Kallweit { 88725e992a4SHeiner Kallweit int value; 88825e992a4SHeiner Kallweit 88925e992a4SHeiner Kallweit RTL_W32(tp, PHYAR, 0x0 | (reg & 0x1f) << 16); 89025e992a4SHeiner Kallweit 891d6836ef0SHeiner Kallweit value = rtl_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ? 8929b994b4aSHeiner Kallweit RTL_R32(tp, PHYAR) & 0xffff : -ETIMEDOUT; 89325e992a4SHeiner Kallweit 89425e992a4SHeiner Kallweit /* 89525e992a4SHeiner Kallweit * According to hardware specs a 20us delay is required after read 89625e992a4SHeiner Kallweit * complete indication, but before sending next command. 89725e992a4SHeiner Kallweit */ 89825e992a4SHeiner Kallweit udelay(20); 89925e992a4SHeiner Kallweit 90025e992a4SHeiner Kallweit return value; 90125e992a4SHeiner Kallweit } 90225e992a4SHeiner Kallweit 90325e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocpar_cond) 90425e992a4SHeiner Kallweit { 90525e992a4SHeiner Kallweit return RTL_R32(tp, OCPAR) & OCPAR_FLAG; 90625e992a4SHeiner Kallweit } 90725e992a4SHeiner Kallweit 90825e992a4SHeiner Kallweit static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data) 90925e992a4SHeiner Kallweit { 91025e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT)); 91125e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_GPHY_WRITE_CMD); 91225e992a4SHeiner Kallweit RTL_W32(tp, EPHY_RXER_NUM, 0); 91325e992a4SHeiner Kallweit 914d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100); 91525e992a4SHeiner Kallweit } 91625e992a4SHeiner Kallweit 91725e992a4SHeiner Kallweit static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value) 91825e992a4SHeiner Kallweit { 91925e992a4SHeiner Kallweit r8168dp_1_mdio_access(tp, reg, 92025e992a4SHeiner Kallweit OCPDR_WRITE_CMD | (value & OCPDR_DATA_MASK)); 92125e992a4SHeiner Kallweit } 92225e992a4SHeiner Kallweit 92325e992a4SHeiner Kallweit static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg) 92425e992a4SHeiner Kallweit { 92525e992a4SHeiner Kallweit r8168dp_1_mdio_access(tp, reg, OCPDR_READ_CMD); 92625e992a4SHeiner Kallweit 92725e992a4SHeiner Kallweit mdelay(1); 92825e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_GPHY_READ_CMD); 92925e992a4SHeiner Kallweit RTL_W32(tp, EPHY_RXER_NUM, 0); 93025e992a4SHeiner Kallweit 931d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ? 9329b994b4aSHeiner Kallweit RTL_R32(tp, OCPDR) & OCPDR_DATA_MASK : -ETIMEDOUT; 93325e992a4SHeiner Kallweit } 93425e992a4SHeiner Kallweit 93525e992a4SHeiner Kallweit #define R8168DP_1_MDIO_ACCESS_BIT 0x00020000 93625e992a4SHeiner Kallweit 93725e992a4SHeiner Kallweit static void r8168dp_2_mdio_start(struct rtl8169_private *tp) 93825e992a4SHeiner Kallweit { 93925e992a4SHeiner Kallweit RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT); 94025e992a4SHeiner Kallweit } 94125e992a4SHeiner Kallweit 94225e992a4SHeiner Kallweit static void r8168dp_2_mdio_stop(struct rtl8169_private *tp) 94325e992a4SHeiner Kallweit { 94425e992a4SHeiner Kallweit RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) | R8168DP_1_MDIO_ACCESS_BIT); 94525e992a4SHeiner Kallweit } 94625e992a4SHeiner Kallweit 94725e992a4SHeiner Kallweit static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value) 94825e992a4SHeiner Kallweit { 94925e992a4SHeiner Kallweit r8168dp_2_mdio_start(tp); 95025e992a4SHeiner Kallweit 95125e992a4SHeiner Kallweit r8169_mdio_write(tp, reg, value); 95225e992a4SHeiner Kallweit 95325e992a4SHeiner Kallweit r8168dp_2_mdio_stop(tp); 95425e992a4SHeiner Kallweit } 95525e992a4SHeiner Kallweit 95625e992a4SHeiner Kallweit static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) 95725e992a4SHeiner Kallweit { 95825e992a4SHeiner Kallweit int value; 95925e992a4SHeiner Kallweit 96062bdc8fdSHeiner Kallweit /* Work around issue with chip reporting wrong PHY ID */ 96162bdc8fdSHeiner Kallweit if (reg == MII_PHYSID2) 96262bdc8fdSHeiner Kallweit return 0xc912; 96362bdc8fdSHeiner Kallweit 96425e992a4SHeiner Kallweit r8168dp_2_mdio_start(tp); 96525e992a4SHeiner Kallweit 96625e992a4SHeiner Kallweit value = r8169_mdio_read(tp, reg); 96725e992a4SHeiner Kallweit 96825e992a4SHeiner Kallweit r8168dp_2_mdio_stop(tp); 96925e992a4SHeiner Kallweit 97025e992a4SHeiner Kallweit return value; 97125e992a4SHeiner Kallweit } 97225e992a4SHeiner Kallweit 97325e992a4SHeiner Kallweit static void rtl_writephy(struct rtl8169_private *tp, int location, int val) 97425e992a4SHeiner Kallweit { 97525e992a4SHeiner Kallweit switch (tp->mac_version) { 97625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 97725e992a4SHeiner Kallweit r8168dp_1_mdio_write(tp, location, val); 97825e992a4SHeiner Kallweit break; 97925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 98025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 98125e992a4SHeiner Kallweit r8168dp_2_mdio_write(tp, location, val); 98225e992a4SHeiner Kallweit break; 983f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61: 98425e992a4SHeiner Kallweit r8168g_mdio_write(tp, location, val); 98525e992a4SHeiner Kallweit break; 98625e992a4SHeiner Kallweit default: 98725e992a4SHeiner Kallweit r8169_mdio_write(tp, location, val); 98825e992a4SHeiner Kallweit break; 98925e992a4SHeiner Kallweit } 99025e992a4SHeiner Kallweit } 99125e992a4SHeiner Kallweit 99225e992a4SHeiner Kallweit static int rtl_readphy(struct rtl8169_private *tp, int location) 99325e992a4SHeiner Kallweit { 99425e992a4SHeiner Kallweit switch (tp->mac_version) { 99525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 99625e992a4SHeiner Kallweit return r8168dp_1_mdio_read(tp, location); 99725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 99825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 99925e992a4SHeiner Kallweit return r8168dp_2_mdio_read(tp, location); 1000f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61: 100125e992a4SHeiner Kallweit return r8168g_mdio_read(tp, location); 100225e992a4SHeiner Kallweit default: 100325e992a4SHeiner Kallweit return r8169_mdio_read(tp, location); 100425e992a4SHeiner Kallweit } 100525e992a4SHeiner Kallweit } 100625e992a4SHeiner Kallweit 100725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ephyar_cond) 100825e992a4SHeiner Kallweit { 100925e992a4SHeiner Kallweit return RTL_R32(tp, EPHYAR) & EPHYAR_FLAG; 101025e992a4SHeiner Kallweit } 101125e992a4SHeiner Kallweit 101225e992a4SHeiner Kallweit static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value) 101325e992a4SHeiner Kallweit { 101425e992a4SHeiner Kallweit RTL_W32(tp, EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) | 101525e992a4SHeiner Kallweit (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 101625e992a4SHeiner Kallweit 1017d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100); 101825e992a4SHeiner Kallweit 101925e992a4SHeiner Kallweit udelay(10); 102025e992a4SHeiner Kallweit } 102125e992a4SHeiner Kallweit 102225e992a4SHeiner Kallweit static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr) 102325e992a4SHeiner Kallweit { 102425e992a4SHeiner Kallweit RTL_W32(tp, EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 102525e992a4SHeiner Kallweit 1026d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ? 102725e992a4SHeiner Kallweit RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0; 102825e992a4SHeiner Kallweit } 102925e992a4SHeiner Kallweit 1030561535b0SHeiner Kallweit static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type) 1031561535b0SHeiner Kallweit { 1032561535b0SHeiner Kallweit /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ 1033561535b0SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB) 1034561535b0SHeiner Kallweit *cmd |= 0x7f0 << 18; 1035561535b0SHeiner Kallweit } 1036561535b0SHeiner Kallweit 103725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_eriar_cond) 103825e992a4SHeiner Kallweit { 103925e992a4SHeiner Kallweit return RTL_R32(tp, ERIAR) & ERIAR_FLAG; 104025e992a4SHeiner Kallweit } 104125e992a4SHeiner Kallweit 104225e992a4SHeiner Kallweit static void _rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 104325e992a4SHeiner Kallweit u32 val, int type) 104425e992a4SHeiner Kallweit { 1045561535b0SHeiner Kallweit u32 cmd = ERIAR_WRITE_CMD | type | mask | addr; 1046561535b0SHeiner Kallweit 104725e992a4SHeiner Kallweit BUG_ON((addr & 3) || (mask == 0)); 104825e992a4SHeiner Kallweit RTL_W32(tp, ERIDR, val); 1049561535b0SHeiner Kallweit r8168fp_adjust_ocp_cmd(tp, &cmd, type); 1050561535b0SHeiner Kallweit RTL_W32(tp, ERIAR, cmd); 105125e992a4SHeiner Kallweit 1052d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); 105325e992a4SHeiner Kallweit } 105425e992a4SHeiner Kallweit 105525e992a4SHeiner Kallweit static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 105625e992a4SHeiner Kallweit u32 val) 105725e992a4SHeiner Kallweit { 105825e992a4SHeiner Kallweit _rtl_eri_write(tp, addr, mask, val, ERIAR_EXGMAC); 105925e992a4SHeiner Kallweit } 106025e992a4SHeiner Kallweit 106125e992a4SHeiner Kallweit static u32 _rtl_eri_read(struct rtl8169_private *tp, int addr, int type) 106225e992a4SHeiner Kallweit { 1063561535b0SHeiner Kallweit u32 cmd = ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr; 1064561535b0SHeiner Kallweit 1065561535b0SHeiner Kallweit r8168fp_adjust_ocp_cmd(tp, &cmd, type); 1066561535b0SHeiner Kallweit RTL_W32(tp, ERIAR, cmd); 106725e992a4SHeiner Kallweit 1068d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? 106925e992a4SHeiner Kallweit RTL_R32(tp, ERIDR) : ~0; 107025e992a4SHeiner Kallweit } 107125e992a4SHeiner Kallweit 107225e992a4SHeiner Kallweit static u32 rtl_eri_read(struct rtl8169_private *tp, int addr) 107325e992a4SHeiner Kallweit { 107425e992a4SHeiner Kallweit return _rtl_eri_read(tp, addr, ERIAR_EXGMAC); 107525e992a4SHeiner Kallweit } 107625e992a4SHeiner Kallweit 107754113dedSHeiner Kallweit static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 p, u32 m) 107825e992a4SHeiner Kallweit { 107954113dedSHeiner Kallweit u32 val = rtl_eri_read(tp, addr); 108025e992a4SHeiner Kallweit 108154113dedSHeiner Kallweit rtl_eri_write(tp, addr, ERIAR_MASK_1111, (val & ~m) | p); 108225e992a4SHeiner Kallweit } 108325e992a4SHeiner Kallweit 108454113dedSHeiner Kallweit static void rtl_eri_set_bits(struct rtl8169_private *tp, int addr, u32 p) 108525e992a4SHeiner Kallweit { 108654113dedSHeiner Kallweit rtl_w0w1_eri(tp, addr, p, 0); 108725e992a4SHeiner Kallweit } 108825e992a4SHeiner Kallweit 108954113dedSHeiner Kallweit static void rtl_eri_clear_bits(struct rtl8169_private *tp, int addr, u32 m) 109025e992a4SHeiner Kallweit { 109154113dedSHeiner Kallweit rtl_w0w1_eri(tp, addr, 0, m); 109225e992a4SHeiner Kallweit } 109325e992a4SHeiner Kallweit 1094a15aaa03SHeiner Kallweit static u32 r8168dp_ocp_read(struct rtl8169_private *tp, u16 reg) 109525e992a4SHeiner Kallweit { 1096a15aaa03SHeiner Kallweit RTL_W32(tp, OCPAR, 0x0fu << 12 | (reg & 0x0fff)); 1097d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ? 109825e992a4SHeiner Kallweit RTL_R32(tp, OCPDR) : ~0; 109925e992a4SHeiner Kallweit } 110025e992a4SHeiner Kallweit 1101787c0c04SHeiner Kallweit static u32 r8168ep_ocp_read(struct rtl8169_private *tp, u16 reg) 110225e992a4SHeiner Kallweit { 110325e992a4SHeiner Kallweit return _rtl_eri_read(tp, reg, ERIAR_OOB); 110425e992a4SHeiner Kallweit } 110525e992a4SHeiner Kallweit 110625e992a4SHeiner Kallweit static void r8168dp_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, 110725e992a4SHeiner Kallweit u32 data) 110825e992a4SHeiner Kallweit { 110925e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, data); 111025e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); 1111d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20); 111225e992a4SHeiner Kallweit } 111325e992a4SHeiner Kallweit 111425e992a4SHeiner Kallweit static void r8168ep_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, 111525e992a4SHeiner Kallweit u32 data) 111625e992a4SHeiner Kallweit { 111725e992a4SHeiner Kallweit _rtl_eri_write(tp, reg, ((u32)mask & 0x0f) << ERIAR_MASK_SHIFT, 111825e992a4SHeiner Kallweit data, ERIAR_OOB); 111925e992a4SHeiner Kallweit } 112025e992a4SHeiner Kallweit 112125e992a4SHeiner Kallweit static void r8168dp_oob_notify(struct rtl8169_private *tp, u8 cmd) 112225e992a4SHeiner Kallweit { 112325e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe8, ERIAR_MASK_0001, cmd); 112425e992a4SHeiner Kallweit 112525e992a4SHeiner Kallweit r8168dp_ocp_write(tp, 0x1, 0x30, 0x00000001); 112625e992a4SHeiner Kallweit } 112725e992a4SHeiner Kallweit 112825e992a4SHeiner Kallweit #define OOB_CMD_RESET 0x00 112925e992a4SHeiner Kallweit #define OOB_CMD_DRIVER_START 0x05 113025e992a4SHeiner Kallweit #define OOB_CMD_DRIVER_STOP 0x06 113125e992a4SHeiner Kallweit 113225e992a4SHeiner Kallweit static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp) 113325e992a4SHeiner Kallweit { 113425e992a4SHeiner Kallweit return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10; 113525e992a4SHeiner Kallweit } 113625e992a4SHeiner Kallweit 113725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_dp_ocp_read_cond) 113825e992a4SHeiner Kallweit { 113925e992a4SHeiner Kallweit u16 reg; 114025e992a4SHeiner Kallweit 114125e992a4SHeiner Kallweit reg = rtl8168_get_ocp_reg(tp); 114225e992a4SHeiner Kallweit 1143a15aaa03SHeiner Kallweit return r8168dp_ocp_read(tp, reg) & 0x00000800; 114425e992a4SHeiner Kallweit } 114525e992a4SHeiner Kallweit 114625e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ep_ocp_read_cond) 114725e992a4SHeiner Kallweit { 1148787c0c04SHeiner Kallweit return r8168ep_ocp_read(tp, 0x124) & 0x00000001; 114925e992a4SHeiner Kallweit } 115025e992a4SHeiner Kallweit 115125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocp_tx_cond) 115225e992a4SHeiner Kallweit { 115325e992a4SHeiner Kallweit return RTL_R8(tp, IBISR0) & 0x20; 115425e992a4SHeiner Kallweit } 115525e992a4SHeiner Kallweit 115625e992a4SHeiner Kallweit static void rtl8168ep_stop_cmac(struct rtl8169_private *tp) 115725e992a4SHeiner Kallweit { 115825e992a4SHeiner Kallweit RTL_W8(tp, IBCR2, RTL_R8(tp, IBCR2) & ~0x01); 1159d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_ocp_tx_cond, 50000, 2000); 116025e992a4SHeiner Kallweit RTL_W8(tp, IBISR0, RTL_R8(tp, IBISR0) | 0x20); 116125e992a4SHeiner Kallweit RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01); 116225e992a4SHeiner Kallweit } 116325e992a4SHeiner Kallweit 116425e992a4SHeiner Kallweit static void rtl8168dp_driver_start(struct rtl8169_private *tp) 116525e992a4SHeiner Kallweit { 116625e992a4SHeiner Kallweit r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START); 1167d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10); 116825e992a4SHeiner Kallweit } 116925e992a4SHeiner Kallweit 117025e992a4SHeiner Kallweit static void rtl8168ep_driver_start(struct rtl8169_private *tp) 117125e992a4SHeiner Kallweit { 117225e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START); 1173787c0c04SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01); 1174d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 10); 117525e992a4SHeiner Kallweit } 117625e992a4SHeiner Kallweit 117725e992a4SHeiner Kallweit static void rtl8168_driver_start(struct rtl8169_private *tp) 117825e992a4SHeiner Kallweit { 117925e992a4SHeiner Kallweit switch (tp->mac_version) { 118025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 118125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 118225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 118325e992a4SHeiner Kallweit rtl8168dp_driver_start(tp); 118425e992a4SHeiner Kallweit break; 11851287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 118625e992a4SHeiner Kallweit rtl8168ep_driver_start(tp); 118725e992a4SHeiner Kallweit break; 118825e992a4SHeiner Kallweit default: 118925e992a4SHeiner Kallweit BUG(); 119025e992a4SHeiner Kallweit break; 119125e992a4SHeiner Kallweit } 119225e992a4SHeiner Kallweit } 119325e992a4SHeiner Kallweit 119425e992a4SHeiner Kallweit static void rtl8168dp_driver_stop(struct rtl8169_private *tp) 119525e992a4SHeiner Kallweit { 119625e992a4SHeiner Kallweit r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP); 1197d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10); 119825e992a4SHeiner Kallweit } 119925e992a4SHeiner Kallweit 120025e992a4SHeiner Kallweit static void rtl8168ep_driver_stop(struct rtl8169_private *tp) 120125e992a4SHeiner Kallweit { 120225e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp); 120325e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP); 1204787c0c04SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01); 1205d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10); 120625e992a4SHeiner Kallweit } 120725e992a4SHeiner Kallweit 120825e992a4SHeiner Kallweit static void rtl8168_driver_stop(struct rtl8169_private *tp) 120925e992a4SHeiner Kallweit { 121025e992a4SHeiner Kallweit switch (tp->mac_version) { 121125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 121225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 121325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 121425e992a4SHeiner Kallweit rtl8168dp_driver_stop(tp); 121525e992a4SHeiner Kallweit break; 12161287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 121725e992a4SHeiner Kallweit rtl8168ep_driver_stop(tp); 121825e992a4SHeiner Kallweit break; 121925e992a4SHeiner Kallweit default: 122025e992a4SHeiner Kallweit BUG(); 122125e992a4SHeiner Kallweit break; 122225e992a4SHeiner Kallweit } 122325e992a4SHeiner Kallweit } 122425e992a4SHeiner Kallweit 122525e992a4SHeiner Kallweit static bool r8168dp_check_dash(struct rtl8169_private *tp) 122625e992a4SHeiner Kallweit { 122725e992a4SHeiner Kallweit u16 reg = rtl8168_get_ocp_reg(tp); 122825e992a4SHeiner Kallweit 1229a15aaa03SHeiner Kallweit return !!(r8168dp_ocp_read(tp, reg) & 0x00008000); 123025e992a4SHeiner Kallweit } 123125e992a4SHeiner Kallweit 123225e992a4SHeiner Kallweit static bool r8168ep_check_dash(struct rtl8169_private *tp) 123325e992a4SHeiner Kallweit { 1234787c0c04SHeiner Kallweit return r8168ep_ocp_read(tp, 0x128) & 0x00000001; 123525e992a4SHeiner Kallweit } 123625e992a4SHeiner Kallweit 123725e992a4SHeiner Kallweit static bool r8168_check_dash(struct rtl8169_private *tp) 123825e992a4SHeiner Kallweit { 123925e992a4SHeiner Kallweit switch (tp->mac_version) { 124025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 124125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 124225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 124325e992a4SHeiner Kallweit return r8168dp_check_dash(tp); 12441287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 124525e992a4SHeiner Kallweit return r8168ep_check_dash(tp); 124625e992a4SHeiner Kallweit default: 124725e992a4SHeiner Kallweit return false; 124825e992a4SHeiner Kallweit } 124925e992a4SHeiner Kallweit } 125025e992a4SHeiner Kallweit 125125e992a4SHeiner Kallweit static void rtl_reset_packet_filter(struct rtl8169_private *tp) 125225e992a4SHeiner Kallweit { 125354113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0xdc, BIT(0)); 125454113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xdc, BIT(0)); 125525e992a4SHeiner Kallweit } 125625e992a4SHeiner Kallweit 125725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_efusear_cond) 125825e992a4SHeiner Kallweit { 125925e992a4SHeiner Kallweit return RTL_R32(tp, EFUSEAR) & EFUSEAR_FLAG; 126025e992a4SHeiner Kallweit } 126125e992a4SHeiner Kallweit 12622992bdfaSHeiner Kallweit u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr) 126325e992a4SHeiner Kallweit { 126425e992a4SHeiner Kallweit RTL_W32(tp, EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT); 126525e992a4SHeiner Kallweit 1266d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ? 126725e992a4SHeiner Kallweit RTL_R32(tp, EFUSEAR) & EFUSEAR_DATA_MASK : ~0; 126825e992a4SHeiner Kallweit } 126925e992a4SHeiner Kallweit 1270c1d532d2SHeiner Kallweit static u32 rtl_get_events(struct rtl8169_private *tp) 1271c1d532d2SHeiner Kallweit { 1272f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1273f1bce4adSHeiner Kallweit return RTL_R32(tp, IntrStatus_8125); 1274f1bce4adSHeiner Kallweit else 1275c1d532d2SHeiner Kallweit return RTL_R16(tp, IntrStatus); 1276c1d532d2SHeiner Kallweit } 1277c1d532d2SHeiner Kallweit 1278c1d532d2SHeiner Kallweit static void rtl_ack_events(struct rtl8169_private *tp, u32 bits) 127925e992a4SHeiner Kallweit { 1280f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1281f1bce4adSHeiner Kallweit RTL_W32(tp, IntrStatus_8125, bits); 1282f1bce4adSHeiner Kallweit else 128325e992a4SHeiner Kallweit RTL_W16(tp, IntrStatus, bits); 128425e992a4SHeiner Kallweit } 128525e992a4SHeiner Kallweit 128625e992a4SHeiner Kallweit static void rtl_irq_disable(struct rtl8169_private *tp) 128725e992a4SHeiner Kallweit { 1288f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1289f1bce4adSHeiner Kallweit RTL_W32(tp, IntrMask_8125, 0); 1290f1bce4adSHeiner Kallweit else 129125e992a4SHeiner Kallweit RTL_W16(tp, IntrMask, 0); 129225e992a4SHeiner Kallweit tp->irq_enabled = 0; 129325e992a4SHeiner Kallweit } 129425e992a4SHeiner Kallweit 129525e992a4SHeiner Kallweit static void rtl_irq_enable(struct rtl8169_private *tp) 129625e992a4SHeiner Kallweit { 129725e992a4SHeiner Kallweit tp->irq_enabled = 1; 1298f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1299f1bce4adSHeiner Kallweit RTL_W32(tp, IntrMask_8125, tp->irq_mask); 1300f1bce4adSHeiner Kallweit else 130125e992a4SHeiner Kallweit RTL_W16(tp, IntrMask, tp->irq_mask); 130225e992a4SHeiner Kallweit } 130325e992a4SHeiner Kallweit 130425e992a4SHeiner Kallweit static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) 130525e992a4SHeiner Kallweit { 130625e992a4SHeiner Kallweit rtl_irq_disable(tp); 1307c1d532d2SHeiner Kallweit rtl_ack_events(tp, 0xffffffff); 1308711463f8SHeiner Kallweit rtl_pci_commit(tp); 130925e992a4SHeiner Kallweit } 131025e992a4SHeiner Kallweit 131125e992a4SHeiner Kallweit static void rtl_link_chg_patch(struct rtl8169_private *tp) 131225e992a4SHeiner Kallweit { 131325e992a4SHeiner Kallweit struct phy_device *phydev = tp->phydev; 131425e992a4SHeiner Kallweit 131525e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34 || 131625e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_38) { 131725e992a4SHeiner Kallweit if (phydev->speed == SPEED_1000) { 131825e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011); 131925e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 132025e992a4SHeiner Kallweit } else if (phydev->speed == SPEED_100) { 132125e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 132225e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 132325e992a4SHeiner Kallweit } else { 132425e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 132525e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f); 132625e992a4SHeiner Kallweit } 132725e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 132825e992a4SHeiner Kallweit } else if (tp->mac_version == RTL_GIGA_MAC_VER_35 || 132925e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_36) { 133025e992a4SHeiner Kallweit if (phydev->speed == SPEED_1000) { 133125e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011); 133225e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 133325e992a4SHeiner Kallweit } else { 133425e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 133525e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f); 133625e992a4SHeiner Kallweit } 133725e992a4SHeiner Kallweit } else if (tp->mac_version == RTL_GIGA_MAC_VER_37) { 133825e992a4SHeiner Kallweit if (phydev->speed == SPEED_10) { 133925e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02); 134025e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060a); 134125e992a4SHeiner Kallweit } else { 134225e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000); 134325e992a4SHeiner Kallweit } 134425e992a4SHeiner Kallweit } 134525e992a4SHeiner Kallweit } 134625e992a4SHeiner Kallweit 134725e992a4SHeiner Kallweit #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) 134825e992a4SHeiner Kallweit 134925e992a4SHeiner Kallweit static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 135025e992a4SHeiner Kallweit { 135125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 135225e992a4SHeiner Kallweit 135325e992a4SHeiner Kallweit rtl_lock_work(tp); 135425e992a4SHeiner Kallweit wol->supported = WAKE_ANY; 135525e992a4SHeiner Kallweit wol->wolopts = tp->saved_wolopts; 135625e992a4SHeiner Kallweit rtl_unlock_work(tp); 135725e992a4SHeiner Kallweit } 135825e992a4SHeiner Kallweit 135925e992a4SHeiner Kallweit static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) 136025e992a4SHeiner Kallweit { 136125e992a4SHeiner Kallweit static const struct { 136225e992a4SHeiner Kallweit u32 opt; 136325e992a4SHeiner Kallweit u16 reg; 136425e992a4SHeiner Kallweit u8 mask; 136525e992a4SHeiner Kallweit } cfg[] = { 136625e992a4SHeiner Kallweit { WAKE_PHY, Config3, LinkUp }, 136725e992a4SHeiner Kallweit { WAKE_UCAST, Config5, UWF }, 136825e992a4SHeiner Kallweit { WAKE_BCAST, Config5, BWF }, 136925e992a4SHeiner Kallweit { WAKE_MCAST, Config5, MWF }, 137025e992a4SHeiner Kallweit { WAKE_ANY, Config5, LanWake }, 137125e992a4SHeiner Kallweit { WAKE_MAGIC, Config3, MagicPacket } 137225e992a4SHeiner Kallweit }; 1373f1bce4adSHeiner Kallweit unsigned int i, tmp = ARRAY_SIZE(cfg); 137425e992a4SHeiner Kallweit u8 options; 137525e992a4SHeiner Kallweit 137625e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 137725e992a4SHeiner Kallweit 13789e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp)) { 1379f1bce4adSHeiner Kallweit tmp--; 138025e992a4SHeiner Kallweit if (wolopts & WAKE_MAGIC) 138154113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x0dc, MagicPacket_v2); 138225e992a4SHeiner Kallweit else 138354113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x0dc, MagicPacket_v2); 1384f1bce4adSHeiner Kallweit } else if (rtl_is_8125(tp)) { 1385f1bce4adSHeiner Kallweit tmp--; 1386f1bce4adSHeiner Kallweit if (wolopts & WAKE_MAGIC) 1387f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b6, 0, BIT(0)); 1388f1bce4adSHeiner Kallweit else 1389f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0); 139025e992a4SHeiner Kallweit } 139125e992a4SHeiner Kallweit 139225e992a4SHeiner Kallweit for (i = 0; i < tmp; i++) { 139325e992a4SHeiner Kallweit options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; 139425e992a4SHeiner Kallweit if (wolopts & cfg[i].opt) 139525e992a4SHeiner Kallweit options |= cfg[i].mask; 139625e992a4SHeiner Kallweit RTL_W8(tp, cfg[i].reg, options); 139725e992a4SHeiner Kallweit } 139825e992a4SHeiner Kallweit 139925e992a4SHeiner Kallweit switch (tp->mac_version) { 1400edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 140125e992a4SHeiner Kallweit options = RTL_R8(tp, Config1) & ~PMEnable; 140225e992a4SHeiner Kallweit if (wolopts) 140325e992a4SHeiner Kallweit options |= PMEnable; 140425e992a4SHeiner Kallweit RTL_W8(tp, Config1, options); 140525e992a4SHeiner Kallweit break; 1406edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_34: 1407edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_37: 1408838974e1SHeiner Kallweit case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_61: 140925e992a4SHeiner Kallweit options = RTL_R8(tp, Config2) & ~PME_SIGNAL; 141025e992a4SHeiner Kallweit if (wolopts) 141125e992a4SHeiner Kallweit options |= PME_SIGNAL; 141225e992a4SHeiner Kallweit RTL_W8(tp, Config2, options); 141325e992a4SHeiner Kallweit break; 1414edcde3eeSHeiner Kallweit default: 1415edcde3eeSHeiner Kallweit break; 141625e992a4SHeiner Kallweit } 141725e992a4SHeiner Kallweit 141825e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 141925e992a4SHeiner Kallweit 142025e992a4SHeiner Kallweit device_set_wakeup_enable(tp_to_dev(tp), wolopts); 1421398fd408SHeiner Kallweit tp->dev->wol_enabled = wolopts ? 1 : 0; 142225e992a4SHeiner Kallweit } 142325e992a4SHeiner Kallweit 142425e992a4SHeiner Kallweit static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 142525e992a4SHeiner Kallweit { 142625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 142725e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 142825e992a4SHeiner Kallweit 142925e992a4SHeiner Kallweit if (wol->wolopts & ~WAKE_ANY) 143025e992a4SHeiner Kallweit return -EINVAL; 143125e992a4SHeiner Kallweit 143225e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 143325e992a4SHeiner Kallweit 143425e992a4SHeiner Kallweit rtl_lock_work(tp); 143525e992a4SHeiner Kallweit 143625e992a4SHeiner Kallweit tp->saved_wolopts = wol->wolopts; 143725e992a4SHeiner Kallweit 143825e992a4SHeiner Kallweit if (pm_runtime_active(d)) 143925e992a4SHeiner Kallweit __rtl8169_set_wol(tp, tp->saved_wolopts); 144025e992a4SHeiner Kallweit 144125e992a4SHeiner Kallweit rtl_unlock_work(tp); 144225e992a4SHeiner Kallweit 144325e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 144425e992a4SHeiner Kallweit 144525e992a4SHeiner Kallweit return 0; 144625e992a4SHeiner Kallweit } 144725e992a4SHeiner Kallweit 144825e992a4SHeiner Kallweit static void rtl8169_get_drvinfo(struct net_device *dev, 144925e992a4SHeiner Kallweit struct ethtool_drvinfo *info) 145025e992a4SHeiner Kallweit { 145125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 145225e992a4SHeiner Kallweit struct rtl_fw *rtl_fw = tp->rtl_fw; 145325e992a4SHeiner Kallweit 145425e992a4SHeiner Kallweit strlcpy(info->driver, MODULENAME, sizeof(info->driver)); 145525e992a4SHeiner Kallweit strlcpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); 145625e992a4SHeiner Kallweit BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); 145725e992a4SHeiner Kallweit if (rtl_fw) 145825e992a4SHeiner Kallweit strlcpy(info->fw_version, rtl_fw->version, 145925e992a4SHeiner Kallweit sizeof(info->fw_version)); 146025e992a4SHeiner Kallweit } 146125e992a4SHeiner Kallweit 146225e992a4SHeiner Kallweit static int rtl8169_get_regs_len(struct net_device *dev) 146325e992a4SHeiner Kallweit { 146425e992a4SHeiner Kallweit return R8169_REGS_SIZE; 146525e992a4SHeiner Kallweit } 146625e992a4SHeiner Kallweit 146725e992a4SHeiner Kallweit static netdev_features_t rtl8169_fix_features(struct net_device *dev, 146825e992a4SHeiner Kallweit netdev_features_t features) 146925e992a4SHeiner Kallweit { 147025e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 147125e992a4SHeiner Kallweit 147225e992a4SHeiner Kallweit if (dev->mtu > TD_MSS_MAX) 147325e992a4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 147425e992a4SHeiner Kallweit 1475a8ec173aSHeiner Kallweit if (dev->mtu > ETH_DATA_LEN && 147625e992a4SHeiner Kallweit tp->mac_version > RTL_GIGA_MAC_VER_06) 14777cb83b21SHeiner Kallweit features &= ~(NETIF_F_CSUM_MASK | NETIF_F_ALL_TSO); 147825e992a4SHeiner Kallweit 147925e992a4SHeiner Kallweit return features; 148025e992a4SHeiner Kallweit } 148125e992a4SHeiner Kallweit 148210478283SHeiner Kallweit static void rtl_set_rx_config_features(struct rtl8169_private *tp, 148325e992a4SHeiner Kallweit netdev_features_t features) 148425e992a4SHeiner Kallweit { 148510478283SHeiner Kallweit u32 rx_config = RTL_R32(tp, RxConfig); 148625e992a4SHeiner Kallweit 148725e992a4SHeiner Kallweit if (features & NETIF_F_RXALL) 148810478283SHeiner Kallweit rx_config |= RX_CONFIG_ACCEPT_ERR_MASK; 148925e992a4SHeiner Kallweit else 149010478283SHeiner Kallweit rx_config &= ~RX_CONFIG_ACCEPT_ERR_MASK; 149125e992a4SHeiner Kallweit 1492f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) { 1493f1bce4adSHeiner Kallweit if (features & NETIF_F_HW_VLAN_CTAG_RX) 1494f1bce4adSHeiner Kallweit rx_config |= RX_VLAN_8125; 1495f1bce4adSHeiner Kallweit else 1496f1bce4adSHeiner Kallweit rx_config &= ~RX_VLAN_8125; 1497f1bce4adSHeiner Kallweit } 1498f1bce4adSHeiner Kallweit 149925e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, rx_config); 150010478283SHeiner Kallweit } 150110478283SHeiner Kallweit 150210478283SHeiner Kallweit static int rtl8169_set_features(struct net_device *dev, 150310478283SHeiner Kallweit netdev_features_t features) 150410478283SHeiner Kallweit { 150510478283SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 150610478283SHeiner Kallweit 150710478283SHeiner Kallweit rtl_lock_work(tp); 150810478283SHeiner Kallweit 150910478283SHeiner Kallweit rtl_set_rx_config_features(tp, features); 151025e992a4SHeiner Kallweit 151125e992a4SHeiner Kallweit if (features & NETIF_F_RXCSUM) 151225e992a4SHeiner Kallweit tp->cp_cmd |= RxChkSum; 151325e992a4SHeiner Kallweit else 151425e992a4SHeiner Kallweit tp->cp_cmd &= ~RxChkSum; 151525e992a4SHeiner Kallweit 1516f1bce4adSHeiner Kallweit if (!rtl_is_8125(tp)) { 151725e992a4SHeiner Kallweit if (features & NETIF_F_HW_VLAN_CTAG_RX) 151825e992a4SHeiner Kallweit tp->cp_cmd |= RxVlan; 151925e992a4SHeiner Kallweit else 152025e992a4SHeiner Kallweit tp->cp_cmd &= ~RxVlan; 1521f1bce4adSHeiner Kallweit } 152225e992a4SHeiner Kallweit 152325e992a4SHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 1524711463f8SHeiner Kallweit rtl_pci_commit(tp); 152525e992a4SHeiner Kallweit 152625e992a4SHeiner Kallweit rtl_unlock_work(tp); 152725e992a4SHeiner Kallweit 152825e992a4SHeiner Kallweit return 0; 152925e992a4SHeiner Kallweit } 153025e992a4SHeiner Kallweit 153125e992a4SHeiner Kallweit static inline u32 rtl8169_tx_vlan_tag(struct sk_buff *skb) 153225e992a4SHeiner Kallweit { 153325e992a4SHeiner Kallweit return (skb_vlan_tag_present(skb)) ? 15347424edbbSHeiner Kallweit TxVlanTag | swab16(skb_vlan_tag_get(skb)) : 0x00; 153525e992a4SHeiner Kallweit } 153625e992a4SHeiner Kallweit 153725e992a4SHeiner Kallweit static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) 153825e992a4SHeiner Kallweit { 153925e992a4SHeiner Kallweit u32 opts2 = le32_to_cpu(desc->opts2); 154025e992a4SHeiner Kallweit 154125e992a4SHeiner Kallweit if (opts2 & RxVlanTag) 15427424edbbSHeiner Kallweit __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), swab16(opts2 & 0xffff)); 154325e992a4SHeiner Kallweit } 154425e992a4SHeiner Kallweit 154525e992a4SHeiner Kallweit static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, 154625e992a4SHeiner Kallweit void *p) 154725e992a4SHeiner Kallweit { 154825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 154925e992a4SHeiner Kallweit u32 __iomem *data = tp->mmio_addr; 155025e992a4SHeiner Kallweit u32 *dw = p; 155125e992a4SHeiner Kallweit int i; 155225e992a4SHeiner Kallweit 155325e992a4SHeiner Kallweit rtl_lock_work(tp); 155425e992a4SHeiner Kallweit for (i = 0; i < R8169_REGS_SIZE; i += 4) 155525e992a4SHeiner Kallweit memcpy_fromio(dw++, data++, 4); 155625e992a4SHeiner Kallweit rtl_unlock_work(tp); 155725e992a4SHeiner Kallweit } 155825e992a4SHeiner Kallweit 155925e992a4SHeiner Kallweit static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = { 156025e992a4SHeiner Kallweit "tx_packets", 156125e992a4SHeiner Kallweit "rx_packets", 156225e992a4SHeiner Kallweit "tx_errors", 156325e992a4SHeiner Kallweit "rx_errors", 156425e992a4SHeiner Kallweit "rx_missed", 156525e992a4SHeiner Kallweit "align_errors", 156625e992a4SHeiner Kallweit "tx_single_collisions", 156725e992a4SHeiner Kallweit "tx_multi_collisions", 156825e992a4SHeiner Kallweit "unicast", 156925e992a4SHeiner Kallweit "broadcast", 157025e992a4SHeiner Kallweit "multicast", 157125e992a4SHeiner Kallweit "tx_aborted", 157225e992a4SHeiner Kallweit "tx_underrun", 157325e992a4SHeiner Kallweit }; 157425e992a4SHeiner Kallweit 157525e992a4SHeiner Kallweit static int rtl8169_get_sset_count(struct net_device *dev, int sset) 157625e992a4SHeiner Kallweit { 157725e992a4SHeiner Kallweit switch (sset) { 157825e992a4SHeiner Kallweit case ETH_SS_STATS: 157925e992a4SHeiner Kallweit return ARRAY_SIZE(rtl8169_gstrings); 158025e992a4SHeiner Kallweit default: 158125e992a4SHeiner Kallweit return -EOPNOTSUPP; 158225e992a4SHeiner Kallweit } 158325e992a4SHeiner Kallweit } 158425e992a4SHeiner Kallweit 158525e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_counters_cond) 158625e992a4SHeiner Kallweit { 158725e992a4SHeiner Kallweit return RTL_R32(tp, CounterAddrLow) & (CounterReset | CounterDump); 158825e992a4SHeiner Kallweit } 158925e992a4SHeiner Kallweit 1590d56f58ceSHeiner Kallweit static void rtl8169_do_counters(struct rtl8169_private *tp, u32 counter_cmd) 159125e992a4SHeiner Kallweit { 159225e992a4SHeiner Kallweit dma_addr_t paddr = tp->counters_phys_addr; 159325e992a4SHeiner Kallweit u32 cmd; 159425e992a4SHeiner Kallweit 159525e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32); 1596711463f8SHeiner Kallweit rtl_pci_commit(tp); 159725e992a4SHeiner Kallweit cmd = (u64)paddr & DMA_BIT_MASK(32); 159825e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrLow, cmd); 159925e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrLow, cmd | counter_cmd); 160025e992a4SHeiner Kallweit 1601d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_counters_cond, 10, 1000); 160225e992a4SHeiner Kallweit } 160325e992a4SHeiner Kallweit 1604d56f58ceSHeiner Kallweit static void rtl8169_reset_counters(struct rtl8169_private *tp) 160525e992a4SHeiner Kallweit { 160625e992a4SHeiner Kallweit /* 160725e992a4SHeiner Kallweit * Versions prior to RTL_GIGA_MAC_VER_19 don't support resetting the 160825e992a4SHeiner Kallweit * tally counters. 160925e992a4SHeiner Kallweit */ 1610d56f58ceSHeiner Kallweit if (tp->mac_version >= RTL_GIGA_MAC_VER_19) 1611d56f58ceSHeiner Kallweit rtl8169_do_counters(tp, CounterReset); 161225e992a4SHeiner Kallweit } 161325e992a4SHeiner Kallweit 1614d56f58ceSHeiner Kallweit static void rtl8169_update_counters(struct rtl8169_private *tp) 161525e992a4SHeiner Kallweit { 161625e992a4SHeiner Kallweit u8 val = RTL_R8(tp, ChipCmd); 161725e992a4SHeiner Kallweit 161825e992a4SHeiner Kallweit /* 161925e992a4SHeiner Kallweit * Some chips are unable to dump tally counters when the receiver 162025e992a4SHeiner Kallweit * is disabled. If 0xff chip may be in a PCI power-save state. 162125e992a4SHeiner Kallweit */ 1622d56f58ceSHeiner Kallweit if (val & CmdRxEnb && val != 0xff) 1623d56f58ceSHeiner Kallweit rtl8169_do_counters(tp, CounterDump); 162425e992a4SHeiner Kallweit } 162525e992a4SHeiner Kallweit 1626d56f58ceSHeiner Kallweit static void rtl8169_init_counter_offsets(struct rtl8169_private *tp) 162725e992a4SHeiner Kallweit { 162825e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 162925e992a4SHeiner Kallweit 163025e992a4SHeiner Kallweit /* 163125e992a4SHeiner Kallweit * rtl8169_init_counter_offsets is called from rtl_open. On chip 163225e992a4SHeiner Kallweit * versions prior to RTL_GIGA_MAC_VER_19 the tally counters are only 163325e992a4SHeiner Kallweit * reset by a power cycle, while the counter values collected by the 163425e992a4SHeiner Kallweit * driver are reset at every driver unload/load cycle. 163525e992a4SHeiner Kallweit * 163625e992a4SHeiner Kallweit * To make sure the HW values returned by @get_stats64 match the SW 163725e992a4SHeiner Kallweit * values, we collect the initial values at first open(*) and use them 163825e992a4SHeiner Kallweit * as offsets to normalize the values returned by @get_stats64. 163925e992a4SHeiner Kallweit * 164025e992a4SHeiner Kallweit * (*) We can't call rtl8169_init_counter_offsets from rtl_init_one 164125e992a4SHeiner Kallweit * for the reason stated in rtl8169_update_counters; CmdRxEnb is only 164225e992a4SHeiner Kallweit * set at open time by rtl_hw_start. 164325e992a4SHeiner Kallweit */ 164425e992a4SHeiner Kallweit 164525e992a4SHeiner Kallweit if (tp->tc_offset.inited) 1646d56f58ceSHeiner Kallweit return; 164725e992a4SHeiner Kallweit 1648d56f58ceSHeiner Kallweit rtl8169_reset_counters(tp); 1649d56f58ceSHeiner Kallweit rtl8169_update_counters(tp); 165025e992a4SHeiner Kallweit 165125e992a4SHeiner Kallweit tp->tc_offset.tx_errors = counters->tx_errors; 165225e992a4SHeiner Kallweit tp->tc_offset.tx_multi_collision = counters->tx_multi_collision; 165325e992a4SHeiner Kallweit tp->tc_offset.tx_aborted = counters->tx_aborted; 16540da3359aSHeiner Kallweit tp->tc_offset.rx_missed = counters->rx_missed; 165525e992a4SHeiner Kallweit tp->tc_offset.inited = true; 165625e992a4SHeiner Kallweit } 165725e992a4SHeiner Kallweit 165825e992a4SHeiner Kallweit static void rtl8169_get_ethtool_stats(struct net_device *dev, 165925e992a4SHeiner Kallweit struct ethtool_stats *stats, u64 *data) 166025e992a4SHeiner Kallweit { 166125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 166225e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 166325e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 166425e992a4SHeiner Kallweit 166525e992a4SHeiner Kallweit ASSERT_RTNL(); 166625e992a4SHeiner Kallweit 166725e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 166825e992a4SHeiner Kallweit 166925e992a4SHeiner Kallweit if (pm_runtime_active(d)) 167025e992a4SHeiner Kallweit rtl8169_update_counters(tp); 167125e992a4SHeiner Kallweit 167225e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 167325e992a4SHeiner Kallweit 167425e992a4SHeiner Kallweit data[0] = le64_to_cpu(counters->tx_packets); 167525e992a4SHeiner Kallweit data[1] = le64_to_cpu(counters->rx_packets); 167625e992a4SHeiner Kallweit data[2] = le64_to_cpu(counters->tx_errors); 167725e992a4SHeiner Kallweit data[3] = le32_to_cpu(counters->rx_errors); 167825e992a4SHeiner Kallweit data[4] = le16_to_cpu(counters->rx_missed); 167925e992a4SHeiner Kallweit data[5] = le16_to_cpu(counters->align_errors); 168025e992a4SHeiner Kallweit data[6] = le32_to_cpu(counters->tx_one_collision); 168125e992a4SHeiner Kallweit data[7] = le32_to_cpu(counters->tx_multi_collision); 168225e992a4SHeiner Kallweit data[8] = le64_to_cpu(counters->rx_unicast); 168325e992a4SHeiner Kallweit data[9] = le64_to_cpu(counters->rx_broadcast); 168425e992a4SHeiner Kallweit data[10] = le32_to_cpu(counters->rx_multicast); 168525e992a4SHeiner Kallweit data[11] = le16_to_cpu(counters->tx_aborted); 168625e992a4SHeiner Kallweit data[12] = le16_to_cpu(counters->tx_underun); 168725e992a4SHeiner Kallweit } 168825e992a4SHeiner Kallweit 168925e992a4SHeiner Kallweit static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) 169025e992a4SHeiner Kallweit { 169125e992a4SHeiner Kallweit switch(stringset) { 169225e992a4SHeiner Kallweit case ETH_SS_STATS: 169325e992a4SHeiner Kallweit memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings)); 169425e992a4SHeiner Kallweit break; 169525e992a4SHeiner Kallweit } 169625e992a4SHeiner Kallweit } 169725e992a4SHeiner Kallweit 169825e992a4SHeiner Kallweit /* 169925e992a4SHeiner Kallweit * Interrupt coalescing 170025e992a4SHeiner Kallweit * 170125e992a4SHeiner Kallweit * > 1 - the availability of the IntrMitigate (0xe2) register through the 170225e992a4SHeiner Kallweit * > 8169, 8168 and 810x line of chipsets 170325e992a4SHeiner Kallweit * 170425e992a4SHeiner Kallweit * 8169, 8168, and 8136(810x) serial chipsets support it. 170525e992a4SHeiner Kallweit * 170625e992a4SHeiner Kallweit * > 2 - the Tx timer unit at gigabit speed 170725e992a4SHeiner Kallweit * 170825e992a4SHeiner Kallweit * The unit of the timer depends on both the speed and the setting of CPlusCmd 170925e992a4SHeiner Kallweit * (0xe0) bit 1 and bit 0. 171025e992a4SHeiner Kallweit * 171125e992a4SHeiner Kallweit * For 8169 171225e992a4SHeiner Kallweit * bit[1:0] \ speed 1000M 100M 10M 171325e992a4SHeiner Kallweit * 0 0 320ns 2.56us 40.96us 171425e992a4SHeiner Kallweit * 0 1 2.56us 20.48us 327.7us 171525e992a4SHeiner Kallweit * 1 0 5.12us 40.96us 655.4us 171625e992a4SHeiner Kallweit * 1 1 10.24us 81.92us 1.31ms 171725e992a4SHeiner Kallweit * 171825e992a4SHeiner Kallweit * For the other 171925e992a4SHeiner Kallweit * bit[1:0] \ speed 1000M 100M 10M 172025e992a4SHeiner Kallweit * 0 0 5us 2.56us 40.96us 172125e992a4SHeiner Kallweit * 0 1 40us 20.48us 327.7us 172225e992a4SHeiner Kallweit * 1 0 80us 40.96us 655.4us 172325e992a4SHeiner Kallweit * 1 1 160us 81.92us 1.31ms 172425e992a4SHeiner Kallweit */ 172525e992a4SHeiner Kallweit 172625e992a4SHeiner Kallweit /* rx/tx scale factors for all CPlusCmd[0:1] cases */ 172725e992a4SHeiner Kallweit struct rtl_coalesce_info { 172825e992a4SHeiner Kallweit u32 speed; 17292815b305SHeiner Kallweit u32 scale_nsecs[4]; 173025e992a4SHeiner Kallweit }; 173125e992a4SHeiner Kallweit 17322815b305SHeiner Kallweit /* produce array with base delay *1, *8, *8*2, *8*2*2 */ 17332815b305SHeiner Kallweit #define COALESCE_DELAY(d) { (d), 8 * (d), 16 * (d), 32 * (d) } 17342815b305SHeiner Kallweit 173525e992a4SHeiner Kallweit static const struct rtl_coalesce_info rtl_coalesce_info_8169[] = { 17362815b305SHeiner Kallweit { SPEED_10, COALESCE_DELAY(40960) }, 17372815b305SHeiner Kallweit { SPEED_100, COALESCE_DELAY(2560) }, 17382815b305SHeiner Kallweit { SPEED_1000, COALESCE_DELAY(320) }, 173925e992a4SHeiner Kallweit { 0 }, 174025e992a4SHeiner Kallweit }; 174125e992a4SHeiner Kallweit 174225e992a4SHeiner Kallweit static const struct rtl_coalesce_info rtl_coalesce_info_8168_8136[] = { 17432815b305SHeiner Kallweit { SPEED_10, COALESCE_DELAY(40960) }, 17442815b305SHeiner Kallweit { SPEED_100, COALESCE_DELAY(2560) }, 17452815b305SHeiner Kallweit { SPEED_1000, COALESCE_DELAY(5000) }, 174625e992a4SHeiner Kallweit { 0 }, 174725e992a4SHeiner Kallweit }; 17482815b305SHeiner Kallweit #undef COALESCE_DELAY 174925e992a4SHeiner Kallweit 175025e992a4SHeiner Kallweit /* get rx/tx scale vector corresponding to current speed */ 1751ef2c0a78SHeiner Kallweit static const struct rtl_coalesce_info * 1752ef2c0a78SHeiner Kallweit rtl_coalesce_info(struct rtl8169_private *tp) 175325e992a4SHeiner Kallweit { 175425e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 175525e992a4SHeiner Kallweit 175620023d3eSHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 175720023d3eSHeiner Kallweit ci = rtl_coalesce_info_8169; 175820023d3eSHeiner Kallweit else 175920023d3eSHeiner Kallweit ci = rtl_coalesce_info_8168_8136; 176025e992a4SHeiner Kallweit 176120023d3eSHeiner Kallweit for (; ci->speed; ci++) { 176220023d3eSHeiner Kallweit if (tp->phydev->speed == ci->speed) 176325e992a4SHeiner Kallweit return ci; 176425e992a4SHeiner Kallweit } 176525e992a4SHeiner Kallweit 176625e992a4SHeiner Kallweit return ERR_PTR(-ELNRNG); 176725e992a4SHeiner Kallweit } 176825e992a4SHeiner Kallweit 176925e992a4SHeiner Kallweit static int rtl_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) 177025e992a4SHeiner Kallweit { 177125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 177225e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 17736cf96dd4SHeiner Kallweit u32 scale, c_us, c_fr; 17746cf96dd4SHeiner Kallweit u16 intrmit; 177525e992a4SHeiner Kallweit 1776f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1777f1bce4adSHeiner Kallweit return -EOPNOTSUPP; 1778f1bce4adSHeiner Kallweit 177925e992a4SHeiner Kallweit memset(ec, 0, sizeof(*ec)); 178025e992a4SHeiner Kallweit 178125e992a4SHeiner Kallweit /* get rx/tx scale corresponding to current speed and CPlusCmd[0:1] */ 1782ef2c0a78SHeiner Kallweit ci = rtl_coalesce_info(tp); 178325e992a4SHeiner Kallweit if (IS_ERR(ci)) 178425e992a4SHeiner Kallweit return PTR_ERR(ci); 178525e992a4SHeiner Kallweit 17862815b305SHeiner Kallweit scale = ci->scale_nsecs[tp->cp_cmd & INTT_MASK]; 178725e992a4SHeiner Kallweit 17886cf96dd4SHeiner Kallweit intrmit = RTL_R16(tp, IntrMitigate); 178925e992a4SHeiner Kallweit 17906cf96dd4SHeiner Kallweit c_us = FIELD_GET(RTL_COALESCE_TX_USECS, intrmit); 17916cf96dd4SHeiner Kallweit ec->tx_coalesce_usecs = DIV_ROUND_UP(c_us * scale, 1000); 179225e992a4SHeiner Kallweit 17936cf96dd4SHeiner Kallweit c_fr = FIELD_GET(RTL_COALESCE_TX_FRAMES, intrmit); 17946cf96dd4SHeiner Kallweit /* ethtool_coalesce states usecs and max_frames must not both be 0 */ 17956cf96dd4SHeiner Kallweit ec->tx_max_coalesced_frames = (c_us || c_fr) ? c_fr * 4 : 1; 17966cf96dd4SHeiner Kallweit 17976cf96dd4SHeiner Kallweit c_us = FIELD_GET(RTL_COALESCE_RX_USECS, intrmit); 17986cf96dd4SHeiner Kallweit ec->rx_coalesce_usecs = DIV_ROUND_UP(c_us * scale, 1000); 17996cf96dd4SHeiner Kallweit 18006cf96dd4SHeiner Kallweit c_fr = FIELD_GET(RTL_COALESCE_RX_FRAMES, intrmit); 18016cf96dd4SHeiner Kallweit ec->rx_max_coalesced_frames = (c_us || c_fr) ? c_fr * 4 : 1; 180225e992a4SHeiner Kallweit 180325e992a4SHeiner Kallweit return 0; 180425e992a4SHeiner Kallweit } 180525e992a4SHeiner Kallweit 1806cb9d97deSHeiner Kallweit /* choose appropriate scale factor and CPlusCmd[0:1] for (speed, usec) */ 1807cb9d97deSHeiner Kallweit static int rtl_coalesce_choose_scale(struct rtl8169_private *tp, u32 usec, 18082815b305SHeiner Kallweit u16 *cp01) 180925e992a4SHeiner Kallweit { 181025e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 181125e992a4SHeiner Kallweit u16 i; 181225e992a4SHeiner Kallweit 1813ef2c0a78SHeiner Kallweit ci = rtl_coalesce_info(tp); 181425e992a4SHeiner Kallweit if (IS_ERR(ci)) 18152815b305SHeiner Kallweit return PTR_ERR(ci); 181625e992a4SHeiner Kallweit 181725e992a4SHeiner Kallweit for (i = 0; i < 4; i++) { 1818cb9d97deSHeiner Kallweit if (usec <= ci->scale_nsecs[i] * RTL_COALESCE_T_MAX / 1000U) { 181925e992a4SHeiner Kallweit *cp01 = i; 18202815b305SHeiner Kallweit return ci->scale_nsecs[i]; 182125e992a4SHeiner Kallweit } 182225e992a4SHeiner Kallweit } 182325e992a4SHeiner Kallweit 1824cb9d97deSHeiner Kallweit return -ERANGE; 182525e992a4SHeiner Kallweit } 182625e992a4SHeiner Kallweit 182725e992a4SHeiner Kallweit static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) 182825e992a4SHeiner Kallweit { 182925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 18302b3e48b6SHeiner Kallweit u32 tx_fr = ec->tx_max_coalesced_frames; 18312b3e48b6SHeiner Kallweit u32 rx_fr = ec->rx_max_coalesced_frames; 18322b3e48b6SHeiner Kallweit u32 coal_usec_max, units; 18332815b305SHeiner Kallweit u16 w = 0, cp01 = 0; 18342b3e48b6SHeiner Kallweit int scale; 183525e992a4SHeiner Kallweit 1836f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1837f1bce4adSHeiner Kallweit return -EOPNOTSUPP; 1838f1bce4adSHeiner Kallweit 18392b3e48b6SHeiner Kallweit if (rx_fr > RTL_COALESCE_FRAME_MAX || tx_fr > RTL_COALESCE_FRAME_MAX) 18402b3e48b6SHeiner Kallweit return -ERANGE; 18412b3e48b6SHeiner Kallweit 1842cb9d97deSHeiner Kallweit coal_usec_max = max(ec->rx_coalesce_usecs, ec->tx_coalesce_usecs); 1843cb9d97deSHeiner Kallweit scale = rtl_coalesce_choose_scale(tp, coal_usec_max, &cp01); 18442815b305SHeiner Kallweit if (scale < 0) 18452815b305SHeiner Kallweit return scale; 184625e992a4SHeiner Kallweit 18472b3e48b6SHeiner Kallweit /* Accept max_frames=1 we returned in rtl_get_coalesce. Accept it 18482b3e48b6SHeiner Kallweit * not only when usecs=0 because of e.g. the following scenario: 184925e992a4SHeiner Kallweit * 185025e992a4SHeiner Kallweit * - both rx_usecs=0 & rx_frames=0 in hardware (no delay on RX) 185125e992a4SHeiner Kallweit * - rtl_get_coalesce returns rx_usecs=0, rx_frames=1 185225e992a4SHeiner Kallweit * - then user does `ethtool -C eth0 rx-usecs 100` 185325e992a4SHeiner Kallweit * 18542b3e48b6SHeiner Kallweit * Since ethtool sends to kernel whole ethtool_coalesce settings, 18552b3e48b6SHeiner Kallweit * if we want to ignore rx_frames then it has to be set to 0. 185625e992a4SHeiner Kallweit */ 18572b3e48b6SHeiner Kallweit if (rx_fr == 1) 18582b3e48b6SHeiner Kallweit rx_fr = 0; 18592b3e48b6SHeiner Kallweit if (tx_fr == 1) 18602b3e48b6SHeiner Kallweit tx_fr = 0; 186125e992a4SHeiner Kallweit 186281496b72SHeiner Kallweit /* HW requires time limit to be set if frame limit is set */ 186381496b72SHeiner Kallweit if ((tx_fr && !ec->tx_coalesce_usecs) || 186481496b72SHeiner Kallweit (rx_fr && !ec->rx_coalesce_usecs)) 186581496b72SHeiner Kallweit return -EINVAL; 186681496b72SHeiner Kallweit 18672b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_TX_FRAMES, DIV_ROUND_UP(tx_fr, 4)); 18682b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_RX_FRAMES, DIV_ROUND_UP(rx_fr, 4)); 186925e992a4SHeiner Kallweit 18702b3e48b6SHeiner Kallweit units = DIV_ROUND_UP(ec->tx_coalesce_usecs * 1000U, scale); 18712b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_TX_USECS, units); 18722b3e48b6SHeiner Kallweit units = DIV_ROUND_UP(ec->rx_coalesce_usecs * 1000U, scale); 18732b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_RX_USECS, units); 187425e992a4SHeiner Kallweit 187525e992a4SHeiner Kallweit rtl_lock_work(tp); 187625e992a4SHeiner Kallweit 18772b3e48b6SHeiner Kallweit RTL_W16(tp, IntrMitigate, w); 187825e992a4SHeiner Kallweit 18795cdfe830SHeiner Kallweit /* Meaning of PktCntrDisable bit changed from RTL8168e-vl */ 18805cdfe830SHeiner Kallweit if (rtl_is_8168evl_up(tp)) { 18815cdfe830SHeiner Kallweit if (!rx_fr && !tx_fr) 18825cdfe830SHeiner Kallweit /* disable packet counter */ 18835cdfe830SHeiner Kallweit tp->cp_cmd |= PktCntrDisable; 18845cdfe830SHeiner Kallweit else 18855cdfe830SHeiner Kallweit tp->cp_cmd &= ~PktCntrDisable; 18865cdfe830SHeiner Kallweit } 18875cdfe830SHeiner Kallweit 188825e992a4SHeiner Kallweit tp->cp_cmd = (tp->cp_cmd & ~INTT_MASK) | cp01; 188925e992a4SHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 1890711463f8SHeiner Kallweit rtl_pci_commit(tp); 189125e992a4SHeiner Kallweit 189225e992a4SHeiner Kallweit rtl_unlock_work(tp); 189325e992a4SHeiner Kallweit 189425e992a4SHeiner Kallweit return 0; 189525e992a4SHeiner Kallweit } 189625e992a4SHeiner Kallweit 189725e992a4SHeiner Kallweit static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data) 189825e992a4SHeiner Kallweit { 189925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 190025e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 190125e992a4SHeiner Kallweit int ret; 190225e992a4SHeiner Kallweit 19032e779ddbSHeiner Kallweit if (!rtl_supports_eee(tp)) 19042e779ddbSHeiner Kallweit return -EOPNOTSUPP; 19052e779ddbSHeiner Kallweit 190625e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 190725e992a4SHeiner Kallweit 190825e992a4SHeiner Kallweit if (!pm_runtime_active(d)) { 190925e992a4SHeiner Kallweit ret = -EOPNOTSUPP; 19102e779ddbSHeiner Kallweit } else { 19112e779ddbSHeiner Kallweit ret = phy_ethtool_get_eee(tp->phydev, data); 191225e992a4SHeiner Kallweit } 191325e992a4SHeiner Kallweit 191425e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 19152e779ddbSHeiner Kallweit 19162e779ddbSHeiner Kallweit return ret; 191725e992a4SHeiner Kallweit } 191825e992a4SHeiner Kallweit 191925e992a4SHeiner Kallweit static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data) 192025e992a4SHeiner Kallweit { 192125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 192225e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 19232e779ddbSHeiner Kallweit int ret; 19242e779ddbSHeiner Kallweit 19252e779ddbSHeiner Kallweit if (!rtl_supports_eee(tp)) 19262e779ddbSHeiner Kallweit return -EOPNOTSUPP; 192725e992a4SHeiner Kallweit 192825e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 192925e992a4SHeiner Kallweit 19302e779ddbSHeiner Kallweit if (!pm_runtime_active(d)) { 193125e992a4SHeiner Kallweit ret = -EOPNOTSUPP; 193225e992a4SHeiner Kallweit goto out; 193325e992a4SHeiner Kallweit } 193425e992a4SHeiner Kallweit 19352e779ddbSHeiner Kallweit ret = phy_ethtool_set_eee(tp->phydev, data); 19367ec3f872SHeiner Kallweit 19377ec3f872SHeiner Kallweit if (!ret) 19387ec3f872SHeiner Kallweit tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN, 19397ec3f872SHeiner Kallweit MDIO_AN_EEE_ADV); 194025e992a4SHeiner Kallweit out: 194125e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 19422e779ddbSHeiner Kallweit return ret; 194325e992a4SHeiner Kallweit } 194425e992a4SHeiner Kallweit 194525e992a4SHeiner Kallweit static const struct ethtool_ops rtl8169_ethtool_ops = { 1946b604eb31SJakub Kicinski .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 1947b604eb31SJakub Kicinski ETHTOOL_COALESCE_MAX_FRAMES, 194825e992a4SHeiner Kallweit .get_drvinfo = rtl8169_get_drvinfo, 194925e992a4SHeiner Kallweit .get_regs_len = rtl8169_get_regs_len, 195025e992a4SHeiner Kallweit .get_link = ethtool_op_get_link, 195125e992a4SHeiner Kallweit .get_coalesce = rtl_get_coalesce, 195225e992a4SHeiner Kallweit .set_coalesce = rtl_set_coalesce, 195325e992a4SHeiner Kallweit .get_regs = rtl8169_get_regs, 195425e992a4SHeiner Kallweit .get_wol = rtl8169_get_wol, 195525e992a4SHeiner Kallweit .set_wol = rtl8169_set_wol, 195625e992a4SHeiner Kallweit .get_strings = rtl8169_get_strings, 195725e992a4SHeiner Kallweit .get_sset_count = rtl8169_get_sset_count, 195825e992a4SHeiner Kallweit .get_ethtool_stats = rtl8169_get_ethtool_stats, 195925e992a4SHeiner Kallweit .get_ts_info = ethtool_op_get_ts_info, 196025e992a4SHeiner Kallweit .nway_reset = phy_ethtool_nway_reset, 196125e992a4SHeiner Kallweit .get_eee = rtl8169_get_eee, 196225e992a4SHeiner Kallweit .set_eee = rtl8169_set_eee, 196325e992a4SHeiner Kallweit .get_link_ksettings = phy_ethtool_get_link_ksettings, 196425e992a4SHeiner Kallweit .set_link_ksettings = phy_ethtool_set_link_ksettings, 196525e992a4SHeiner Kallweit }; 196625e992a4SHeiner Kallweit 196725e992a4SHeiner Kallweit static void rtl_enable_eee(struct rtl8169_private *tp) 196825e992a4SHeiner Kallweit { 19692e779ddbSHeiner Kallweit struct phy_device *phydev = tp->phydev; 19707ec3f872SHeiner Kallweit int adv; 197125e992a4SHeiner Kallweit 19727ec3f872SHeiner Kallweit /* respect EEE advertisement the user may have set */ 19737ec3f872SHeiner Kallweit if (tp->eee_adv >= 0) 19747ec3f872SHeiner Kallweit adv = tp->eee_adv; 19757ec3f872SHeiner Kallweit else 19767ec3f872SHeiner Kallweit adv = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); 19777ec3f872SHeiner Kallweit 19787ec3f872SHeiner Kallweit if (adv >= 0) 19797ec3f872SHeiner Kallweit phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv); 198025e992a4SHeiner Kallweit } 198125e992a4SHeiner Kallweit 1982f1f9ca28SHeiner Kallweit static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) 198325e992a4SHeiner Kallweit { 198425e992a4SHeiner Kallweit /* 198525e992a4SHeiner Kallweit * The driver currently handles the 8168Bf and the 8168Be identically 198625e992a4SHeiner Kallweit * but they can be identified more specifically through the test below 198725e992a4SHeiner Kallweit * if needed: 198825e992a4SHeiner Kallweit * 198925e992a4SHeiner Kallweit * (RTL_R32(tp, TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be 199025e992a4SHeiner Kallweit * 199125e992a4SHeiner Kallweit * Same thing for the 8101Eb and the 8101Ec: 199225e992a4SHeiner Kallweit * 199325e992a4SHeiner Kallweit * (RTL_R32(tp, TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec 199425e992a4SHeiner Kallweit */ 199525e992a4SHeiner Kallweit static const struct rtl_mac_info { 199625e992a4SHeiner Kallweit u16 mask; 199725e992a4SHeiner Kallweit u16 val; 1998f1f9ca28SHeiner Kallweit enum mac_version ver; 199925e992a4SHeiner Kallweit } mac_info[] = { 2000f1bce4adSHeiner Kallweit /* 8125 family. */ 2001f1bce4adSHeiner Kallweit { 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 }, 2002f1bce4adSHeiner Kallweit { 0x7c8, 0x608, RTL_GIGA_MAC_VER_61 }, 2003f1bce4adSHeiner Kallweit 20041287723aSHeiner Kallweit /* RTL8117 */ 20051287723aSHeiner Kallweit { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52 }, 20061287723aSHeiner Kallweit 200725e992a4SHeiner Kallweit /* 8168EP family. */ 200825e992a4SHeiner Kallweit { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51 }, 200925e992a4SHeiner Kallweit { 0x7cf, 0x501, RTL_GIGA_MAC_VER_50 }, 201025e992a4SHeiner Kallweit { 0x7cf, 0x500, RTL_GIGA_MAC_VER_49 }, 201125e992a4SHeiner Kallweit 201225e992a4SHeiner Kallweit /* 8168H family. */ 201325e992a4SHeiner Kallweit { 0x7cf, 0x541, RTL_GIGA_MAC_VER_46 }, 201425e992a4SHeiner Kallweit { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 }, 201525e992a4SHeiner Kallweit 201625e992a4SHeiner Kallweit /* 8168G family. */ 201725e992a4SHeiner Kallweit { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 }, 201825e992a4SHeiner Kallweit { 0x7cf, 0x509, RTL_GIGA_MAC_VER_42 }, 201925e992a4SHeiner Kallweit { 0x7cf, 0x4c1, RTL_GIGA_MAC_VER_41 }, 202025e992a4SHeiner Kallweit { 0x7cf, 0x4c0, RTL_GIGA_MAC_VER_40 }, 202125e992a4SHeiner Kallweit 202225e992a4SHeiner Kallweit /* 8168F family. */ 202325e992a4SHeiner Kallweit { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38 }, 202425e992a4SHeiner Kallweit { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36 }, 202525e992a4SHeiner Kallweit { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35 }, 202625e992a4SHeiner Kallweit 202725e992a4SHeiner Kallweit /* 8168E family. */ 202825e992a4SHeiner Kallweit { 0x7c8, 0x2c8, RTL_GIGA_MAC_VER_34 }, 202925e992a4SHeiner Kallweit { 0x7cf, 0x2c1, RTL_GIGA_MAC_VER_32 }, 203025e992a4SHeiner Kallweit { 0x7c8, 0x2c0, RTL_GIGA_MAC_VER_33 }, 203125e992a4SHeiner Kallweit 203225e992a4SHeiner Kallweit /* 8168D family. */ 203325e992a4SHeiner Kallweit { 0x7cf, 0x281, RTL_GIGA_MAC_VER_25 }, 203425e992a4SHeiner Kallweit { 0x7c8, 0x280, RTL_GIGA_MAC_VER_26 }, 203525e992a4SHeiner Kallweit 203625e992a4SHeiner Kallweit /* 8168DP family. */ 203725e992a4SHeiner Kallweit { 0x7cf, 0x288, RTL_GIGA_MAC_VER_27 }, 203825e992a4SHeiner Kallweit { 0x7cf, 0x28a, RTL_GIGA_MAC_VER_28 }, 203925e992a4SHeiner Kallweit { 0x7cf, 0x28b, RTL_GIGA_MAC_VER_31 }, 204025e992a4SHeiner Kallweit 204125e992a4SHeiner Kallweit /* 8168C family. */ 204225e992a4SHeiner Kallweit { 0x7cf, 0x3c9, RTL_GIGA_MAC_VER_23 }, 204325e992a4SHeiner Kallweit { 0x7cf, 0x3c8, RTL_GIGA_MAC_VER_18 }, 204425e992a4SHeiner Kallweit { 0x7c8, 0x3c8, RTL_GIGA_MAC_VER_24 }, 204525e992a4SHeiner Kallweit { 0x7cf, 0x3c0, RTL_GIGA_MAC_VER_19 }, 204625e992a4SHeiner Kallweit { 0x7cf, 0x3c2, RTL_GIGA_MAC_VER_20 }, 204725e992a4SHeiner Kallweit { 0x7cf, 0x3c3, RTL_GIGA_MAC_VER_21 }, 204825e992a4SHeiner Kallweit { 0x7c8, 0x3c0, RTL_GIGA_MAC_VER_22 }, 204925e992a4SHeiner Kallweit 205025e992a4SHeiner Kallweit /* 8168B family. */ 205125e992a4SHeiner Kallweit { 0x7cf, 0x380, RTL_GIGA_MAC_VER_12 }, 205225e992a4SHeiner Kallweit { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 }, 205325e992a4SHeiner Kallweit { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 }, 205425e992a4SHeiner Kallweit 205525e992a4SHeiner Kallweit /* 8101 family. */ 205625e992a4SHeiner Kallweit { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 }, 205725e992a4SHeiner Kallweit { 0x7c8, 0x440, RTL_GIGA_MAC_VER_37 }, 205825e992a4SHeiner Kallweit { 0x7cf, 0x409, RTL_GIGA_MAC_VER_29 }, 205925e992a4SHeiner Kallweit { 0x7c8, 0x408, RTL_GIGA_MAC_VER_30 }, 206025e992a4SHeiner Kallweit { 0x7cf, 0x349, RTL_GIGA_MAC_VER_08 }, 206125e992a4SHeiner Kallweit { 0x7cf, 0x249, RTL_GIGA_MAC_VER_08 }, 206225e992a4SHeiner Kallweit { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 }, 206325e992a4SHeiner Kallweit { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 }, 206425e992a4SHeiner Kallweit { 0x7cf, 0x340, RTL_GIGA_MAC_VER_13 }, 20651f8492dfSHeiner Kallweit /* RTL8401, reportedly works if treated as RTL8101e */ 20661f8492dfSHeiner Kallweit { 0x7cf, 0x240, RTL_GIGA_MAC_VER_13 }, 206725e992a4SHeiner Kallweit { 0x7cf, 0x343, RTL_GIGA_MAC_VER_10 }, 206825e992a4SHeiner Kallweit { 0x7cf, 0x342, RTL_GIGA_MAC_VER_16 }, 206925e992a4SHeiner Kallweit { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 }, 207025e992a4SHeiner Kallweit { 0x7c8, 0x248, RTL_GIGA_MAC_VER_09 }, 207125e992a4SHeiner Kallweit { 0x7c8, 0x340, RTL_GIGA_MAC_VER_16 }, 207225e992a4SHeiner Kallweit /* FIXME: where did these entries come from ? -- FR */ 207325e992a4SHeiner Kallweit { 0xfc8, 0x388, RTL_GIGA_MAC_VER_15 }, 207425e992a4SHeiner Kallweit { 0xfc8, 0x308, RTL_GIGA_MAC_VER_14 }, 207525e992a4SHeiner Kallweit 207625e992a4SHeiner Kallweit /* 8110 family. */ 207725e992a4SHeiner Kallweit { 0xfc8, 0x980, RTL_GIGA_MAC_VER_06 }, 207825e992a4SHeiner Kallweit { 0xfc8, 0x180, RTL_GIGA_MAC_VER_05 }, 207925e992a4SHeiner Kallweit { 0xfc8, 0x100, RTL_GIGA_MAC_VER_04 }, 208025e992a4SHeiner Kallweit { 0xfc8, 0x040, RTL_GIGA_MAC_VER_03 }, 208125e992a4SHeiner Kallweit { 0xfc8, 0x008, RTL_GIGA_MAC_VER_02 }, 208225e992a4SHeiner Kallweit 208325e992a4SHeiner Kallweit /* Catch-all */ 208425e992a4SHeiner Kallweit { 0x000, 0x000, RTL_GIGA_MAC_NONE } 208525e992a4SHeiner Kallweit }; 208625e992a4SHeiner Kallweit const struct rtl_mac_info *p = mac_info; 2087f1f9ca28SHeiner Kallweit enum mac_version ver; 208825e992a4SHeiner Kallweit 2089f1f9ca28SHeiner Kallweit while ((xid & p->mask) != p->val) 209025e992a4SHeiner Kallweit p++; 2091f1f9ca28SHeiner Kallweit ver = p->ver; 209225e992a4SHeiner Kallweit 2093f1f9ca28SHeiner Kallweit if (ver != RTL_GIGA_MAC_NONE && !gmii) { 2094f1f9ca28SHeiner Kallweit if (ver == RTL_GIGA_MAC_VER_42) 2095f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_43; 2096f1f9ca28SHeiner Kallweit else if (ver == RTL_GIGA_MAC_VER_45) 2097f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_47; 2098f1f9ca28SHeiner Kallweit else if (ver == RTL_GIGA_MAC_VER_46) 2099f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_48; 210025e992a4SHeiner Kallweit } 2101f1f9ca28SHeiner Kallweit 2102f1f9ca28SHeiner Kallweit return ver; 210325e992a4SHeiner Kallweit } 210425e992a4SHeiner Kallweit 210525e992a4SHeiner Kallweit static void rtl_release_firmware(struct rtl8169_private *tp) 210625e992a4SHeiner Kallweit { 210725e992a4SHeiner Kallweit if (tp->rtl_fw) { 210825e992a4SHeiner Kallweit rtl_fw_release_firmware(tp->rtl_fw); 210925e992a4SHeiner Kallweit kfree(tp->rtl_fw); 211025e992a4SHeiner Kallweit tp->rtl_fw = NULL; 211125e992a4SHeiner Kallweit } 211225e992a4SHeiner Kallweit } 211325e992a4SHeiner Kallweit 21142992bdfaSHeiner Kallweit void r8169_apply_firmware(struct rtl8169_private *tp) 211525e992a4SHeiner Kallweit { 211625e992a4SHeiner Kallweit /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ 211725e992a4SHeiner Kallweit if (tp->rtl_fw) 211825e992a4SHeiner Kallweit rtl_fw_write_firmware(tp, tp->rtl_fw); 211925e992a4SHeiner Kallweit } 212025e992a4SHeiner Kallweit 212125e992a4SHeiner Kallweit static void rtl8168_config_eee_mac(struct rtl8169_private *tp) 212225e992a4SHeiner Kallweit { 212325e992a4SHeiner Kallweit /* Adjust EEE LED frequency */ 212425e992a4SHeiner Kallweit if (tp->mac_version != RTL_GIGA_MAC_VER_38) 212525e992a4SHeiner Kallweit RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07); 212625e992a4SHeiner Kallweit 212754113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, 0x0003); 212825e992a4SHeiner Kallweit } 212925e992a4SHeiner Kallweit 2130b3a42e3aSHeiner Kallweit static void rtl8125_config_eee_mac(struct rtl8169_private *tp) 2131b3a42e3aSHeiner Kallweit { 2132b3a42e3aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0)); 2133b3a42e3aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb62, 0, BIT(2) | BIT(1)); 2134b3a42e3aSHeiner Kallweit } 2135b3a42e3aSHeiner Kallweit 213625e992a4SHeiner Kallweit static void rtl_rar_exgmac_set(struct rtl8169_private *tp, u8 *addr) 213725e992a4SHeiner Kallweit { 213825e992a4SHeiner Kallweit const u16 w[] = { 213925e992a4SHeiner Kallweit addr[0] | (addr[1] << 8), 214025e992a4SHeiner Kallweit addr[2] | (addr[3] << 8), 214125e992a4SHeiner Kallweit addr[4] | (addr[5] << 8) 214225e992a4SHeiner Kallweit }; 214325e992a4SHeiner Kallweit 214425e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe0, ERIAR_MASK_1111, w[0] | (w[1] << 16)); 214525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe4, ERIAR_MASK_1111, w[2]); 214625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xf0, ERIAR_MASK_1111, w[0] << 16); 214725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xf4, ERIAR_MASK_1111, w[1] | (w[2] << 16)); 214825e992a4SHeiner Kallweit } 214925e992a4SHeiner Kallweit 21502992bdfaSHeiner Kallweit u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp) 21513127f7c9SHeiner Kallweit { 21523127f7c9SHeiner Kallweit u16 data1, data2, ioffset; 21533127f7c9SHeiner Kallweit 21543127f7c9SHeiner Kallweit r8168_mac_ocp_write(tp, 0xdd02, 0x807d); 21553127f7c9SHeiner Kallweit data1 = r8168_mac_ocp_read(tp, 0xdd02); 21563127f7c9SHeiner Kallweit data2 = r8168_mac_ocp_read(tp, 0xdd00); 21573127f7c9SHeiner Kallweit 21583127f7c9SHeiner Kallweit ioffset = (data2 >> 1) & 0x7ff8; 21593127f7c9SHeiner Kallweit ioffset |= data2 & 0x0007; 21603127f7c9SHeiner Kallweit if (data1 & BIT(7)) 21613127f7c9SHeiner Kallweit ioffset |= BIT(15); 21623127f7c9SHeiner Kallweit 21633127f7c9SHeiner Kallweit return ioffset; 21643127f7c9SHeiner Kallweit } 21653127f7c9SHeiner Kallweit 216625e992a4SHeiner Kallweit static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) 216725e992a4SHeiner Kallweit { 21683f6ca6c7SHeiner Kallweit set_bit(flag, tp->wk.flags); 216925e992a4SHeiner Kallweit schedule_work(&tp->wk.work); 217025e992a4SHeiner Kallweit } 217125e992a4SHeiner Kallweit 2172b5aed0b3SHeiner Kallweit static void rtl8169_init_phy(struct rtl8169_private *tp) 217325e992a4SHeiner Kallweit { 2174becd837eSHeiner Kallweit r8169_hw_phy_config(tp, tp->phydev, tp->mac_version); 217525e992a4SHeiner Kallweit 217625e992a4SHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { 217725e992a4SHeiner Kallweit pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); 217825e992a4SHeiner Kallweit pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); 2179b5aed0b3SHeiner Kallweit /* set undocumented MAC Reg C+CR Offset 0x82h */ 218025e992a4SHeiner Kallweit RTL_W8(tp, 0x82, 0x01); 218125e992a4SHeiner Kallweit } 218225e992a4SHeiner Kallweit 2183fc712387SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05 && 2184fc712387SHeiner Kallweit tp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_GIGABYTE && 2185fc712387SHeiner Kallweit tp->pci_dev->subsystem_device == 0xe000) 2186fc712387SHeiner Kallweit phy_write_paged(tp->phydev, 0x0001, 0x10, 0xf01b); 2187fc712387SHeiner Kallweit 218825e992a4SHeiner Kallweit /* We may have called phy_speed_down before */ 218925e992a4SHeiner Kallweit phy_speed_up(tp->phydev); 219025e992a4SHeiner Kallweit 2191af779778SHeiner Kallweit if (rtl_supports_eee(tp)) 2192af779778SHeiner Kallweit rtl_enable_eee(tp); 2193af779778SHeiner Kallweit 219425e992a4SHeiner Kallweit genphy_soft_reset(tp->phydev); 219525e992a4SHeiner Kallweit } 219625e992a4SHeiner Kallweit 219725e992a4SHeiner Kallweit static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) 219825e992a4SHeiner Kallweit { 219925e992a4SHeiner Kallweit rtl_lock_work(tp); 220025e992a4SHeiner Kallweit 220125e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 220225e992a4SHeiner Kallweit 220325e992a4SHeiner Kallweit RTL_W32(tp, MAC4, addr[4] | addr[5] << 8); 2204711463f8SHeiner Kallweit rtl_pci_commit(tp); 220525e992a4SHeiner Kallweit 220625e992a4SHeiner Kallweit RTL_W32(tp, MAC0, addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); 2207711463f8SHeiner Kallweit rtl_pci_commit(tp); 220825e992a4SHeiner Kallweit 220925e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34) 221025e992a4SHeiner Kallweit rtl_rar_exgmac_set(tp, addr); 221125e992a4SHeiner Kallweit 221225e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 221325e992a4SHeiner Kallweit 221425e992a4SHeiner Kallweit rtl_unlock_work(tp); 221525e992a4SHeiner Kallweit } 221625e992a4SHeiner Kallweit 221725e992a4SHeiner Kallweit static int rtl_set_mac_address(struct net_device *dev, void *p) 221825e992a4SHeiner Kallweit { 221925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 222025e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 222125e992a4SHeiner Kallweit int ret; 222225e992a4SHeiner Kallweit 222325e992a4SHeiner Kallweit ret = eth_mac_addr(dev, p); 222425e992a4SHeiner Kallweit if (ret) 222525e992a4SHeiner Kallweit return ret; 222625e992a4SHeiner Kallweit 222725e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 222825e992a4SHeiner Kallweit 222925e992a4SHeiner Kallweit if (pm_runtime_active(d)) 223025e992a4SHeiner Kallweit rtl_rar_set(tp, dev->dev_addr); 223125e992a4SHeiner Kallweit 223225e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 223325e992a4SHeiner Kallweit 223425e992a4SHeiner Kallweit return 0; 223525e992a4SHeiner Kallweit } 223625e992a4SHeiner Kallweit 223725e992a4SHeiner Kallweit static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) 223825e992a4SHeiner Kallweit { 223925e992a4SHeiner Kallweit switch (tp->mac_version) { 224025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25: 224125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_26: 224225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_29: 224325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_30: 224425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_32: 224525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_33: 224625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_34: 224700222d13SHeiner Kallweit case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_61: 224825e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | 224925e992a4SHeiner Kallweit AcceptBroadcast | AcceptMulticast | AcceptMyPhys); 225025e992a4SHeiner Kallweit break; 225125e992a4SHeiner Kallweit default: 225225e992a4SHeiner Kallweit break; 225325e992a4SHeiner Kallweit } 225425e992a4SHeiner Kallweit } 225525e992a4SHeiner Kallweit 225625e992a4SHeiner Kallweit static void rtl_pll_power_down(struct rtl8169_private *tp) 225725e992a4SHeiner Kallweit { 225825e992a4SHeiner Kallweit if (r8168_check_dash(tp)) 225925e992a4SHeiner Kallweit return; 226025e992a4SHeiner Kallweit 226125e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_32 || 226225e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_33) 226325e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x19, 0xff64); 226425e992a4SHeiner Kallweit 226525e992a4SHeiner Kallweit if (device_may_wakeup(tp_to_dev(tp))) { 226625e992a4SHeiner Kallweit phy_speed_down(tp->phydev, false); 226725e992a4SHeiner Kallweit rtl_wol_suspend_quirk(tp); 226825e992a4SHeiner Kallweit return; 226925e992a4SHeiner Kallweit } 227025e992a4SHeiner Kallweit 227125e992a4SHeiner Kallweit switch (tp->mac_version) { 227225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: 227325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_37: 227425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_39: 227525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_43: 227625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_44: 227725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_45: 227825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_46: 227925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_47: 228025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_48: 228125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_50: 228225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_51: 22831287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_52: 2284f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60: 2285f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_61: 228625e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); 228725e992a4SHeiner Kallweit break; 228825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40: 228925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_41: 229025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_49: 229154113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1a8, 0xfc000000); 229225e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); 229325e992a4SHeiner Kallweit break; 229425e992a4SHeiner Kallweit default: 229525e992a4SHeiner Kallweit break; 229625e992a4SHeiner Kallweit } 229725e992a4SHeiner Kallweit } 229825e992a4SHeiner Kallweit 229925e992a4SHeiner Kallweit static void rtl_pll_power_up(struct rtl8169_private *tp) 230025e992a4SHeiner Kallweit { 230125e992a4SHeiner Kallweit switch (tp->mac_version) { 230225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: 230325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_37: 230425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_39: 230525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_43: 230625e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0x80); 230725e992a4SHeiner Kallweit break; 230825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_44: 230925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_45: 231025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_46: 231125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_47: 231225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_48: 231325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_50: 231425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_51: 23151287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_52: 2316f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60: 2317f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_61: 231825e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); 231925e992a4SHeiner Kallweit break; 232025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40: 232125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_41: 232225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_49: 232325e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); 232454113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x1a8, 0xfc000000); 232525e992a4SHeiner Kallweit break; 232625e992a4SHeiner Kallweit default: 232725e992a4SHeiner Kallweit break; 232825e992a4SHeiner Kallweit } 232925e992a4SHeiner Kallweit 233025e992a4SHeiner Kallweit phy_resume(tp->phydev); 233125e992a4SHeiner Kallweit } 233225e992a4SHeiner Kallweit 233325e992a4SHeiner Kallweit static void rtl_init_rxcfg(struct rtl8169_private *tp) 233425e992a4SHeiner Kallweit { 233525e992a4SHeiner Kallweit switch (tp->mac_version) { 233625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 233725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17: 233825e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX_FIFO_THRESH | RX_DMA_BURST); 233925e992a4SHeiner Kallweit break; 234025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: 234125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_36: 234225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_38: 234325e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); 234425e992a4SHeiner Kallweit break; 23451287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: 234625e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); 234725e992a4SHeiner Kallweit break; 2348f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: 234910478283SHeiner Kallweit RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST); 2350f1bce4adSHeiner Kallweit break; 235125e992a4SHeiner Kallweit default: 235225e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST); 235325e992a4SHeiner Kallweit break; 235425e992a4SHeiner Kallweit } 235525e992a4SHeiner Kallweit } 235625e992a4SHeiner Kallweit 235725e992a4SHeiner Kallweit static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) 235825e992a4SHeiner Kallweit { 235925e992a4SHeiner Kallweit tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0; 236025e992a4SHeiner Kallweit } 236125e992a4SHeiner Kallweit 236225e992a4SHeiner Kallweit static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) 236325e992a4SHeiner Kallweit { 236425e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 236525e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); 236625e992a4SHeiner Kallweit } 236725e992a4SHeiner Kallweit 236825e992a4SHeiner Kallweit static void r8168c_hw_jumbo_disable(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 r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) 237525e992a4SHeiner Kallweit { 237625e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 237725e992a4SHeiner Kallweit } 237825e992a4SHeiner Kallweit 237925e992a4SHeiner Kallweit static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) 238025e992a4SHeiner Kallweit { 238125e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); 238225e992a4SHeiner Kallweit } 238325e992a4SHeiner Kallweit 238425e992a4SHeiner Kallweit static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) 238525e992a4SHeiner Kallweit { 238625e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, 0x3f); 238725e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 238825e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01); 238925e992a4SHeiner Kallweit } 239025e992a4SHeiner Kallweit 239125e992a4SHeiner Kallweit static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) 239225e992a4SHeiner Kallweit { 239325e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, 0x0c); 239425e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); 239525e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01); 239625e992a4SHeiner Kallweit } 239725e992a4SHeiner Kallweit 239825e992a4SHeiner Kallweit static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) 239925e992a4SHeiner Kallweit { 240025e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0)); 240125e992a4SHeiner Kallweit } 240225e992a4SHeiner Kallweit 240325e992a4SHeiner Kallweit static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) 240425e992a4SHeiner Kallweit { 240525e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0)); 240625e992a4SHeiner Kallweit } 240725e992a4SHeiner Kallweit 24089db0ac57SHeiner Kallweit static void rtl_jumbo_config(struct rtl8169_private *tp) 240925e992a4SHeiner Kallweit { 24109db0ac57SHeiner Kallweit bool jumbo = tp->dev->mtu > ETH_DATA_LEN; 24119db0ac57SHeiner Kallweit 241225e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 241325e992a4SHeiner Kallweit switch (tp->mac_version) { 241425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 241525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 24169db0ac57SHeiner Kallweit if (jumbo) { 241721b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 241825e992a4SHeiner Kallweit r8168b_1_hw_jumbo_enable(tp); 24199db0ac57SHeiner Kallweit } else { 24209db0ac57SHeiner Kallweit r8168b_1_hw_jumbo_disable(tp); 24219db0ac57SHeiner Kallweit } 242225e992a4SHeiner Kallweit break; 242325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26: 24249db0ac57SHeiner Kallweit if (jumbo) { 242521b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 242625e992a4SHeiner Kallweit r8168c_hw_jumbo_enable(tp); 24279db0ac57SHeiner Kallweit } else { 242825e992a4SHeiner Kallweit r8168c_hw_jumbo_disable(tp); 24299db0ac57SHeiner Kallweit } 243025e992a4SHeiner Kallweit break; 243125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28: 24329db0ac57SHeiner Kallweit if (jumbo) 24339db0ac57SHeiner Kallweit r8168dp_hw_jumbo_enable(tp); 24349db0ac57SHeiner Kallweit else 243525e992a4SHeiner Kallweit r8168dp_hw_jumbo_disable(tp); 243625e992a4SHeiner Kallweit break; 24370fc75219SHeiner Kallweit case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33: 24389db0ac57SHeiner Kallweit if (jumbo) { 24399db0ac57SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 24409db0ac57SHeiner Kallweit r8168e_hw_jumbo_enable(tp); 24419db0ac57SHeiner Kallweit } else { 244225e992a4SHeiner Kallweit r8168e_hw_jumbo_disable(tp); 24439db0ac57SHeiner Kallweit } 244425e992a4SHeiner Kallweit break; 244525e992a4SHeiner Kallweit default: 244625e992a4SHeiner Kallweit break; 244725e992a4SHeiner Kallweit } 244825e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 244921b5f672SHeiner Kallweit 24509db0ac57SHeiner Kallweit if (!jumbo && pci_is_pcie(tp->pci_dev) && tp->supports_gmii) 245121b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 4096); 245225e992a4SHeiner Kallweit } 245325e992a4SHeiner Kallweit 245425e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_chipcmd_cond) 245525e992a4SHeiner Kallweit { 245625e992a4SHeiner Kallweit return RTL_R8(tp, ChipCmd) & CmdReset; 245725e992a4SHeiner Kallweit } 245825e992a4SHeiner Kallweit 245925e992a4SHeiner Kallweit static void rtl_hw_reset(struct rtl8169_private *tp) 246025e992a4SHeiner Kallweit { 246125e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, CmdReset); 246225e992a4SHeiner Kallweit 2463d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100); 246425e992a4SHeiner Kallweit } 246525e992a4SHeiner Kallweit 246625e992a4SHeiner Kallweit static void rtl_request_firmware(struct rtl8169_private *tp) 246725e992a4SHeiner Kallweit { 246825e992a4SHeiner Kallweit struct rtl_fw *rtl_fw; 246925e992a4SHeiner Kallweit 247025e992a4SHeiner Kallweit /* firmware loaded already or no firmware available */ 247125e992a4SHeiner Kallweit if (tp->rtl_fw || !tp->fw_name) 247225e992a4SHeiner Kallweit return; 247325e992a4SHeiner Kallweit 247425e992a4SHeiner Kallweit rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL); 24753bf6ff3cSHeiner Kallweit if (!rtl_fw) 247625e992a4SHeiner Kallweit return; 247725e992a4SHeiner Kallweit 247825e992a4SHeiner Kallweit rtl_fw->phy_write = rtl_writephy; 247925e992a4SHeiner Kallweit rtl_fw->phy_read = rtl_readphy; 248025e992a4SHeiner Kallweit rtl_fw->mac_mcu_write = mac_mcu_write; 248125e992a4SHeiner Kallweit rtl_fw->mac_mcu_read = mac_mcu_read; 248225e992a4SHeiner Kallweit rtl_fw->fw_name = tp->fw_name; 248325e992a4SHeiner Kallweit rtl_fw->dev = tp_to_dev(tp); 248425e992a4SHeiner Kallweit 248525e992a4SHeiner Kallweit if (rtl_fw_request_firmware(rtl_fw)) 248625e992a4SHeiner Kallweit kfree(rtl_fw); 248725e992a4SHeiner Kallweit else 248825e992a4SHeiner Kallweit tp->rtl_fw = rtl_fw; 248925e992a4SHeiner Kallweit } 249025e992a4SHeiner Kallweit 249125e992a4SHeiner Kallweit static void rtl_rx_close(struct rtl8169_private *tp) 249225e992a4SHeiner Kallweit { 249325e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~RX_CONFIG_ACCEPT_MASK); 249425e992a4SHeiner Kallweit } 249525e992a4SHeiner Kallweit 249625e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_npq_cond) 249725e992a4SHeiner Kallweit { 249825e992a4SHeiner Kallweit return RTL_R8(tp, TxPoll) & NPQ; 249925e992a4SHeiner Kallweit } 250025e992a4SHeiner Kallweit 250125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_txcfg_empty_cond) 250225e992a4SHeiner Kallweit { 250325e992a4SHeiner Kallweit return RTL_R32(tp, TxConfig) & TXCFG_EMPTY; 250425e992a4SHeiner Kallweit } 250525e992a4SHeiner Kallweit 25066f9395c6SHeiner Kallweit DECLARE_RTL_COND(rtl_rxtx_empty_cond) 25076f9395c6SHeiner Kallweit { 25086f9395c6SHeiner Kallweit return (RTL_R8(tp, MCU) & RXTX_EMPTY) == RXTX_EMPTY; 25096f9395c6SHeiner Kallweit } 25106f9395c6SHeiner Kallweit 25116f9395c6SHeiner Kallweit static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp) 25126f9395c6SHeiner Kallweit { 25136f9395c6SHeiner Kallweit switch (tp->mac_version) { 25146f9395c6SHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: 25156f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42); 25166f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); 25176f9395c6SHeiner Kallweit break; 25186f9395c6SHeiner Kallweit case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: 25196f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); 25206f9395c6SHeiner Kallweit break; 25216f9395c6SHeiner Kallweit default: 25226f9395c6SHeiner Kallweit break; 25236f9395c6SHeiner Kallweit } 25246f9395c6SHeiner Kallweit } 25256f9395c6SHeiner Kallweit 25269617886fSHeiner Kallweit static void rtl_enable_rxdvgate(struct rtl8169_private *tp) 25279617886fSHeiner Kallweit { 25289617886fSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN); 25299617886fSHeiner Kallweit fsleep(2000); 25306f9395c6SHeiner Kallweit rtl_wait_txrx_fifo_empty(tp); 25319617886fSHeiner Kallweit } 25329617886fSHeiner Kallweit 253325e992a4SHeiner Kallweit static void rtl_set_tx_config_registers(struct rtl8169_private *tp) 253425e992a4SHeiner Kallweit { 253525e992a4SHeiner Kallweit u32 val = TX_DMA_BURST << TxDMAShift | 253625e992a4SHeiner Kallweit InterFrameGap << TxInterFrameGapShift; 253725e992a4SHeiner Kallweit 25389e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp)) 253925e992a4SHeiner Kallweit val |= TXCFG_AUTO_FIFO; 254025e992a4SHeiner Kallweit 254125e992a4SHeiner Kallweit RTL_W32(tp, TxConfig, val); 254225e992a4SHeiner Kallweit } 254325e992a4SHeiner Kallweit 254425e992a4SHeiner Kallweit static void rtl_set_rx_max_size(struct rtl8169_private *tp) 254525e992a4SHeiner Kallweit { 254625e992a4SHeiner Kallweit /* Low hurts. Let's disable the filtering. */ 254725e992a4SHeiner Kallweit RTL_W16(tp, RxMaxSize, R8169_RX_BUF_SIZE + 1); 254825e992a4SHeiner Kallweit } 254925e992a4SHeiner Kallweit 255025e992a4SHeiner Kallweit static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp) 255125e992a4SHeiner Kallweit { 255225e992a4SHeiner Kallweit /* 255325e992a4SHeiner Kallweit * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh 255425e992a4SHeiner Kallweit * register to be written before TxDescAddrLow to work. 255525e992a4SHeiner Kallweit * Switching from MMIO to I/O access fixes the issue as well. 255625e992a4SHeiner Kallweit */ 255725e992a4SHeiner Kallweit RTL_W32(tp, TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32); 255825e992a4SHeiner Kallweit RTL_W32(tp, TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32)); 255925e992a4SHeiner Kallweit RTL_W32(tp, RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32); 256025e992a4SHeiner Kallweit RTL_W32(tp, RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32)); 256125e992a4SHeiner Kallweit } 256225e992a4SHeiner Kallweit 2563ef891284SHeiner Kallweit static void rtl8169_set_magic_reg(struct rtl8169_private *tp) 256425e992a4SHeiner Kallweit { 256525e992a4SHeiner Kallweit u32 val; 256625e992a4SHeiner Kallweit 256725e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05) 256825e992a4SHeiner Kallweit val = 0x000fff00; 256925e992a4SHeiner Kallweit else if (tp->mac_version == RTL_GIGA_MAC_VER_06) 257025e992a4SHeiner Kallweit val = 0x00ffff00; 257125e992a4SHeiner Kallweit else 257225e992a4SHeiner Kallweit return; 257325e992a4SHeiner Kallweit 257425e992a4SHeiner Kallweit if (RTL_R8(tp, Config2) & PCI_Clock_66MHz) 257525e992a4SHeiner Kallweit val |= 0xff; 257625e992a4SHeiner Kallweit 257725e992a4SHeiner Kallweit RTL_W32(tp, 0x7c, val); 257825e992a4SHeiner Kallweit } 257925e992a4SHeiner Kallweit 258025e992a4SHeiner Kallweit static void rtl_set_rx_mode(struct net_device *dev) 258125e992a4SHeiner Kallweit { 258281cd17a4SHeiner Kallweit u32 rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast; 258381cd17a4SHeiner Kallweit /* Multicast hash filter */ 258481cd17a4SHeiner Kallweit u32 mc_filter[2] = { 0xffffffff, 0xffffffff }; 258525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 258681cd17a4SHeiner Kallweit u32 tmp; 258725e992a4SHeiner Kallweit 258825e992a4SHeiner Kallweit if (dev->flags & IFF_PROMISC) { 258981cd17a4SHeiner Kallweit rx_mode |= AcceptAllPhys; 259081cd17a4SHeiner Kallweit } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || 259181cd17a4SHeiner Kallweit dev->flags & IFF_ALLMULTI || 259281cd17a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_35) { 259381cd17a4SHeiner Kallweit /* accept all multicasts */ 259481cd17a4SHeiner Kallweit } else if (netdev_mc_empty(dev)) { 259581cd17a4SHeiner Kallweit rx_mode &= ~AcceptMulticast; 259625e992a4SHeiner Kallweit } else { 259725e992a4SHeiner Kallweit struct netdev_hw_addr *ha; 259825e992a4SHeiner Kallweit 259925e992a4SHeiner Kallweit mc_filter[1] = mc_filter[0] = 0; 260025e992a4SHeiner Kallweit netdev_for_each_mc_addr(ha, dev) { 2601bc54ac36SHeiner Kallweit u32 bit_nr = eth_hw_addr_crc(ha) >> 26; 260281cd17a4SHeiner Kallweit mc_filter[bit_nr >> 5] |= BIT(bit_nr & 31); 260381cd17a4SHeiner Kallweit } 260481cd17a4SHeiner Kallweit 260581cd17a4SHeiner Kallweit if (tp->mac_version > RTL_GIGA_MAC_VER_06) { 260681cd17a4SHeiner Kallweit tmp = mc_filter[0]; 260781cd17a4SHeiner Kallweit mc_filter[0] = swab32(mc_filter[1]); 260881cd17a4SHeiner Kallweit mc_filter[1] = swab32(tmp); 260925e992a4SHeiner Kallweit } 261025e992a4SHeiner Kallweit } 261125e992a4SHeiner Kallweit 261225e992a4SHeiner Kallweit RTL_W32(tp, MAR0 + 4, mc_filter[1]); 261325e992a4SHeiner Kallweit RTL_W32(tp, MAR0 + 0, mc_filter[0]); 261425e992a4SHeiner Kallweit 261581cd17a4SHeiner Kallweit tmp = RTL_R32(tp, RxConfig); 261610478283SHeiner Kallweit RTL_W32(tp, RxConfig, (tmp & ~RX_CONFIG_ACCEPT_OK_MASK) | rx_mode); 261725e992a4SHeiner Kallweit } 261825e992a4SHeiner Kallweit 261925e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_csiar_cond) 262025e992a4SHeiner Kallweit { 262125e992a4SHeiner Kallweit return RTL_R32(tp, CSIAR) & CSIAR_FLAG; 262225e992a4SHeiner Kallweit } 262325e992a4SHeiner Kallweit 262425e992a4SHeiner Kallweit static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value) 262525e992a4SHeiner Kallweit { 262625e992a4SHeiner Kallweit u32 func = PCI_FUNC(tp->pci_dev->devfn); 262725e992a4SHeiner Kallweit 262825e992a4SHeiner Kallweit RTL_W32(tp, CSIDR, value); 262925e992a4SHeiner Kallweit RTL_W32(tp, CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | 263025e992a4SHeiner Kallweit CSIAR_BYTE_ENABLE | func << 16); 263125e992a4SHeiner Kallweit 2632d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_csiar_cond, 10, 100); 263325e992a4SHeiner Kallweit } 263425e992a4SHeiner Kallweit 263525e992a4SHeiner Kallweit static u32 rtl_csi_read(struct rtl8169_private *tp, int addr) 263625e992a4SHeiner Kallweit { 263725e992a4SHeiner Kallweit u32 func = PCI_FUNC(tp->pci_dev->devfn); 263825e992a4SHeiner Kallweit 263925e992a4SHeiner Kallweit RTL_W32(tp, CSIAR, (addr & CSIAR_ADDR_MASK) | func << 16 | 264025e992a4SHeiner Kallweit CSIAR_BYTE_ENABLE); 264125e992a4SHeiner Kallweit 2642d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ? 264325e992a4SHeiner Kallweit RTL_R32(tp, CSIDR) : ~0; 264425e992a4SHeiner Kallweit } 264525e992a4SHeiner Kallweit 264625e992a4SHeiner Kallweit static void rtl_csi_access_enable(struct rtl8169_private *tp, u8 val) 264725e992a4SHeiner Kallweit { 264825e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 264925e992a4SHeiner Kallweit u32 csi; 265025e992a4SHeiner Kallweit 265125e992a4SHeiner Kallweit /* According to Realtek the value at config space address 0x070f 265225e992a4SHeiner Kallweit * controls the L0s/L1 entrance latency. We try standard ECAM access 265325e992a4SHeiner Kallweit * first and if it fails fall back to CSI. 265425e992a4SHeiner Kallweit */ 265525e992a4SHeiner Kallweit if (pdev->cfg_size > 0x070f && 265625e992a4SHeiner Kallweit pci_write_config_byte(pdev, 0x070f, val) == PCIBIOS_SUCCESSFUL) 265725e992a4SHeiner Kallweit return; 265825e992a4SHeiner Kallweit 265925e992a4SHeiner Kallweit netdev_notice_once(tp->dev, 266025e992a4SHeiner Kallweit "No native access to PCI extended config space, falling back to CSI\n"); 266125e992a4SHeiner Kallweit csi = rtl_csi_read(tp, 0x070c) & 0x00ffffff; 266225e992a4SHeiner Kallweit rtl_csi_write(tp, 0x070c, csi | val << 24); 266325e992a4SHeiner Kallweit } 266425e992a4SHeiner Kallweit 266525e992a4SHeiner Kallweit static void rtl_set_def_aspm_entry_latency(struct rtl8169_private *tp) 266625e992a4SHeiner Kallweit { 266725e992a4SHeiner Kallweit rtl_csi_access_enable(tp, 0x27); 266825e992a4SHeiner Kallweit } 266925e992a4SHeiner Kallweit 267025e992a4SHeiner Kallweit struct ephy_info { 267125e992a4SHeiner Kallweit unsigned int offset; 267225e992a4SHeiner Kallweit u16 mask; 267325e992a4SHeiner Kallweit u16 bits; 267425e992a4SHeiner Kallweit }; 267525e992a4SHeiner Kallweit 267625e992a4SHeiner Kallweit static void __rtl_ephy_init(struct rtl8169_private *tp, 267725e992a4SHeiner Kallweit const struct ephy_info *e, int len) 267825e992a4SHeiner Kallweit { 267925e992a4SHeiner Kallweit u16 w; 268025e992a4SHeiner Kallweit 268125e992a4SHeiner Kallweit while (len-- > 0) { 268225e992a4SHeiner Kallweit w = (rtl_ephy_read(tp, e->offset) & ~e->mask) | e->bits; 268325e992a4SHeiner Kallweit rtl_ephy_write(tp, e->offset, w); 268425e992a4SHeiner Kallweit e++; 268525e992a4SHeiner Kallweit } 268625e992a4SHeiner Kallweit } 268725e992a4SHeiner Kallweit 268825e992a4SHeiner Kallweit #define rtl_ephy_init(tp, a) __rtl_ephy_init(tp, a, ARRAY_SIZE(a)) 268925e992a4SHeiner Kallweit 269025e992a4SHeiner Kallweit static void rtl_disable_clock_request(struct rtl8169_private *tp) 269125e992a4SHeiner Kallweit { 269225e992a4SHeiner Kallweit pcie_capability_clear_word(tp->pci_dev, PCI_EXP_LNKCTL, 269325e992a4SHeiner Kallweit PCI_EXP_LNKCTL_CLKREQ_EN); 269425e992a4SHeiner Kallweit } 269525e992a4SHeiner Kallweit 269625e992a4SHeiner Kallweit static void rtl_enable_clock_request(struct rtl8169_private *tp) 269725e992a4SHeiner Kallweit { 269825e992a4SHeiner Kallweit pcie_capability_set_word(tp->pci_dev, PCI_EXP_LNKCTL, 269925e992a4SHeiner Kallweit PCI_EXP_LNKCTL_CLKREQ_EN); 270025e992a4SHeiner Kallweit } 270125e992a4SHeiner Kallweit 270225e992a4SHeiner Kallweit static void rtl_pcie_state_l2l3_disable(struct rtl8169_private *tp) 270325e992a4SHeiner Kallweit { 270425e992a4SHeiner Kallweit /* work around an issue when PCI reset occurs during L2/L3 state */ 270525e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Rdy_to_L23); 270625e992a4SHeiner Kallweit } 270725e992a4SHeiner Kallweit 270825e992a4SHeiner Kallweit static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) 270925e992a4SHeiner Kallweit { 271062b1b3b3SHeiner Kallweit /* Don't enable ASPM in the chip if OS can't control ASPM */ 271162b1b3b3SHeiner Kallweit if (enable && tp->aspm_manageable) { 271225e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) | ASPM_en); 271325e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) | ClkReqEn); 271425e992a4SHeiner Kallweit } else { 271525e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn); 271625e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en); 271725e992a4SHeiner Kallweit } 271825e992a4SHeiner Kallweit 271925e992a4SHeiner Kallweit udelay(10); 272025e992a4SHeiner Kallweit } 272125e992a4SHeiner Kallweit 272225e992a4SHeiner Kallweit static void rtl_set_fifo_size(struct rtl8169_private *tp, u16 rx_stat, 272325e992a4SHeiner Kallweit u16 tx_stat, u16 rx_dyn, u16 tx_dyn) 272425e992a4SHeiner Kallweit { 272525e992a4SHeiner Kallweit /* Usage of dynamic vs. static FIFO is controlled by bit 272625e992a4SHeiner Kallweit * TXCFG_AUTO_FIFO. Exact meaning of FIFO values isn't known. 272725e992a4SHeiner Kallweit */ 272825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, (rx_stat << 16) | rx_dyn); 272925e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, (tx_stat << 16) | tx_dyn); 273025e992a4SHeiner Kallweit } 273125e992a4SHeiner Kallweit 273225e992a4SHeiner Kallweit static void rtl8168g_set_pause_thresholds(struct rtl8169_private *tp, 273325e992a4SHeiner Kallweit u8 low, u8 high) 273425e992a4SHeiner Kallweit { 273525e992a4SHeiner Kallweit /* FIFO thresholds for pause flow control */ 273625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, low); 273725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, high); 273825e992a4SHeiner Kallweit } 273925e992a4SHeiner Kallweit 274094b5ff74SHeiner Kallweit static void rtl_hw_start_8168b(struct rtl8169_private *tp) 274125e992a4SHeiner Kallweit { 274225e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 274325e992a4SHeiner Kallweit } 274425e992a4SHeiner Kallweit 274525e992a4SHeiner Kallweit static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) 274625e992a4SHeiner Kallweit { 274725e992a4SHeiner Kallweit RTL_W8(tp, Config1, RTL_R8(tp, Config1) | Speed_down); 274825e992a4SHeiner Kallweit 274925e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 275025e992a4SHeiner Kallweit 275125e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 275225e992a4SHeiner Kallweit } 275325e992a4SHeiner Kallweit 275425e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) 275525e992a4SHeiner Kallweit { 275625e992a4SHeiner Kallweit static const struct ephy_info e_info_8168cp[] = { 275725e992a4SHeiner Kallweit { 0x01, 0, 0x0001 }, 275825e992a4SHeiner Kallweit { 0x02, 0x0800, 0x1000 }, 275925e992a4SHeiner Kallweit { 0x03, 0, 0x0042 }, 276025e992a4SHeiner Kallweit { 0x06, 0x0080, 0x0000 }, 276125e992a4SHeiner Kallweit { 0x07, 0, 0x2000 } 276225e992a4SHeiner Kallweit }; 276325e992a4SHeiner Kallweit 276425e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 276525e992a4SHeiner Kallweit 276625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168cp); 276725e992a4SHeiner Kallweit 276825e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 276925e992a4SHeiner Kallweit } 277025e992a4SHeiner Kallweit 277125e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) 277225e992a4SHeiner Kallweit { 277325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 277425e992a4SHeiner Kallweit 277525e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 277625e992a4SHeiner Kallweit } 277725e992a4SHeiner Kallweit 277825e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) 277925e992a4SHeiner Kallweit { 278025e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 278125e992a4SHeiner Kallweit 278225e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 278325e992a4SHeiner Kallweit 278425e992a4SHeiner Kallweit /* Magic. */ 278525e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, 0x20); 278625e992a4SHeiner Kallweit } 278725e992a4SHeiner Kallweit 278825e992a4SHeiner Kallweit static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) 278925e992a4SHeiner Kallweit { 279025e992a4SHeiner Kallweit static const struct ephy_info e_info_8168c_1[] = { 279125e992a4SHeiner Kallweit { 0x02, 0x0800, 0x1000 }, 279225e992a4SHeiner Kallweit { 0x03, 0, 0x0002 }, 279325e992a4SHeiner Kallweit { 0x06, 0x0080, 0x0000 } 279425e992a4SHeiner Kallweit }; 279525e992a4SHeiner Kallweit 279625e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 279725e992a4SHeiner Kallweit 279825e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); 279925e992a4SHeiner Kallweit 280025e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168c_1); 280125e992a4SHeiner Kallweit 280225e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 280325e992a4SHeiner Kallweit } 280425e992a4SHeiner Kallweit 280525e992a4SHeiner Kallweit static void rtl_hw_start_8168c_2(struct rtl8169_private *tp) 280625e992a4SHeiner Kallweit { 280725e992a4SHeiner Kallweit static const struct ephy_info e_info_8168c_2[] = { 280825e992a4SHeiner Kallweit { 0x01, 0, 0x0001 }, 2809a7a92cf8SHeiner Kallweit { 0x03, 0x0400, 0x0020 } 281025e992a4SHeiner Kallweit }; 281125e992a4SHeiner Kallweit 281225e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 281325e992a4SHeiner Kallweit 281425e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168c_2); 281525e992a4SHeiner Kallweit 281625e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 281725e992a4SHeiner Kallweit } 281825e992a4SHeiner Kallweit 281925e992a4SHeiner Kallweit static void rtl_hw_start_8168c_3(struct rtl8169_private *tp) 282025e992a4SHeiner Kallweit { 282125e992a4SHeiner Kallweit rtl_hw_start_8168c_2(tp); 282225e992a4SHeiner Kallweit } 282325e992a4SHeiner Kallweit 282425e992a4SHeiner Kallweit static void rtl_hw_start_8168c_4(struct rtl8169_private *tp) 282525e992a4SHeiner Kallweit { 282625e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 282725e992a4SHeiner Kallweit 282825e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 282925e992a4SHeiner Kallweit } 283025e992a4SHeiner Kallweit 283125e992a4SHeiner Kallweit static void rtl_hw_start_8168d(struct rtl8169_private *tp) 283225e992a4SHeiner Kallweit { 283325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 283425e992a4SHeiner Kallweit 283525e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 283625e992a4SHeiner Kallweit } 283725e992a4SHeiner Kallweit 283825e992a4SHeiner Kallweit static void rtl_hw_start_8168d_4(struct rtl8169_private *tp) 283925e992a4SHeiner Kallweit { 284025e992a4SHeiner Kallweit static const struct ephy_info e_info_8168d_4[] = { 284125e992a4SHeiner Kallweit { 0x0b, 0x0000, 0x0048 }, 284225e992a4SHeiner Kallweit { 0x19, 0x0020, 0x0050 }, 2843a7a92cf8SHeiner Kallweit { 0x0c, 0x0100, 0x0020 }, 2844a7a92cf8SHeiner Kallweit { 0x10, 0x0004, 0x0000 }, 284525e992a4SHeiner Kallweit }; 284625e992a4SHeiner Kallweit 284725e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 284825e992a4SHeiner Kallweit 284925e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168d_4); 285025e992a4SHeiner Kallweit 285125e992a4SHeiner Kallweit rtl_enable_clock_request(tp); 285225e992a4SHeiner Kallweit } 285325e992a4SHeiner Kallweit 285425e992a4SHeiner Kallweit static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) 285525e992a4SHeiner Kallweit { 285625e992a4SHeiner Kallweit static const struct ephy_info e_info_8168e_1[] = { 285725e992a4SHeiner Kallweit { 0x00, 0x0200, 0x0100 }, 285825e992a4SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 285925e992a4SHeiner Kallweit { 0x06, 0x0002, 0x0001 }, 286025e992a4SHeiner Kallweit { 0x06, 0x0000, 0x0030 }, 286125e992a4SHeiner Kallweit { 0x07, 0x0000, 0x2000 }, 286225e992a4SHeiner Kallweit { 0x00, 0x0000, 0x0020 }, 286325e992a4SHeiner Kallweit { 0x03, 0x5800, 0x2000 }, 286425e992a4SHeiner Kallweit { 0x03, 0x0000, 0x0001 }, 286525e992a4SHeiner Kallweit { 0x01, 0x0800, 0x1000 }, 286625e992a4SHeiner Kallweit { 0x07, 0x0000, 0x4000 }, 286725e992a4SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 286825e992a4SHeiner Kallweit { 0x19, 0xffff, 0xfe6c }, 286925e992a4SHeiner Kallweit { 0x0a, 0x0000, 0x0040 } 287025e992a4SHeiner Kallweit }; 287125e992a4SHeiner Kallweit 287225e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 287325e992a4SHeiner Kallweit 287425e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168e_1); 287525e992a4SHeiner Kallweit 287625e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 287725e992a4SHeiner Kallweit 287825e992a4SHeiner Kallweit /* Reset tx FIFO pointer */ 287925e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | TXPLA_RST); 288025e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~TXPLA_RST); 288125e992a4SHeiner Kallweit 288225e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 288325e992a4SHeiner Kallweit } 288425e992a4SHeiner Kallweit 288525e992a4SHeiner Kallweit static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) 288625e992a4SHeiner Kallweit { 288725e992a4SHeiner Kallweit static const struct ephy_info e_info_8168e_2[] = { 288825e992a4SHeiner Kallweit { 0x09, 0x0000, 0x0080 }, 2889a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2890a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2891a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 289225e992a4SHeiner Kallweit }; 289325e992a4SHeiner Kallweit 289425e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 289525e992a4SHeiner Kallweit 289625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168e_2); 289725e992a4SHeiner Kallweit 289825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 289933b00ca1SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_1111, 0x0000); 290025e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); 290133b00ca1SHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, 0x1f00); 290233b00ca1SHeiner Kallweit rtl_eri_set_bits(tp, 0x1d0, BIT(1)); 290333b00ca1SHeiner Kallweit rtl_reset_packet_filter(tp); 290433b00ca1SHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, BIT(4)); 290525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050); 290625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x07ff0060); 290725e992a4SHeiner Kallweit 290825e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 290925e992a4SHeiner Kallweit 291025e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 291125e992a4SHeiner Kallweit 291225e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 291325e992a4SHeiner Kallweit 291425e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 291525e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN); 291625e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 291725e992a4SHeiner Kallweit 291825e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 291925e992a4SHeiner Kallweit } 292025e992a4SHeiner Kallweit 292125e992a4SHeiner Kallweit static void rtl_hw_start_8168f(struct rtl8169_private *tp) 292225e992a4SHeiner Kallweit { 292325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 292425e992a4SHeiner Kallweit 292525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 2926d05890c5SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_1111, 0x0000); 292725e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); 292825e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 292954113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, BIT(4)); 2930d05890c5SHeiner Kallweit rtl_eri_set_bits(tp, 0x1d0, BIT(4) | BIT(1)); 293125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050); 293225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060); 293325e992a4SHeiner Kallweit 293425e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 293525e992a4SHeiner Kallweit 293625e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 293725e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 293825e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN); 293925e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 294025e992a4SHeiner Kallweit 294125e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 294225e992a4SHeiner Kallweit } 294325e992a4SHeiner Kallweit 294425e992a4SHeiner Kallweit static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) 294525e992a4SHeiner Kallweit { 294625e992a4SHeiner Kallweit static const struct ephy_info e_info_8168f_1[] = { 294725e992a4SHeiner Kallweit { 0x06, 0x00c0, 0x0020 }, 294825e992a4SHeiner Kallweit { 0x08, 0x0001, 0x0002 }, 294925e992a4SHeiner Kallweit { 0x09, 0x0000, 0x0080 }, 2950a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2951a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2952a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 295325e992a4SHeiner Kallweit }; 295425e992a4SHeiner Kallweit 295525e992a4SHeiner Kallweit rtl_hw_start_8168f(tp); 295625e992a4SHeiner Kallweit 295725e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168f_1); 295825e992a4SHeiner Kallweit 2959d05890c5SHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, 0x1f00); 296025e992a4SHeiner Kallweit } 296125e992a4SHeiner Kallweit 296225e992a4SHeiner Kallweit static void rtl_hw_start_8411(struct rtl8169_private *tp) 296325e992a4SHeiner Kallweit { 296425e992a4SHeiner Kallweit static const struct ephy_info e_info_8168f_1[] = { 296525e992a4SHeiner Kallweit { 0x06, 0x00c0, 0x0020 }, 296625e992a4SHeiner Kallweit { 0x0f, 0xffff, 0x5200 }, 2967a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2968a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2969a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 297025e992a4SHeiner Kallweit }; 297125e992a4SHeiner Kallweit 297225e992a4SHeiner Kallweit rtl_hw_start_8168f(tp); 297325e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 297425e992a4SHeiner Kallweit 297525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168f_1); 297625e992a4SHeiner Kallweit 297754113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, 0x0c00); 297825e992a4SHeiner Kallweit } 297925e992a4SHeiner Kallweit 298025e992a4SHeiner Kallweit static void rtl_hw_start_8168g(struct rtl8169_private *tp) 298125e992a4SHeiner Kallweit { 298225e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 298325e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x38, 0x48); 298425e992a4SHeiner Kallweit 298525e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 298625e992a4SHeiner Kallweit 298725e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 298825e992a4SHeiner Kallweit rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f); 298925e992a4SHeiner Kallweit 299025e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 299125e992a4SHeiner Kallweit 299225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 299325e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 2994d29d5ff9SHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, 0x1f80); 299525e992a4SHeiner Kallweit 299625e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 299725e992a4SHeiner Kallweit 299854113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x2fc, 0x01, 0x06); 299954113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12)); 300025e992a4SHeiner Kallweit 300125e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 300225e992a4SHeiner Kallweit } 300325e992a4SHeiner Kallweit 300425e992a4SHeiner Kallweit static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) 300525e992a4SHeiner Kallweit { 300625e992a4SHeiner Kallweit static const struct ephy_info e_info_8168g_1[] = { 3007a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 3008a7a92cf8SHeiner Kallweit { 0x0c, 0x3ff0, 0x0820 }, 300925e992a4SHeiner Kallweit { 0x1e, 0x0000, 0x0001 }, 301025e992a4SHeiner Kallweit { 0x19, 0x8000, 0x0000 } 301125e992a4SHeiner Kallweit }; 301225e992a4SHeiner Kallweit 301325e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 301425e992a4SHeiner Kallweit 301525e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 301625e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 301725e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168g_1); 301825e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 301925e992a4SHeiner Kallweit } 302025e992a4SHeiner Kallweit 302125e992a4SHeiner Kallweit static void rtl_hw_start_8168g_2(struct rtl8169_private *tp) 302225e992a4SHeiner Kallweit { 302325e992a4SHeiner Kallweit static const struct ephy_info e_info_8168g_2[] = { 3024a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 3025a7a92cf8SHeiner Kallweit { 0x0c, 0x3ff0, 0x0820 }, 3026a7a92cf8SHeiner Kallweit { 0x19, 0xffff, 0x7c00 }, 3027a7a92cf8SHeiner Kallweit { 0x1e, 0xffff, 0x20eb }, 3028a7a92cf8SHeiner Kallweit { 0x0d, 0xffff, 0x1666 }, 3029a7a92cf8SHeiner Kallweit { 0x00, 0xffff, 0x10a3 }, 3030a7a92cf8SHeiner Kallweit { 0x06, 0xffff, 0xf050 }, 3031a7a92cf8SHeiner Kallweit { 0x04, 0x0000, 0x0010 }, 3032a7a92cf8SHeiner Kallweit { 0x1d, 0x4000, 0x0000 }, 303325e992a4SHeiner Kallweit }; 303425e992a4SHeiner Kallweit 303525e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 303625e992a4SHeiner Kallweit 303725e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 3038ebdcebcbSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 303925e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168g_2); 304025e992a4SHeiner Kallweit } 304125e992a4SHeiner Kallweit 304225e992a4SHeiner Kallweit static void rtl_hw_start_8411_2(struct rtl8169_private *tp) 304325e992a4SHeiner Kallweit { 304425e992a4SHeiner Kallweit static const struct ephy_info e_info_8411_2[] = { 3045a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 3046a7a92cf8SHeiner Kallweit { 0x0c, 0x37d0, 0x0820 }, 3047a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x0001 }, 3048a7a92cf8SHeiner Kallweit { 0x19, 0x8021, 0x0000 }, 3049a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 3050a7a92cf8SHeiner Kallweit { 0x0d, 0x0100, 0x0200 }, 3051a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0080 }, 3052a7a92cf8SHeiner Kallweit { 0x06, 0x0000, 0x0010 }, 3053a7a92cf8SHeiner Kallweit { 0x04, 0x0000, 0x0010 }, 3054a7a92cf8SHeiner Kallweit { 0x1d, 0x0000, 0x4000 }, 305525e992a4SHeiner Kallweit }; 305625e992a4SHeiner Kallweit 305725e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 305825e992a4SHeiner Kallweit 305925e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 306025e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 306125e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8411_2); 3062fe4e8db0SHeiner Kallweit 3063fe4e8db0SHeiner Kallweit /* The following Realtek-provided magic fixes an issue with the RX unit 3064fe4e8db0SHeiner Kallweit * getting confused after the PHY having been powered-down. 3065fe4e8db0SHeiner Kallweit */ 3066fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC28, 0x0000); 3067fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2A, 0x0000); 3068fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2C, 0x0000); 3069fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2E, 0x0000); 3070fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC30, 0x0000); 3071fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC32, 0x0000); 3072fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC34, 0x0000); 3073fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC36, 0x0000); 3074fe4e8db0SHeiner Kallweit mdelay(3); 3075fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC26, 0x0000); 3076fe4e8db0SHeiner Kallweit 3077fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF800, 0xE008); 3078fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF802, 0xE00A); 3079fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF804, 0xE00C); 3080fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF806, 0xE00E); 3081fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF808, 0xE027); 3082fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80A, 0xE04F); 3083fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80C, 0xE05E); 3084fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80E, 0xE065); 3085fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF810, 0xC602); 3086fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF812, 0xBE00); 3087fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF814, 0x0000); 3088fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF816, 0xC502); 3089fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF818, 0xBD00); 3090fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81A, 0x074C); 3091fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81C, 0xC302); 3092fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81E, 0xBB00); 3093fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF820, 0x080A); 3094fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF822, 0x6420); 3095fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF824, 0x48C2); 3096fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF826, 0x8C20); 3097fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF828, 0xC516); 3098fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82A, 0x64A4); 3099fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82C, 0x49C0); 3100fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82E, 0xF009); 3101fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF830, 0x74A2); 3102fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF832, 0x8CA5); 3103fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF834, 0x74A0); 3104fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF836, 0xC50E); 3105fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF838, 0x9CA2); 3106fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83A, 0x1C11); 3107fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83C, 0x9CA0); 3108fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83E, 0xE006); 3109fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF840, 0x74F8); 3110fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF842, 0x48C4); 3111fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF844, 0x8CF8); 3112fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF846, 0xC404); 3113fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF848, 0xBC00); 3114fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84A, 0xC403); 3115fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84C, 0xBC00); 3116fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84E, 0x0BF2); 3117fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF850, 0x0C0A); 3118fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF852, 0xE434); 3119fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF854, 0xD3C0); 3120fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF856, 0x49D9); 3121fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF858, 0xF01F); 3122fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85A, 0xC526); 3123fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85C, 0x64A5); 3124fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85E, 0x1400); 3125fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF860, 0xF007); 3126fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF862, 0x0C01); 3127fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF864, 0x8CA5); 3128fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF866, 0x1C15); 3129fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF868, 0xC51B); 3130fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86A, 0x9CA0); 3131fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86C, 0xE013); 3132fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86E, 0xC519); 3133fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF870, 0x74A0); 3134fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF872, 0x48C4); 3135fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF874, 0x8CA0); 3136fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF876, 0xC516); 3137fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF878, 0x74A4); 3138fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87A, 0x48C8); 3139fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87C, 0x48CA); 3140fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87E, 0x9CA4); 3141fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF880, 0xC512); 3142fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF882, 0x1B00); 3143fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF884, 0x9BA0); 3144fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF886, 0x1B1C); 3145fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF888, 0x483F); 3146fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88A, 0x9BA2); 3147fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88C, 0x1B04); 3148fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88E, 0xC508); 3149fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF890, 0x9BA0); 3150fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF892, 0xC505); 3151fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF894, 0xBD00); 3152fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF896, 0xC502); 3153fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF898, 0xBD00); 3154fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89A, 0x0300); 3155fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89C, 0x051E); 3156fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89E, 0xE434); 3157fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A0, 0xE018); 3158fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A2, 0xE092); 3159fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A4, 0xDE20); 3160fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A6, 0xD3C0); 3161fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A8, 0xC50F); 3162fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AA, 0x76A4); 3163fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AC, 0x49E3); 3164fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AE, 0xF007); 3165fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B0, 0x49C0); 3166fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B2, 0xF103); 3167fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B4, 0xC607); 3168fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B6, 0xBE00); 3169fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B8, 0xC606); 3170fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BA, 0xBE00); 3171fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BC, 0xC602); 3172fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BE, 0xBE00); 3173fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C0, 0x0C4C); 3174fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C2, 0x0C28); 3175fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C4, 0x0C2C); 3176fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C6, 0xDC00); 3177fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C8, 0xC707); 3178fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CA, 0x1D00); 3179fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CC, 0x8DE2); 3180fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CE, 0x48C1); 3181fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D0, 0xC502); 3182fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D2, 0xBD00); 3183fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D4, 0x00AA); 3184fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D6, 0xE0C0); 3185fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D8, 0xC502); 3186fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8DA, 0xBD00); 3187fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8DC, 0x0132); 3188fe4e8db0SHeiner Kallweit 3189fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC26, 0x8000); 3190fe4e8db0SHeiner Kallweit 3191fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2A, 0x0743); 3192fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2C, 0x0801); 3193fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2E, 0x0BE9); 3194fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC30, 0x02FD); 3195fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC32, 0x0C25); 3196fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC34, 0x00A9); 3197fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC36, 0x012D); 3198fe4e8db0SHeiner Kallweit 319925e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 320025e992a4SHeiner Kallweit } 320125e992a4SHeiner Kallweit 320225e992a4SHeiner Kallweit static void rtl_hw_start_8168h_1(struct rtl8169_private *tp) 320325e992a4SHeiner Kallweit { 320425e992a4SHeiner Kallweit static const struct ephy_info e_info_8168h_1[] = { 320525e992a4SHeiner Kallweit { 0x1e, 0x0800, 0x0001 }, 320625e992a4SHeiner Kallweit { 0x1d, 0x0000, 0x0800 }, 320725e992a4SHeiner Kallweit { 0x05, 0xffff, 0x2089 }, 320825e992a4SHeiner Kallweit { 0x06, 0xffff, 0x5881 }, 3209a7a92cf8SHeiner Kallweit { 0x04, 0xffff, 0x854a }, 321025e992a4SHeiner Kallweit { 0x01, 0xffff, 0x068b } 321125e992a4SHeiner Kallweit }; 3212ef712edeSHeiner Kallweit int rg_saw_cnt; 321325e992a4SHeiner Kallweit 321425e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 321525e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 321625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168h_1); 321725e992a4SHeiner Kallweit 321825e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 321925e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x38, 0x48); 322025e992a4SHeiner Kallweit 322125e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 322225e992a4SHeiner Kallweit 322325e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 322425e992a4SHeiner Kallweit 322554113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x1f00); 3226ee1350f9SHeiner Kallweit rtl_eri_set_bits(tp, 0xdc, 0x001c); 322725e992a4SHeiner Kallweit 322825e992a4SHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 322925e992a4SHeiner Kallweit 323025e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 323125e992a4SHeiner Kallweit 323225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 323325e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 323425e992a4SHeiner Kallweit 323525e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 323625e992a4SHeiner Kallweit 323725e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 323825e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 323925e992a4SHeiner Kallweit 324025e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 324125e992a4SHeiner Kallweit 324254113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12)); 324325e992a4SHeiner Kallweit 324425e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 324525e992a4SHeiner Kallweit 32463ab077d2SHeiner Kallweit rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff; 324725e992a4SHeiner Kallweit if (rg_saw_cnt > 0) { 324825e992a4SHeiner Kallweit u16 sw_cnt_1ms_ini; 324925e992a4SHeiner Kallweit 325025e992a4SHeiner Kallweit sw_cnt_1ms_ini = 16000000/rg_saw_cnt; 325125e992a4SHeiner Kallweit sw_cnt_1ms_ini &= 0x0fff; 3252ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini); 325325e992a4SHeiner Kallweit } 325425e992a4SHeiner Kallweit 3255ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070); 3256ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x6000, 0x8008); 3257ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe0d6, 0x01ff, 0x017f); 3258ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f); 325925e992a4SHeiner Kallweit 326025e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0001); 326125e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0000); 326225e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xc094, 0x0000); 326325e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xc09e, 0x0000); 326425e992a4SHeiner Kallweit 326525e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 326625e992a4SHeiner Kallweit } 326725e992a4SHeiner Kallweit 326825e992a4SHeiner Kallweit static void rtl_hw_start_8168ep(struct rtl8169_private *tp) 326925e992a4SHeiner Kallweit { 327025e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp); 327125e992a4SHeiner Kallweit 327225e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 327325e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f); 327425e992a4SHeiner Kallweit 327525e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 327625e992a4SHeiner Kallweit 327725e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 327825e992a4SHeiner Kallweit 327954113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x1f80); 328025e992a4SHeiner Kallweit 328125e992a4SHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 328225e992a4SHeiner Kallweit 328325e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 328425e992a4SHeiner Kallweit 328525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 328625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 328725e992a4SHeiner Kallweit 328825e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 328925e992a4SHeiner Kallweit 329054113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x2fc, 0x01, 0x06); 329125e992a4SHeiner Kallweit 329225e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 329325e992a4SHeiner Kallweit 329425e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 329525e992a4SHeiner Kallweit } 329625e992a4SHeiner Kallweit 329725e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_1(struct rtl8169_private *tp) 329825e992a4SHeiner Kallweit { 329925e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_1[] = { 330025e992a4SHeiner Kallweit { 0x00, 0xffff, 0x10ab }, 330125e992a4SHeiner Kallweit { 0x06, 0xffff, 0xf030 }, 330225e992a4SHeiner Kallweit { 0x08, 0xffff, 0x2006 }, 330325e992a4SHeiner Kallweit { 0x0d, 0xffff, 0x1666 }, 330425e992a4SHeiner Kallweit { 0x0c, 0x3ff0, 0x0000 } 330525e992a4SHeiner Kallweit }; 330625e992a4SHeiner Kallweit 330725e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 330825e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 330925e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_1); 331025e992a4SHeiner Kallweit 331125e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 331225e992a4SHeiner Kallweit 331325e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 331425e992a4SHeiner Kallweit } 331525e992a4SHeiner Kallweit 331625e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_2(struct rtl8169_private *tp) 331725e992a4SHeiner Kallweit { 331825e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_2[] = { 331925e992a4SHeiner Kallweit { 0x00, 0xffff, 0x10a3 }, 332025e992a4SHeiner Kallweit { 0x19, 0xffff, 0xfc00 }, 332125e992a4SHeiner Kallweit { 0x1e, 0xffff, 0x20ea } 332225e992a4SHeiner Kallweit }; 332325e992a4SHeiner Kallweit 332425e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 332525e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 332625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_2); 332725e992a4SHeiner Kallweit 332825e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 332925e992a4SHeiner Kallweit 333025e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 333125e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 333225e992a4SHeiner Kallweit 333325e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 333425e992a4SHeiner Kallweit } 333525e992a4SHeiner Kallweit 333625e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp) 333725e992a4SHeiner Kallweit { 333825e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_3[] = { 3339a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0080 }, 3340a7a92cf8SHeiner Kallweit { 0x0d, 0x0100, 0x0200 }, 3341a7a92cf8SHeiner Kallweit { 0x19, 0x8021, 0x0000 }, 3342a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 334325e992a4SHeiner Kallweit }; 334425e992a4SHeiner Kallweit 334525e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 334625e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 334725e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_3); 334825e992a4SHeiner Kallweit 334925e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 335025e992a4SHeiner Kallweit 335125e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 335225e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 335325e992a4SHeiner Kallweit 3354ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e2, 0x0fff, 0x0271); 3355ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e4, 0x00ff, 0x0000); 3356ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe860, 0x0000, 0x0080); 335725e992a4SHeiner Kallweit 335825e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 335925e992a4SHeiner Kallweit } 336025e992a4SHeiner Kallweit 33611287723aSHeiner Kallweit static void rtl_hw_start_8117(struct rtl8169_private *tp) 33621287723aSHeiner Kallweit { 33631287723aSHeiner Kallweit static const struct ephy_info e_info_8117[] = { 33641287723aSHeiner Kallweit { 0x19, 0x0040, 0x1100 }, 33651287723aSHeiner Kallweit { 0x59, 0x0040, 0x1100 }, 33661287723aSHeiner Kallweit }; 33671287723aSHeiner Kallweit int rg_saw_cnt; 33681287723aSHeiner Kallweit 33691287723aSHeiner Kallweit rtl8168ep_stop_cmac(tp); 33701287723aSHeiner Kallweit 33711287723aSHeiner Kallweit /* disable aspm and clock request before access ephy */ 33721287723aSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 33731287723aSHeiner Kallweit rtl_ephy_init(tp, e_info_8117); 33741287723aSHeiner Kallweit 33751287723aSHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 33761287723aSHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f); 33771287723aSHeiner Kallweit 33781287723aSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 33791287723aSHeiner Kallweit 33801287723aSHeiner Kallweit rtl_reset_packet_filter(tp); 33811287723aSHeiner Kallweit 338254113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x1f90); 33831287723aSHeiner Kallweit 33841287723aSHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 33851287723aSHeiner Kallweit 33861287723aSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 33871287723aSHeiner Kallweit 33881287723aSHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 33891287723aSHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 33901287723aSHeiner Kallweit 33911287723aSHeiner Kallweit rtl8168_config_eee_mac(tp); 33921287723aSHeiner Kallweit 33931287723aSHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 33941287723aSHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 33951287723aSHeiner Kallweit 33961287723aSHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 33971287723aSHeiner Kallweit 339854113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12)); 33991287723aSHeiner Kallweit 34001287723aSHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 34011287723aSHeiner Kallweit 34021287723aSHeiner Kallweit rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff; 34031287723aSHeiner Kallweit if (rg_saw_cnt > 0) { 34041287723aSHeiner Kallweit u16 sw_cnt_1ms_ini; 34051287723aSHeiner Kallweit 34061287723aSHeiner Kallweit sw_cnt_1ms_ini = (16000000 / rg_saw_cnt) & 0x0fff; 34071287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini); 34081287723aSHeiner Kallweit } 34091287723aSHeiner Kallweit 34101287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070); 34111287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xea80, 0x0003); 34121287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x0000, 0x0009); 34131287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f); 34141287723aSHeiner Kallweit 34151287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0001); 34161287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0000); 34171287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc094, 0x0000); 34181287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc09e, 0x0000); 34191287723aSHeiner Kallweit 3420229c1e0dSHeiner Kallweit /* firmware is for MAC only */ 34211c5be5e9SHeiner Kallweit r8169_apply_firmware(tp); 3422229c1e0dSHeiner Kallweit 34231287723aSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 34241287723aSHeiner Kallweit } 34251287723aSHeiner Kallweit 342625e992a4SHeiner Kallweit static void rtl_hw_start_8102e_1(struct rtl8169_private *tp) 342725e992a4SHeiner Kallweit { 342825e992a4SHeiner Kallweit static const struct ephy_info e_info_8102e_1[] = { 342925e992a4SHeiner Kallweit { 0x01, 0, 0x6e65 }, 343025e992a4SHeiner Kallweit { 0x02, 0, 0x091f }, 343125e992a4SHeiner Kallweit { 0x03, 0, 0xc2f9 }, 343225e992a4SHeiner Kallweit { 0x06, 0, 0xafb5 }, 343325e992a4SHeiner Kallweit { 0x07, 0, 0x0e00 }, 343425e992a4SHeiner Kallweit { 0x19, 0, 0xec80 }, 343525e992a4SHeiner Kallweit { 0x01, 0, 0x2e65 }, 343625e992a4SHeiner Kallweit { 0x01, 0, 0x6e65 } 343725e992a4SHeiner Kallweit }; 343825e992a4SHeiner Kallweit u8 cfg1; 343925e992a4SHeiner Kallweit 344025e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 344125e992a4SHeiner Kallweit 344225e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, FIX_NAK_1); 344325e992a4SHeiner Kallweit 344425e992a4SHeiner Kallweit RTL_W8(tp, Config1, 344525e992a4SHeiner Kallweit LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable); 344625e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 344725e992a4SHeiner Kallweit 344825e992a4SHeiner Kallweit cfg1 = RTL_R8(tp, Config1); 344925e992a4SHeiner Kallweit if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) 345025e992a4SHeiner Kallweit RTL_W8(tp, Config1, cfg1 & ~LEDS0); 345125e992a4SHeiner Kallweit 345225e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8102e_1); 345325e992a4SHeiner Kallweit } 345425e992a4SHeiner Kallweit 345525e992a4SHeiner Kallweit static void rtl_hw_start_8102e_2(struct rtl8169_private *tp) 345625e992a4SHeiner Kallweit { 345725e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 345825e992a4SHeiner Kallweit 345925e992a4SHeiner Kallweit RTL_W8(tp, Config1, MEMMAP | IOMAP | VPD | PMEnable); 346025e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 346125e992a4SHeiner Kallweit } 346225e992a4SHeiner Kallweit 346325e992a4SHeiner Kallweit static void rtl_hw_start_8102e_3(struct rtl8169_private *tp) 346425e992a4SHeiner Kallweit { 346525e992a4SHeiner Kallweit rtl_hw_start_8102e_2(tp); 346625e992a4SHeiner Kallweit 346725e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x03, 0xc2f9); 346825e992a4SHeiner Kallweit } 346925e992a4SHeiner Kallweit 347025e992a4SHeiner Kallweit static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) 347125e992a4SHeiner Kallweit { 347225e992a4SHeiner Kallweit static const struct ephy_info e_info_8105e_1[] = { 347325e992a4SHeiner Kallweit { 0x07, 0, 0x4000 }, 347425e992a4SHeiner Kallweit { 0x19, 0, 0x0200 }, 347525e992a4SHeiner Kallweit { 0x19, 0, 0x0020 }, 347625e992a4SHeiner Kallweit { 0x1e, 0, 0x2000 }, 347725e992a4SHeiner Kallweit { 0x03, 0, 0x0001 }, 347825e992a4SHeiner Kallweit { 0x19, 0, 0x0100 }, 347925e992a4SHeiner Kallweit { 0x19, 0, 0x0004 }, 348025e992a4SHeiner Kallweit { 0x0a, 0, 0x0020 } 348125e992a4SHeiner Kallweit }; 348225e992a4SHeiner Kallweit 348325e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 348425e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 348525e992a4SHeiner Kallweit 348625e992a4SHeiner Kallweit /* Disable Early Tally Counter */ 348725e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) & ~0x010000); 348825e992a4SHeiner Kallweit 348925e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET); 349025e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 349125e992a4SHeiner Kallweit 349225e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8105e_1); 349325e992a4SHeiner Kallweit 349425e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 349525e992a4SHeiner Kallweit } 349625e992a4SHeiner Kallweit 349725e992a4SHeiner Kallweit static void rtl_hw_start_8105e_2(struct rtl8169_private *tp) 349825e992a4SHeiner Kallweit { 349925e992a4SHeiner Kallweit rtl_hw_start_8105e_1(tp); 350025e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x1e, rtl_ephy_read(tp, 0x1e) | 0x8000); 350125e992a4SHeiner Kallweit } 350225e992a4SHeiner Kallweit 350325e992a4SHeiner Kallweit static void rtl_hw_start_8402(struct rtl8169_private *tp) 350425e992a4SHeiner Kallweit { 350525e992a4SHeiner Kallweit static const struct ephy_info e_info_8402[] = { 350625e992a4SHeiner Kallweit { 0x19, 0xffff, 0xff64 }, 350725e992a4SHeiner Kallweit { 0x1e, 0, 0x4000 } 350825e992a4SHeiner Kallweit }; 350925e992a4SHeiner Kallweit 351025e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 351125e992a4SHeiner Kallweit 351225e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 351325e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 351425e992a4SHeiner Kallweit 351525e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 351625e992a4SHeiner Kallweit 351725e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8402); 351825e992a4SHeiner Kallweit 351925e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x00, 0x00, 0x02, 0x06); 352025e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 352125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 352225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 352354113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x0d4, 0x0e00, 0xff00); 352425e992a4SHeiner Kallweit 35256d7a631eSHeiner Kallweit /* disable EEE */ 35266d7a631eSHeiner Kallweit rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000); 35276d7a631eSHeiner Kallweit 352825e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 352925e992a4SHeiner Kallweit } 353025e992a4SHeiner Kallweit 353125e992a4SHeiner Kallweit static void rtl_hw_start_8106(struct rtl8169_private *tp) 353225e992a4SHeiner Kallweit { 353325e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 353425e992a4SHeiner Kallweit 353525e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 353625e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 353725e992a4SHeiner Kallweit 353825e992a4SHeiner Kallweit RTL_W32(tp, MISC, (RTL_R32(tp, MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN); 353925e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET); 354025e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 354125e992a4SHeiner Kallweit 35428d46f620SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000); 35438d46f620SHeiner Kallweit 35446d7a631eSHeiner Kallweit /* disable EEE */ 35456d7a631eSHeiner Kallweit rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000); 35466d7a631eSHeiner Kallweit 354725e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 354825e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 354925e992a4SHeiner Kallweit } 355025e992a4SHeiner Kallweit 3551f1bce4adSHeiner Kallweit DECLARE_RTL_COND(rtl_mac_ocp_e00e_cond) 3552f1bce4adSHeiner Kallweit { 3553f1bce4adSHeiner Kallweit return r8168_mac_ocp_read(tp, 0xe00e) & BIT(13); 3554f1bce4adSHeiner Kallweit } 3555f1bce4adSHeiner Kallweit 3556f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_common(struct rtl8169_private *tp) 3557f1bce4adSHeiner Kallweit { 3558f1bce4adSHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 3559f1bce4adSHeiner Kallweit 3560f1bce4adSHeiner Kallweit RTL_W16(tp, 0x382, 0x221b); 3561f1bce4adSHeiner Kallweit RTL_W8(tp, 0x4500, 0); 3562f1bce4adSHeiner Kallweit RTL_W16(tp, 0x4800, 0); 3563f1bce4adSHeiner Kallweit 3564f1bce4adSHeiner Kallweit /* disable UPS */ 3565f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd40a, 0x0010, 0x0000); 3566f1bce4adSHeiner Kallweit 3567f1bce4adSHeiner Kallweit RTL_W8(tp, Config1, RTL_R8(tp, Config1) & ~0x10); 3568f1bce4adSHeiner Kallweit 3569f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc140, 0xffff); 3570f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc142, 0xffff); 3571f1bce4adSHeiner Kallweit 3572f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e2, 0x0fff, 0x03a9); 3573f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e4, 0x00ff, 0x0000); 3574f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe860, 0x0000, 0x0080); 3575f1bce4adSHeiner Kallweit 3576f1bce4adSHeiner Kallweit /* disable new tx descriptor format */ 3577f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000); 3578f1bce4adSHeiner Kallweit 3579f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400); 3580f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0020); 3581f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b4, 0x0000, 0x000c); 3582f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb6a, 0x00ff, 0x0033); 3583f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb50, 0x03e0, 0x0040); 3584f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); 3585f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); 3586f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403); 3587f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0067); 3588f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0ac, 0x0080, 0x1f00); 3589f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f); 3590f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe84c, 0x0000, 0x00c0); 3591f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000); 3592f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb54, 0x0000, 0x0001); 3593f1bce4adSHeiner Kallweit udelay(1); 3594f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb54, 0x0001, 0x0000); 3595f1bce4adSHeiner Kallweit RTL_W16(tp, 0x1880, RTL_R16(tp, 0x1880) & ~0x0030); 3596f1bce4adSHeiner Kallweit 3597f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe098, 0xc302); 3598f1bce4adSHeiner Kallweit 3599d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10); 3600f1bce4adSHeiner Kallweit 3601b3a42e3aSHeiner Kallweit rtl8125_config_eee_mac(tp); 3602b3a42e3aSHeiner Kallweit 3603f1bce4adSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 3604f1bce4adSHeiner Kallweit udelay(10); 3605f1bce4adSHeiner Kallweit } 3606f1bce4adSHeiner Kallweit 3607f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_1(struct rtl8169_private *tp) 3608f1bce4adSHeiner Kallweit { 3609f1bce4adSHeiner Kallweit static const struct ephy_info e_info_8125_1[] = { 3610f1bce4adSHeiner Kallweit { 0x01, 0xffff, 0xa812 }, 3611f1bce4adSHeiner Kallweit { 0x09, 0xffff, 0x520c }, 3612f1bce4adSHeiner Kallweit { 0x04, 0xffff, 0xd000 }, 3613f1bce4adSHeiner Kallweit { 0x0d, 0xffff, 0xf702 }, 3614f1bce4adSHeiner Kallweit { 0x0a, 0xffff, 0x8653 }, 3615f1bce4adSHeiner Kallweit { 0x06, 0xffff, 0x001e }, 3616f1bce4adSHeiner Kallweit { 0x08, 0xffff, 0x3595 }, 3617f1bce4adSHeiner Kallweit { 0x20, 0xffff, 0x9455 }, 3618f1bce4adSHeiner Kallweit { 0x21, 0xffff, 0x99ff }, 3619f1bce4adSHeiner Kallweit { 0x02, 0xffff, 0x6046 }, 3620f1bce4adSHeiner Kallweit { 0x29, 0xffff, 0xfe00 }, 3621f1bce4adSHeiner Kallweit { 0x23, 0xffff, 0xab62 }, 3622f1bce4adSHeiner Kallweit 3623f1bce4adSHeiner Kallweit { 0x41, 0xffff, 0xa80c }, 3624f1bce4adSHeiner Kallweit { 0x49, 0xffff, 0x520c }, 3625f1bce4adSHeiner Kallweit { 0x44, 0xffff, 0xd000 }, 3626f1bce4adSHeiner Kallweit { 0x4d, 0xffff, 0xf702 }, 3627f1bce4adSHeiner Kallweit { 0x4a, 0xffff, 0x8653 }, 3628f1bce4adSHeiner Kallweit { 0x46, 0xffff, 0x001e }, 3629f1bce4adSHeiner Kallweit { 0x48, 0xffff, 0x3595 }, 3630f1bce4adSHeiner Kallweit { 0x60, 0xffff, 0x9455 }, 3631f1bce4adSHeiner Kallweit { 0x61, 0xffff, 0x99ff }, 3632f1bce4adSHeiner Kallweit { 0x42, 0xffff, 0x6046 }, 3633f1bce4adSHeiner Kallweit { 0x69, 0xffff, 0xfe00 }, 3634f1bce4adSHeiner Kallweit { 0x63, 0xffff, 0xab62 }, 3635f1bce4adSHeiner Kallweit }; 3636f1bce4adSHeiner Kallweit 3637f1bce4adSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 3638f1bce4adSHeiner Kallweit 3639f1bce4adSHeiner Kallweit /* disable aspm and clock request before access ephy */ 3640f1bce4adSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 3641f1bce4adSHeiner Kallweit rtl_ephy_init(tp, e_info_8125_1); 3642f1bce4adSHeiner Kallweit 3643f1bce4adSHeiner Kallweit rtl_hw_start_8125_common(tp); 3644f1bce4adSHeiner Kallweit } 3645f1bce4adSHeiner Kallweit 3646f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_2(struct rtl8169_private *tp) 3647f1bce4adSHeiner Kallweit { 3648f1bce4adSHeiner Kallweit static const struct ephy_info e_info_8125_2[] = { 3649f1bce4adSHeiner Kallweit { 0x04, 0xffff, 0xd000 }, 3650f1bce4adSHeiner Kallweit { 0x0a, 0xffff, 0x8653 }, 3651f1bce4adSHeiner Kallweit { 0x23, 0xffff, 0xab66 }, 3652f1bce4adSHeiner Kallweit { 0x20, 0xffff, 0x9455 }, 3653f1bce4adSHeiner Kallweit { 0x21, 0xffff, 0x99ff }, 3654f1bce4adSHeiner Kallweit { 0x29, 0xffff, 0xfe04 }, 3655f1bce4adSHeiner Kallweit 3656f1bce4adSHeiner Kallweit { 0x44, 0xffff, 0xd000 }, 3657f1bce4adSHeiner Kallweit { 0x4a, 0xffff, 0x8653 }, 3658f1bce4adSHeiner Kallweit { 0x63, 0xffff, 0xab66 }, 3659f1bce4adSHeiner Kallweit { 0x60, 0xffff, 0x9455 }, 3660f1bce4adSHeiner Kallweit { 0x61, 0xffff, 0x99ff }, 3661f1bce4adSHeiner Kallweit { 0x69, 0xffff, 0xfe04 }, 3662f1bce4adSHeiner Kallweit }; 3663f1bce4adSHeiner Kallweit 3664f1bce4adSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 3665f1bce4adSHeiner Kallweit 3666f1bce4adSHeiner Kallweit /* disable aspm and clock request before access ephy */ 3667f1bce4adSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 3668f1bce4adSHeiner Kallweit rtl_ephy_init(tp, e_info_8125_2); 3669f1bce4adSHeiner Kallweit 3670f1bce4adSHeiner Kallweit rtl_hw_start_8125_common(tp); 3671f1bce4adSHeiner Kallweit } 3672f1bce4adSHeiner Kallweit 367325e992a4SHeiner Kallweit static void rtl_hw_config(struct rtl8169_private *tp) 367425e992a4SHeiner Kallweit { 367525e992a4SHeiner Kallweit static const rtl_generic_fct hw_configs[] = { 367625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_07] = rtl_hw_start_8102e_1, 367725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_08] = rtl_hw_start_8102e_3, 367825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_09] = rtl_hw_start_8102e_2, 367925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_10] = NULL, 368094b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b, 368194b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_12] = rtl_hw_start_8168b, 368225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_13] = NULL, 368325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_14] = NULL, 368425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_15] = NULL, 368525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_16] = NULL, 368694b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b, 368725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1, 368825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_19] = rtl_hw_start_8168c_1, 368925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_20] = rtl_hw_start_8168c_2, 369025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_21] = rtl_hw_start_8168c_3, 369125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_22] = rtl_hw_start_8168c_4, 369225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_23] = rtl_hw_start_8168cp_2, 369325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_24] = rtl_hw_start_8168cp_3, 369425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_25] = rtl_hw_start_8168d, 369525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_26] = rtl_hw_start_8168d, 369625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_27] = rtl_hw_start_8168d, 369725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_28] = rtl_hw_start_8168d_4, 369825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_29] = rtl_hw_start_8105e_1, 369925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_30] = rtl_hw_start_8105e_2, 37000a413e6bSHeiner Kallweit [RTL_GIGA_MAC_VER_31] = rtl_hw_start_8168d, 370125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_32] = rtl_hw_start_8168e_1, 370225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_33] = rtl_hw_start_8168e_1, 370325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_34] = rtl_hw_start_8168e_2, 370425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_35] = rtl_hw_start_8168f_1, 370525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_36] = rtl_hw_start_8168f_1, 370625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_37] = rtl_hw_start_8402, 370725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_38] = rtl_hw_start_8411, 370825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_39] = rtl_hw_start_8106, 370925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_40] = rtl_hw_start_8168g_1, 371025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_41] = rtl_hw_start_8168g_1, 371125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_42] = rtl_hw_start_8168g_2, 371225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_43] = rtl_hw_start_8168g_2, 371325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_44] = rtl_hw_start_8411_2, 371425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_45] = rtl_hw_start_8168h_1, 371525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_46] = rtl_hw_start_8168h_1, 371625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_47] = rtl_hw_start_8168h_1, 371725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_48] = rtl_hw_start_8168h_1, 371825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_49] = rtl_hw_start_8168ep_1, 371925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_50] = rtl_hw_start_8168ep_2, 372025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3, 37211287723aSHeiner Kallweit [RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117, 3722f1bce4adSHeiner Kallweit [RTL_GIGA_MAC_VER_60] = rtl_hw_start_8125_1, 3723f1bce4adSHeiner Kallweit [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125_2, 372425e992a4SHeiner Kallweit }; 372525e992a4SHeiner Kallweit 372625e992a4SHeiner Kallweit if (hw_configs[tp->mac_version]) 372725e992a4SHeiner Kallweit hw_configs[tp->mac_version](tp); 372825e992a4SHeiner Kallweit } 372925e992a4SHeiner Kallweit 3730f1bce4adSHeiner Kallweit static void rtl_hw_start_8125(struct rtl8169_private *tp) 3731f1bce4adSHeiner Kallweit { 3732f1bce4adSHeiner Kallweit int i; 3733f1bce4adSHeiner Kallweit 3734f1bce4adSHeiner Kallweit /* disable interrupt coalescing */ 3735f1bce4adSHeiner Kallweit for (i = 0xa00; i < 0xb00; i += 4) 3736f1bce4adSHeiner Kallweit RTL_W32(tp, i, 0); 3737f1bce4adSHeiner Kallweit 3738f1bce4adSHeiner Kallweit rtl_hw_config(tp); 3739f1bce4adSHeiner Kallweit } 3740f1bce4adSHeiner Kallweit 374125e992a4SHeiner Kallweit static void rtl_hw_start_8168(struct rtl8169_private *tp) 374225e992a4SHeiner Kallweit { 3743272b2265SHeiner Kallweit if (rtl_is_8168evl_up(tp)) 3744272b2265SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, EarlySize); 3745272b2265SHeiner Kallweit else 374625e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, TxPacketMax); 374725e992a4SHeiner Kallweit 374825e992a4SHeiner Kallweit rtl_hw_config(tp); 3749bcf2b868SHeiner Kallweit 3750bcf2b868SHeiner Kallweit /* disable interrupt coalescing */ 3751bcf2b868SHeiner Kallweit RTL_W16(tp, IntrMitigate, 0x0000); 375225e992a4SHeiner Kallweit } 375325e992a4SHeiner Kallweit 37546c19156eSHeiner Kallweit static void rtl_hw_start_8169(struct rtl8169_private *tp) 37556c19156eSHeiner Kallweit { 37566c19156eSHeiner Kallweit RTL_W8(tp, EarlyTxThres, NoEarlyTx); 37576c19156eSHeiner Kallweit 37586c19156eSHeiner Kallweit tp->cp_cmd |= PCIMulRW; 37596c19156eSHeiner Kallweit 37606c19156eSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_02 || 376109e65335SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_03) 376209e65335SHeiner Kallweit tp->cp_cmd |= EnAnaPLL; 37636c19156eSHeiner Kallweit 37646c19156eSHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 37656c19156eSHeiner Kallweit 3766ef891284SHeiner Kallweit rtl8169_set_magic_reg(tp); 37676c19156eSHeiner Kallweit 3768bcf2b868SHeiner Kallweit /* disable interrupt coalescing */ 3769bcf2b868SHeiner Kallweit RTL_W16(tp, IntrMitigate, 0x0000); 37706c19156eSHeiner Kallweit } 37716c19156eSHeiner Kallweit 37726c19156eSHeiner Kallweit static void rtl_hw_start(struct rtl8169_private *tp) 37736c19156eSHeiner Kallweit { 37746c19156eSHeiner Kallweit rtl_unlock_config_regs(tp); 37756c19156eSHeiner Kallweit 37766c19156eSHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 37776c19156eSHeiner Kallweit 37786c19156eSHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 37796c19156eSHeiner Kallweit rtl_hw_start_8169(tp); 3780f1bce4adSHeiner Kallweit else if (rtl_is_8125(tp)) 3781f1bce4adSHeiner Kallweit rtl_hw_start_8125(tp); 37826c19156eSHeiner Kallweit else 37836c19156eSHeiner Kallweit rtl_hw_start_8168(tp); 37846c19156eSHeiner Kallweit 37856c19156eSHeiner Kallweit rtl_set_rx_max_size(tp); 37866c19156eSHeiner Kallweit rtl_set_rx_tx_desc_registers(tp); 37876c19156eSHeiner Kallweit rtl_lock_config_regs(tp); 37886c19156eSHeiner Kallweit 37899db0ac57SHeiner Kallweit rtl_jumbo_config(tp); 37904ebcb113SHeiner Kallweit 37916c19156eSHeiner Kallweit /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ 3792711463f8SHeiner Kallweit rtl_pci_commit(tp); 3793711463f8SHeiner Kallweit 37946c19156eSHeiner Kallweit RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); 37956c19156eSHeiner Kallweit rtl_init_rxcfg(tp); 37966c19156eSHeiner Kallweit rtl_set_tx_config_registers(tp); 379710478283SHeiner Kallweit rtl_set_rx_config_features(tp, tp->dev->features); 37986c19156eSHeiner Kallweit rtl_set_rx_mode(tp->dev); 37996c19156eSHeiner Kallweit rtl_irq_enable(tp); 38006c19156eSHeiner Kallweit } 38016c19156eSHeiner Kallweit 380225e992a4SHeiner Kallweit static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) 380325e992a4SHeiner Kallweit { 380425e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 380525e992a4SHeiner Kallweit 380625e992a4SHeiner Kallweit dev->mtu = new_mtu; 380725e992a4SHeiner Kallweit netdev_update_features(dev); 38089db0ac57SHeiner Kallweit rtl_jumbo_config(tp); 380925e992a4SHeiner Kallweit 381025e992a4SHeiner Kallweit return 0; 381125e992a4SHeiner Kallweit } 381225e992a4SHeiner Kallweit 3813e2e5fb8dSHeiner Kallweit static void rtl8169_mark_to_asic(struct RxDesc *desc) 381425e992a4SHeiner Kallweit { 381525e992a4SHeiner Kallweit u32 eor = le32_to_cpu(desc->opts1) & RingEnd; 381625e992a4SHeiner Kallweit 3817047521d7SHeiner Kallweit desc->opts2 = 0; 381825e992a4SHeiner Kallweit /* Force memory writes to complete before releasing descriptor */ 381925e992a4SHeiner Kallweit dma_wmb(); 3820e2e5fb8dSHeiner Kallweit WRITE_ONCE(desc->opts1, cpu_to_le32(DescOwn | eor | R8169_RX_BUF_SIZE)); 382125e992a4SHeiner Kallweit } 382225e992a4SHeiner Kallweit 382332879f00SHeiner Kallweit static struct page *rtl8169_alloc_rx_data(struct rtl8169_private *tp, 382425e992a4SHeiner Kallweit struct RxDesc *desc) 382525e992a4SHeiner Kallweit { 382625e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 382725e992a4SHeiner Kallweit int node = dev_to_node(d); 382832879f00SHeiner Kallweit dma_addr_t mapping; 382932879f00SHeiner Kallweit struct page *data; 383025e992a4SHeiner Kallweit 383132879f00SHeiner Kallweit data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); 383225e992a4SHeiner Kallweit if (!data) 383325e992a4SHeiner Kallweit return NULL; 383425e992a4SHeiner Kallweit 383532879f00SHeiner Kallweit mapping = dma_map_page(d, data, 0, R8169_RX_BUF_SIZE, DMA_FROM_DEVICE); 383625e992a4SHeiner Kallweit if (unlikely(dma_mapping_error(d, mapping))) { 383793882c6fSHeiner Kallweit netdev_err(tp->dev, "Failed to map RX DMA!\n"); 383832879f00SHeiner Kallweit __free_pages(data, get_order(R8169_RX_BUF_SIZE)); 383932879f00SHeiner Kallweit return NULL; 384025e992a4SHeiner Kallweit } 384125e992a4SHeiner Kallweit 384225e992a4SHeiner Kallweit desc->addr = cpu_to_le64(mapping); 384325e992a4SHeiner Kallweit rtl8169_mark_to_asic(desc); 384425e992a4SHeiner Kallweit 384532879f00SHeiner Kallweit return data; 384625e992a4SHeiner Kallweit } 384725e992a4SHeiner Kallweit 384825e992a4SHeiner Kallweit static void rtl8169_rx_clear(struct rtl8169_private *tp) 384925e992a4SHeiner Kallweit { 385025e992a4SHeiner Kallweit unsigned int i; 385125e992a4SHeiner Kallweit 3852eb2e7f09SHeiner Kallweit for (i = 0; i < NUM_RX_DESC && tp->Rx_databuff[i]; i++) { 3853eb2e7f09SHeiner Kallweit dma_unmap_page(tp_to_dev(tp), 3854eb2e7f09SHeiner Kallweit le64_to_cpu(tp->RxDescArray[i].addr), 3855eb2e7f09SHeiner Kallweit R8169_RX_BUF_SIZE, DMA_FROM_DEVICE); 3856eb2e7f09SHeiner Kallweit __free_pages(tp->Rx_databuff[i], get_order(R8169_RX_BUF_SIZE)); 3857eb2e7f09SHeiner Kallweit tp->Rx_databuff[i] = NULL; 38589d3679feSHeiner Kallweit tp->RxDescArray[i].addr = 0; 38599d3679feSHeiner Kallweit tp->RxDescArray[i].opts1 = 0; 386025e992a4SHeiner Kallweit } 386125e992a4SHeiner Kallweit } 386225e992a4SHeiner Kallweit 386325e992a4SHeiner Kallweit static int rtl8169_rx_fill(struct rtl8169_private *tp) 386425e992a4SHeiner Kallweit { 386525e992a4SHeiner Kallweit unsigned int i; 386625e992a4SHeiner Kallweit 386725e992a4SHeiner Kallweit for (i = 0; i < NUM_RX_DESC; i++) { 386832879f00SHeiner Kallweit struct page *data; 386925e992a4SHeiner Kallweit 387025e992a4SHeiner Kallweit data = rtl8169_alloc_rx_data(tp, tp->RxDescArray + i); 387125e992a4SHeiner Kallweit if (!data) { 3872e4b5c7a5SHeiner Kallweit rtl8169_rx_clear(tp); 3873e4b5c7a5SHeiner Kallweit return -ENOMEM; 387425e992a4SHeiner Kallweit } 387525e992a4SHeiner Kallweit tp->Rx_databuff[i] = data; 387625e992a4SHeiner Kallweit } 387725e992a4SHeiner Kallweit 38782ac1fa43SHeiner Kallweit /* mark as last descriptor in the ring */ 38792ac1fa43SHeiner Kallweit tp->RxDescArray[NUM_RX_DESC - 1].opts1 |= cpu_to_le32(RingEnd); 388025e992a4SHeiner Kallweit 3881e4b5c7a5SHeiner Kallweit return 0; 388225e992a4SHeiner Kallweit } 388325e992a4SHeiner Kallweit 388425e992a4SHeiner Kallweit static int rtl8169_init_ring(struct rtl8169_private *tp) 388525e992a4SHeiner Kallweit { 388625e992a4SHeiner Kallweit rtl8169_init_ring_indexes(tp); 388725e992a4SHeiner Kallweit 388825e992a4SHeiner Kallweit memset(tp->tx_skb, 0, sizeof(tp->tx_skb)); 388925e992a4SHeiner Kallweit memset(tp->Rx_databuff, 0, sizeof(tp->Rx_databuff)); 389025e992a4SHeiner Kallweit 389125e992a4SHeiner Kallweit return rtl8169_rx_fill(tp); 389225e992a4SHeiner Kallweit } 389325e992a4SHeiner Kallweit 389422d352c5SHeiner Kallweit static void rtl8169_unmap_tx_skb(struct rtl8169_private *tp, unsigned int entry) 389525e992a4SHeiner Kallweit { 389622d352c5SHeiner Kallweit struct ring_info *tx_skb = tp->tx_skb + entry; 389722d352c5SHeiner Kallweit struct TxDesc *desc = tp->TxDescArray + entry; 389825e992a4SHeiner Kallweit 389922d352c5SHeiner Kallweit dma_unmap_single(tp_to_dev(tp), le64_to_cpu(desc->addr), tx_skb->len, 390022d352c5SHeiner Kallweit DMA_TO_DEVICE); 39016a41f2b2SHeiner Kallweit memset(desc, 0, sizeof(*desc)); 39026a41f2b2SHeiner Kallweit memset(tx_skb, 0, sizeof(*tx_skb)); 390325e992a4SHeiner Kallweit } 390425e992a4SHeiner Kallweit 390525e992a4SHeiner Kallweit static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, 390625e992a4SHeiner Kallweit unsigned int n) 390725e992a4SHeiner Kallweit { 390825e992a4SHeiner Kallweit unsigned int i; 390925e992a4SHeiner Kallweit 391025e992a4SHeiner Kallweit for (i = 0; i < n; i++) { 391125e992a4SHeiner Kallweit unsigned int entry = (start + i) % NUM_TX_DESC; 391225e992a4SHeiner Kallweit struct ring_info *tx_skb = tp->tx_skb + entry; 391325e992a4SHeiner Kallweit unsigned int len = tx_skb->len; 391425e992a4SHeiner Kallweit 391525e992a4SHeiner Kallweit if (len) { 391625e992a4SHeiner Kallweit struct sk_buff *skb = tx_skb->skb; 391725e992a4SHeiner Kallweit 391822d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 39196a41f2b2SHeiner Kallweit if (skb) 392025e992a4SHeiner Kallweit dev_consume_skb_any(skb); 392125e992a4SHeiner Kallweit } 392225e992a4SHeiner Kallweit } 392325e992a4SHeiner Kallweit } 392425e992a4SHeiner Kallweit 392525e992a4SHeiner Kallweit static void rtl8169_tx_clear(struct rtl8169_private *tp) 392625e992a4SHeiner Kallweit { 392725e992a4SHeiner Kallweit rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); 392825e992a4SHeiner Kallweit netdev_reset_queue(tp->dev); 392925e992a4SHeiner Kallweit } 393025e992a4SHeiner Kallweit 393112006848SHeiner Kallweit static void rtl8169_hw_reset(struct rtl8169_private *tp, bool going_down) 3932bac75d85SHeiner Kallweit { 3933bac75d85SHeiner Kallweit /* Give a racing hard_start_xmit a few cycles to complete. */ 3934bac75d85SHeiner Kallweit synchronize_rcu(); 3935bac75d85SHeiner Kallweit 3936bac75d85SHeiner Kallweit /* Disable interrupts */ 3937bac75d85SHeiner Kallweit rtl8169_irq_mask_and_ack(tp); 3938bac75d85SHeiner Kallweit 3939bac75d85SHeiner Kallweit rtl_rx_close(tp); 3940bac75d85SHeiner Kallweit 394112006848SHeiner Kallweit if (going_down && tp->dev->wol_enabled) 394212006848SHeiner Kallweit goto no_reset; 394312006848SHeiner Kallweit 3944bac75d85SHeiner Kallweit switch (tp->mac_version) { 3945bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 3946bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 3947bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 3948bac75d85SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_npq_cond, 20, 2000); 3949bac75d85SHeiner Kallweit break; 3950bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38: 3951bac75d85SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); 3952bac75d85SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); 3953bac75d85SHeiner Kallweit break; 3954bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61: 3955bac75d85SHeiner Kallweit rtl_enable_rxdvgate(tp); 3956bac75d85SHeiner Kallweit fsleep(2000); 3957bac75d85SHeiner Kallweit break; 3958bac75d85SHeiner Kallweit default: 3959bac75d85SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); 3960bac75d85SHeiner Kallweit fsleep(100); 3961bac75d85SHeiner Kallweit break; 3962bac75d85SHeiner Kallweit } 3963bac75d85SHeiner Kallweit 3964bac75d85SHeiner Kallweit rtl_hw_reset(tp); 396512006848SHeiner Kallweit no_reset: 3966bac75d85SHeiner Kallweit rtl8169_tx_clear(tp); 3967bac75d85SHeiner Kallweit rtl8169_init_ring_indexes(tp); 3968bac75d85SHeiner Kallweit } 3969bac75d85SHeiner Kallweit 397025e992a4SHeiner Kallweit static void rtl_reset_work(struct rtl8169_private *tp) 397125e992a4SHeiner Kallweit { 397225e992a4SHeiner Kallweit struct net_device *dev = tp->dev; 397325e992a4SHeiner Kallweit int i; 397425e992a4SHeiner Kallweit 397525e992a4SHeiner Kallweit napi_disable(&tp->napi); 397625e992a4SHeiner Kallweit netif_stop_queue(dev); 397725e992a4SHeiner Kallweit 397812006848SHeiner Kallweit rtl8169_hw_reset(tp, false); 397925e992a4SHeiner Kallweit 398025e992a4SHeiner Kallweit for (i = 0; i < NUM_RX_DESC; i++) 398125e992a4SHeiner Kallweit rtl8169_mark_to_asic(tp->RxDescArray + i); 398225e992a4SHeiner Kallweit 398325e992a4SHeiner Kallweit napi_enable(&tp->napi); 398425e992a4SHeiner Kallweit rtl_hw_start(tp); 398525e992a4SHeiner Kallweit netif_wake_queue(dev); 398625e992a4SHeiner Kallweit } 398725e992a4SHeiner Kallweit 39880290bd29SMichael S. Tsirkin static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue) 398925e992a4SHeiner Kallweit { 399025e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 399125e992a4SHeiner Kallweit 399225e992a4SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 399325e992a4SHeiner Kallweit } 399425e992a4SHeiner Kallweit 3995b8447abcSHeiner Kallweit static int rtl8169_tx_map(struct rtl8169_private *tp, const u32 *opts, u32 len, 3996b8447abcSHeiner Kallweit void *addr, unsigned int entry, bool desc_own) 399725e992a4SHeiner Kallweit { 3998b8447abcSHeiner Kallweit struct TxDesc *txd = tp->TxDescArray + entry; 3999b8447abcSHeiner Kallweit struct device *d = tp_to_dev(tp); 4000b8447abcSHeiner Kallweit dma_addr_t mapping; 4001b8447abcSHeiner Kallweit u32 opts1; 4002b8447abcSHeiner Kallweit int ret; 400325e992a4SHeiner Kallweit 4004b8447abcSHeiner Kallweit mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE); 4005b8447abcSHeiner Kallweit ret = dma_mapping_error(d, mapping); 4006b8447abcSHeiner Kallweit if (unlikely(ret)) { 4007b8447abcSHeiner Kallweit if (net_ratelimit()) 400893882c6fSHeiner Kallweit netdev_err(tp->dev, "Failed to map TX data!\n"); 4009b8447abcSHeiner Kallweit return ret; 4010b8447abcSHeiner Kallweit } 4011b8447abcSHeiner Kallweit 4012b8447abcSHeiner Kallweit txd->addr = cpu_to_le64(mapping); 4013b8447abcSHeiner Kallweit txd->opts2 = cpu_to_le32(opts[1]); 4014b8447abcSHeiner Kallweit 4015b8447abcSHeiner Kallweit opts1 = opts[0] | len; 401625e992a4SHeiner Kallweit if (entry == NUM_TX_DESC - 1) 4017b8447abcSHeiner Kallweit opts1 |= RingEnd; 4018b8447abcSHeiner Kallweit if (desc_own) 4019b8447abcSHeiner Kallweit opts1 |= DescOwn; 4020b8447abcSHeiner Kallweit txd->opts1 = cpu_to_le32(opts1); 402125e992a4SHeiner Kallweit 4022b8447abcSHeiner Kallweit tp->tx_skb[entry].len = len; 4023b8447abcSHeiner Kallweit 4024b8447abcSHeiner Kallweit return 0; 402525e992a4SHeiner Kallweit } 402625e992a4SHeiner Kallweit 402725e992a4SHeiner Kallweit static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, 4028b8447abcSHeiner Kallweit const u32 *opts, unsigned int entry) 402925e992a4SHeiner Kallweit { 403025e992a4SHeiner Kallweit struct skb_shared_info *info = skb_shinfo(skb); 4031b8447abcSHeiner Kallweit unsigned int cur_frag; 403225e992a4SHeiner Kallweit 403325e992a4SHeiner Kallweit for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { 403425e992a4SHeiner Kallweit const skb_frag_t *frag = info->frags + cur_frag; 4035b8447abcSHeiner Kallweit void *addr = skb_frag_address(frag); 4036b8447abcSHeiner Kallweit u32 len = skb_frag_size(frag); 403725e992a4SHeiner Kallweit 403825e992a4SHeiner Kallweit entry = (entry + 1) % NUM_TX_DESC; 403925e992a4SHeiner Kallweit 4040b8447abcSHeiner Kallweit if (unlikely(rtl8169_tx_map(tp, opts, len, addr, entry, true))) 404125e992a4SHeiner Kallweit goto err_out; 404225e992a4SHeiner Kallweit } 404325e992a4SHeiner Kallweit 40449020845fSHeiner Kallweit return 0; 404525e992a4SHeiner Kallweit 404625e992a4SHeiner Kallweit err_out: 404725e992a4SHeiner Kallweit rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag); 404825e992a4SHeiner Kallweit return -EIO; 404925e992a4SHeiner Kallweit } 405025e992a4SHeiner Kallweit 405125e992a4SHeiner Kallweit static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) 405225e992a4SHeiner Kallweit { 405325e992a4SHeiner Kallweit return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; 405425e992a4SHeiner Kallweit } 405525e992a4SHeiner Kallweit 405625e992a4SHeiner Kallweit static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts) 405725e992a4SHeiner Kallweit { 405825e992a4SHeiner Kallweit u32 mss = skb_shinfo(skb)->gso_size; 405925e992a4SHeiner Kallweit 406025e992a4SHeiner Kallweit if (mss) { 406125e992a4SHeiner Kallweit opts[0] |= TD_LSO; 40624abc3c04SHeiner Kallweit opts[0] |= mss << TD0_MSS_SHIFT; 406325e992a4SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 406425e992a4SHeiner Kallweit const struct iphdr *ip = ip_hdr(skb); 406525e992a4SHeiner Kallweit 406625e992a4SHeiner Kallweit if (ip->protocol == IPPROTO_TCP) 406725e992a4SHeiner Kallweit opts[0] |= TD0_IP_CS | TD0_TCP_CS; 406825e992a4SHeiner Kallweit else if (ip->protocol == IPPROTO_UDP) 406925e992a4SHeiner Kallweit opts[0] |= TD0_IP_CS | TD0_UDP_CS; 407025e992a4SHeiner Kallweit else 407125e992a4SHeiner Kallweit WARN_ON_ONCE(1); 407225e992a4SHeiner Kallweit } 407325e992a4SHeiner Kallweit } 407425e992a4SHeiner Kallweit 407525e992a4SHeiner Kallweit static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, 407625e992a4SHeiner Kallweit struct sk_buff *skb, u32 *opts) 407725e992a4SHeiner Kallweit { 407825e992a4SHeiner Kallweit u32 transport_offset = (u32)skb_transport_offset(skb); 40790623b98bSHeiner Kallweit struct skb_shared_info *shinfo = skb_shinfo(skb); 40800623b98bSHeiner Kallweit u32 mss = shinfo->gso_size; 408125e992a4SHeiner Kallweit 408225e992a4SHeiner Kallweit if (mss) { 40830623b98bSHeiner Kallweit if (shinfo->gso_type & SKB_GSO_TCPV4) { 408425e992a4SHeiner Kallweit opts[0] |= TD1_GTSENV4; 40850623b98bSHeiner Kallweit } else if (shinfo->gso_type & SKB_GSO_TCPV6) { 40868b19c68cSHeiner Kallweit if (skb_cow_head(skb, 0)) 408725e992a4SHeiner Kallweit return false; 408825e992a4SHeiner Kallweit 40898b19c68cSHeiner Kallweit tcp_v6_gso_csum_prep(skb); 409025e992a4SHeiner Kallweit opts[0] |= TD1_GTSENV6; 40910623b98bSHeiner Kallweit } else { 409225e992a4SHeiner Kallweit WARN_ON_ONCE(1); 409325e992a4SHeiner Kallweit } 409425e992a4SHeiner Kallweit 409525e992a4SHeiner Kallweit opts[0] |= transport_offset << GTTCPHO_SHIFT; 40964abc3c04SHeiner Kallweit opts[1] |= mss << TD1_MSS_SHIFT; 409725e992a4SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 409825e992a4SHeiner Kallweit u8 ip_protocol; 409925e992a4SHeiner Kallweit 410025e992a4SHeiner Kallweit switch (vlan_get_protocol(skb)) { 410125e992a4SHeiner Kallweit case htons(ETH_P_IP): 410225e992a4SHeiner Kallweit opts[1] |= TD1_IPv4_CS; 410325e992a4SHeiner Kallweit ip_protocol = ip_hdr(skb)->protocol; 410425e992a4SHeiner Kallweit break; 410525e992a4SHeiner Kallweit 410625e992a4SHeiner Kallweit case htons(ETH_P_IPV6): 410725e992a4SHeiner Kallweit opts[1] |= TD1_IPv6_CS; 410825e992a4SHeiner Kallweit ip_protocol = ipv6_hdr(skb)->nexthdr; 410925e992a4SHeiner Kallweit break; 411025e992a4SHeiner Kallweit 411125e992a4SHeiner Kallweit default: 411225e992a4SHeiner Kallweit ip_protocol = IPPROTO_RAW; 411325e992a4SHeiner Kallweit break; 411425e992a4SHeiner Kallweit } 411525e992a4SHeiner Kallweit 411625e992a4SHeiner Kallweit if (ip_protocol == IPPROTO_TCP) 411725e992a4SHeiner Kallweit opts[1] |= TD1_TCP_CS; 411825e992a4SHeiner Kallweit else if (ip_protocol == IPPROTO_UDP) 411925e992a4SHeiner Kallweit opts[1] |= TD1_UDP_CS; 412025e992a4SHeiner Kallweit else 412125e992a4SHeiner Kallweit WARN_ON_ONCE(1); 412225e992a4SHeiner Kallweit 412325e992a4SHeiner Kallweit opts[1] |= transport_offset << TCPHO_SHIFT; 412425e992a4SHeiner Kallweit } else { 412525e992a4SHeiner Kallweit if (unlikely(rtl_test_hw_pad_bug(tp, skb))) 412625e992a4SHeiner Kallweit return !eth_skb_pad(skb); 412725e992a4SHeiner Kallweit } 412825e992a4SHeiner Kallweit 412925e992a4SHeiner Kallweit return true; 413025e992a4SHeiner Kallweit } 413125e992a4SHeiner Kallweit 413225e992a4SHeiner Kallweit static bool rtl_tx_slots_avail(struct rtl8169_private *tp, 413325e992a4SHeiner Kallweit unsigned int nr_frags) 413425e992a4SHeiner Kallweit { 413525e992a4SHeiner Kallweit unsigned int slots_avail = tp->dirty_tx + NUM_TX_DESC - tp->cur_tx; 413625e992a4SHeiner Kallweit 413725e992a4SHeiner Kallweit /* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ 413825e992a4SHeiner Kallweit return slots_avail > nr_frags; 413925e992a4SHeiner Kallweit } 414025e992a4SHeiner Kallweit 414125e992a4SHeiner Kallweit /* Versions RTL8102e and from RTL8168c onwards support csum_v2 */ 414225e992a4SHeiner Kallweit static bool rtl_chip_supports_csum_v2(struct rtl8169_private *tp) 414325e992a4SHeiner Kallweit { 414425e992a4SHeiner Kallweit switch (tp->mac_version) { 414525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 414625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17: 414725e992a4SHeiner Kallweit return false; 414825e992a4SHeiner Kallweit default: 414925e992a4SHeiner Kallweit return true; 415025e992a4SHeiner Kallweit } 415125e992a4SHeiner Kallweit } 415225e992a4SHeiner Kallweit 4153f1bce4adSHeiner Kallweit static void rtl8169_doorbell(struct rtl8169_private *tp) 4154f1bce4adSHeiner Kallweit { 4155f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 4156f1bce4adSHeiner Kallweit RTL_W16(tp, TxPoll_8125, BIT(0)); 4157f1bce4adSHeiner Kallweit else 4158f1bce4adSHeiner Kallweit RTL_W8(tp, TxPoll, NPQ); 4159f1bce4adSHeiner Kallweit } 4160f1bce4adSHeiner Kallweit 416125e992a4SHeiner Kallweit static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, 416225e992a4SHeiner Kallweit struct net_device *dev) 416325e992a4SHeiner Kallweit { 41649020845fSHeiner Kallweit unsigned int frags = skb_shinfo(skb)->nr_frags; 416525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 416625e992a4SHeiner Kallweit unsigned int entry = tp->cur_tx % NUM_TX_DESC; 4167b8447abcSHeiner Kallweit struct TxDesc *txd_first, *txd_last; 4168b8447abcSHeiner Kallweit bool stop_queue, door_bell; 4169b8447abcSHeiner Kallweit u32 opts[2]; 4170b8447abcSHeiner Kallweit 4171b8447abcSHeiner Kallweit txd_first = tp->TxDescArray + entry; 417225e992a4SHeiner Kallweit 41739020845fSHeiner Kallweit if (unlikely(!rtl_tx_slots_avail(tp, frags))) { 417493882c6fSHeiner Kallweit if (net_ratelimit()) 417593882c6fSHeiner Kallweit netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); 417625e992a4SHeiner Kallweit goto err_stop_0; 417725e992a4SHeiner Kallweit } 417825e992a4SHeiner Kallweit 4179b8447abcSHeiner Kallweit if (unlikely(le32_to_cpu(txd_first->opts1) & DescOwn)) 418025e992a4SHeiner Kallweit goto err_stop_0; 418125e992a4SHeiner Kallweit 4182355f948aSHeiner Kallweit opts[1] = rtl8169_tx_vlan_tag(skb); 4183b8447abcSHeiner Kallweit opts[0] = 0; 418425e992a4SHeiner Kallweit 4185b8447abcSHeiner Kallweit if (!rtl_chip_supports_csum_v2(tp)) 418625e992a4SHeiner Kallweit rtl8169_tso_csum_v1(skb, opts); 4187b8447abcSHeiner Kallweit else if (!rtl8169_tso_csum_v2(tp, skb, opts)) 418825e992a4SHeiner Kallweit goto err_dma_0; 418925e992a4SHeiner Kallweit 4190b8447abcSHeiner Kallweit if (unlikely(rtl8169_tx_map(tp, opts, skb_headlen(skb), skb->data, 4191b8447abcSHeiner Kallweit entry, false))) 4192b8447abcSHeiner Kallweit goto err_dma_0; 419325e992a4SHeiner Kallweit 4194b8447abcSHeiner Kallweit if (frags) { 4195b8447abcSHeiner Kallweit if (rtl8169_xmit_frags(tp, skb, opts, entry)) 41969020845fSHeiner Kallweit goto err_dma_1; 4197b8447abcSHeiner Kallweit entry = (entry + frags) % NUM_TX_DESC; 419825e992a4SHeiner Kallweit } 419925e992a4SHeiner Kallweit 4200b8447abcSHeiner Kallweit txd_last = tp->TxDescArray + entry; 4201b8447abcSHeiner Kallweit txd_last->opts1 |= cpu_to_le32(LastFrag); 4202b8447abcSHeiner Kallweit tp->tx_skb[entry].skb = skb; 420325e992a4SHeiner Kallweit 420425e992a4SHeiner Kallweit skb_tx_timestamp(skb); 420525e992a4SHeiner Kallweit 420625e992a4SHeiner Kallweit /* Force memory writes to complete before releasing descriptor */ 420725e992a4SHeiner Kallweit dma_wmb(); 420825e992a4SHeiner Kallweit 4209ef143585SHeiner Kallweit door_bell = __netdev_sent_queue(dev, skb->len, netdev_xmit_more()); 4210ef143585SHeiner Kallweit 4211b8447abcSHeiner Kallweit txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag); 421225e992a4SHeiner Kallweit 4213794867eeSHeiner Kallweit /* rtl_tx needs to see descriptor changes before updated tp->cur_tx */ 4214794867eeSHeiner Kallweit smp_wmb(); 421525e992a4SHeiner Kallweit 421625e992a4SHeiner Kallweit tp->cur_tx += frags + 1; 421725e992a4SHeiner Kallweit 4218ef143585SHeiner Kallweit stop_queue = !rtl_tx_slots_avail(tp, MAX_SKB_FRAGS); 4219ef143585SHeiner Kallweit if (unlikely(stop_queue)) { 422025e992a4SHeiner Kallweit /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must 422125e992a4SHeiner Kallweit * not miss a ring update when it notices a stopped queue. 422225e992a4SHeiner Kallweit */ 422325e992a4SHeiner Kallweit smp_wmb(); 422425e992a4SHeiner Kallweit netif_stop_queue(dev); 42254773f9bdSHeiner Kallweit door_bell = true; 4226ef143585SHeiner Kallweit } 4227ef143585SHeiner Kallweit 4228ef143585SHeiner Kallweit if (door_bell) 4229f1bce4adSHeiner Kallweit rtl8169_doorbell(tp); 4230ef143585SHeiner Kallweit 4231ef143585SHeiner Kallweit if (unlikely(stop_queue)) { 423225e992a4SHeiner Kallweit /* Sync with rtl_tx: 423325e992a4SHeiner Kallweit * - publish queue status and cur_tx ring index (write barrier) 423425e992a4SHeiner Kallweit * - refresh dirty_tx ring index (read barrier). 423525e992a4SHeiner Kallweit * May the current thread have a pessimistic view of the ring 423625e992a4SHeiner Kallweit * status and forget to wake up queue, a racing rtl_tx thread 423725e992a4SHeiner Kallweit * can't. 423825e992a4SHeiner Kallweit */ 423925e992a4SHeiner Kallweit smp_mb(); 424025e992a4SHeiner Kallweit if (rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) 424125e992a4SHeiner Kallweit netif_start_queue(dev); 424225e992a4SHeiner Kallweit } 424325e992a4SHeiner Kallweit 424425e992a4SHeiner Kallweit return NETDEV_TX_OK; 424525e992a4SHeiner Kallweit 424625e992a4SHeiner Kallweit err_dma_1: 424722d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 424825e992a4SHeiner Kallweit err_dma_0: 424925e992a4SHeiner Kallweit dev_kfree_skb_any(skb); 425025e992a4SHeiner Kallweit dev->stats.tx_dropped++; 425125e992a4SHeiner Kallweit return NETDEV_TX_OK; 425225e992a4SHeiner Kallweit 425325e992a4SHeiner Kallweit err_stop_0: 425425e992a4SHeiner Kallweit netif_stop_queue(dev); 425525e992a4SHeiner Kallweit dev->stats.tx_dropped++; 425625e992a4SHeiner Kallweit return NETDEV_TX_BUSY; 425725e992a4SHeiner Kallweit } 425825e992a4SHeiner Kallweit 4259773235f4SHeiner Kallweit static unsigned int rtl_last_frag_len(struct sk_buff *skb) 4260773235f4SHeiner Kallweit { 4261773235f4SHeiner Kallweit struct skb_shared_info *info = skb_shinfo(skb); 4262773235f4SHeiner Kallweit unsigned int nr_frags = info->nr_frags; 4263773235f4SHeiner Kallweit 4264773235f4SHeiner Kallweit if (!nr_frags) 4265773235f4SHeiner Kallweit return UINT_MAX; 4266773235f4SHeiner Kallweit 4267773235f4SHeiner Kallweit return skb_frag_size(info->frags + nr_frags - 1); 4268773235f4SHeiner Kallweit } 4269773235f4SHeiner Kallweit 4270773235f4SHeiner Kallweit /* Workaround for hw issues with TSO on RTL8168evl */ 4271773235f4SHeiner Kallweit static netdev_features_t rtl8168evl_fix_tso(struct sk_buff *skb, 4272773235f4SHeiner Kallweit netdev_features_t features) 4273773235f4SHeiner Kallweit { 4274773235f4SHeiner Kallweit /* IPv4 header has options field */ 4275773235f4SHeiner Kallweit if (vlan_get_protocol(skb) == htons(ETH_P_IP) && 4276773235f4SHeiner Kallweit ip_hdrlen(skb) > sizeof(struct iphdr)) 4277773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4278773235f4SHeiner Kallweit 4279773235f4SHeiner Kallweit /* IPv4 TCP header has options field */ 4280773235f4SHeiner Kallweit else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 && 4281773235f4SHeiner Kallweit tcp_hdrlen(skb) > sizeof(struct tcphdr)) 4282773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4283773235f4SHeiner Kallweit 4284773235f4SHeiner Kallweit else if (rtl_last_frag_len(skb) <= 6) 4285773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4286773235f4SHeiner Kallweit 4287773235f4SHeiner Kallweit return features; 4288773235f4SHeiner Kallweit } 4289773235f4SHeiner Kallweit 4290e64e0c89SHeiner Kallweit static netdev_features_t rtl8169_features_check(struct sk_buff *skb, 4291e64e0c89SHeiner Kallweit struct net_device *dev, 4292e64e0c89SHeiner Kallweit netdev_features_t features) 4293e64e0c89SHeiner Kallweit { 4294e64e0c89SHeiner Kallweit int transport_offset = skb_transport_offset(skb); 4295e64e0c89SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 4296e64e0c89SHeiner Kallweit 4297e64e0c89SHeiner Kallweit if (skb_is_gso(skb)) { 4298773235f4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34) 4299773235f4SHeiner Kallweit features = rtl8168evl_fix_tso(skb, features); 4300773235f4SHeiner Kallweit 4301e64e0c89SHeiner Kallweit if (transport_offset > GTTCPHO_MAX && 4302e64e0c89SHeiner Kallweit rtl_chip_supports_csum_v2(tp)) 4303e64e0c89SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4304e64e0c89SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 4305e64e0c89SHeiner Kallweit if (skb->len < ETH_ZLEN) { 4306e64e0c89SHeiner Kallweit switch (tp->mac_version) { 4307e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_11: 4308e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 4309e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 4310e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_34: 4311e64e0c89SHeiner Kallweit features &= ~NETIF_F_CSUM_MASK; 4312e64e0c89SHeiner Kallweit break; 4313e64e0c89SHeiner Kallweit default: 4314e64e0c89SHeiner Kallweit break; 4315e64e0c89SHeiner Kallweit } 4316e64e0c89SHeiner Kallweit } 4317e64e0c89SHeiner Kallweit 4318e64e0c89SHeiner Kallweit if (transport_offset > TCPHO_MAX && 4319e64e0c89SHeiner Kallweit rtl_chip_supports_csum_v2(tp)) 4320e64e0c89SHeiner Kallweit features &= ~NETIF_F_CSUM_MASK; 4321e64e0c89SHeiner Kallweit } 4322e64e0c89SHeiner Kallweit 4323e64e0c89SHeiner Kallweit return vlan_features_check(skb, features); 4324e64e0c89SHeiner Kallweit } 4325e64e0c89SHeiner Kallweit 432625e992a4SHeiner Kallweit static void rtl8169_pcierr_interrupt(struct net_device *dev) 432725e992a4SHeiner Kallweit { 432825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 432925e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 43302864a883SHeiner Kallweit int pci_status_errs; 43312864a883SHeiner Kallweit u16 pci_cmd; 433225e992a4SHeiner Kallweit 433325e992a4SHeiner Kallweit pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); 433425e992a4SHeiner Kallweit 43352864a883SHeiner Kallweit pci_status_errs = pci_status_get_and_clear_errors(pdev); 43362864a883SHeiner Kallweit 433793882c6fSHeiner Kallweit if (net_ratelimit()) 433893882c6fSHeiner Kallweit netdev_err(dev, "PCI error (cmd = 0x%04x, status_errs = 0x%04x)\n", 43392864a883SHeiner Kallweit pci_cmd, pci_status_errs); 434025e992a4SHeiner Kallweit /* 434125e992a4SHeiner Kallweit * The recovery sequence below admits a very elaborated explanation: 434225e992a4SHeiner Kallweit * - it seems to work; 434325e992a4SHeiner Kallweit * - I did not see what else could be done; 434425e992a4SHeiner Kallweit * - it makes iop3xx happy. 434525e992a4SHeiner Kallweit * 434625e992a4SHeiner Kallweit * Feel free to adjust to your needs. 434725e992a4SHeiner Kallweit */ 434825e992a4SHeiner Kallweit if (pdev->broken_parity_status) 434925e992a4SHeiner Kallweit pci_cmd &= ~PCI_COMMAND_PARITY; 435025e992a4SHeiner Kallweit else 435125e992a4SHeiner Kallweit pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY; 435225e992a4SHeiner Kallweit 435325e992a4SHeiner Kallweit pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); 435425e992a4SHeiner Kallweit 435525e992a4SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 435625e992a4SHeiner Kallweit } 435725e992a4SHeiner Kallweit 435825e992a4SHeiner Kallweit static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, 435925e992a4SHeiner Kallweit int budget) 436025e992a4SHeiner Kallweit { 436125e992a4SHeiner Kallweit unsigned int dirty_tx, tx_left, bytes_compl = 0, pkts_compl = 0; 436225e992a4SHeiner Kallweit 436325e992a4SHeiner Kallweit dirty_tx = tp->dirty_tx; 436425e992a4SHeiner Kallweit smp_rmb(); 436525e992a4SHeiner Kallweit 4366a0e6650bSHeiner Kallweit for (tx_left = tp->cur_tx - dirty_tx; tx_left > 0; tx_left--) { 436725e992a4SHeiner Kallweit unsigned int entry = dirty_tx % NUM_TX_DESC; 436822d352c5SHeiner Kallweit struct sk_buff *skb = tp->tx_skb[entry].skb; 436925e992a4SHeiner Kallweit u32 status; 437025e992a4SHeiner Kallweit 437125e992a4SHeiner Kallweit status = le32_to_cpu(tp->TxDescArray[entry].opts1); 437225e992a4SHeiner Kallweit if (status & DescOwn) 437325e992a4SHeiner Kallweit break; 437425e992a4SHeiner Kallweit 437522d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 437622d352c5SHeiner Kallweit 43776a41f2b2SHeiner Kallweit if (skb) { 437825e992a4SHeiner Kallweit pkts_compl++; 43796a41f2b2SHeiner Kallweit bytes_compl += skb->len; 43806a41f2b2SHeiner Kallweit napi_consume_skb(skb, budget); 438125e992a4SHeiner Kallweit } 438225e992a4SHeiner Kallweit dirty_tx++; 438325e992a4SHeiner Kallweit } 438425e992a4SHeiner Kallweit 438525e992a4SHeiner Kallweit if (tp->dirty_tx != dirty_tx) { 438625e992a4SHeiner Kallweit netdev_completed_queue(dev, pkts_compl, bytes_compl); 438725e992a4SHeiner Kallweit 438825e992a4SHeiner Kallweit u64_stats_update_begin(&tp->tx_stats.syncp); 438925e992a4SHeiner Kallweit tp->tx_stats.packets += pkts_compl; 439025e992a4SHeiner Kallweit tp->tx_stats.bytes += bytes_compl; 439125e992a4SHeiner Kallweit u64_stats_update_end(&tp->tx_stats.syncp); 439225e992a4SHeiner Kallweit 439325e992a4SHeiner Kallweit tp->dirty_tx = dirty_tx; 439425e992a4SHeiner Kallweit /* Sync with rtl8169_start_xmit: 439525e992a4SHeiner Kallweit * - publish dirty_tx ring index (write barrier) 439625e992a4SHeiner Kallweit * - refresh cur_tx ring index and queue status (read barrier) 439725e992a4SHeiner Kallweit * May the current thread miss the stopped queue condition, 439825e992a4SHeiner Kallweit * a racing xmit thread can only have a right view of the 439925e992a4SHeiner Kallweit * ring status. 440025e992a4SHeiner Kallweit */ 440125e992a4SHeiner Kallweit smp_mb(); 440225e992a4SHeiner Kallweit if (netif_queue_stopped(dev) && 440325e992a4SHeiner Kallweit rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) { 440425e992a4SHeiner Kallweit netif_wake_queue(dev); 440525e992a4SHeiner Kallweit } 440625e992a4SHeiner Kallweit /* 440725e992a4SHeiner Kallweit * 8168 hack: TxPoll requests are lost when the Tx packets are 440825e992a4SHeiner Kallweit * too close. Let's kick an extra TxPoll request when a burst 440925e992a4SHeiner Kallweit * of start_xmit activity is detected (if it is not detected, 441025e992a4SHeiner Kallweit * it is slow enough). -- FR 441125e992a4SHeiner Kallweit */ 441225e992a4SHeiner Kallweit if (tp->cur_tx != dirty_tx) 4413f1bce4adSHeiner Kallweit rtl8169_doorbell(tp); 441425e992a4SHeiner Kallweit } 441525e992a4SHeiner Kallweit } 441625e992a4SHeiner Kallweit 441725e992a4SHeiner Kallweit static inline int rtl8169_fragmented_frame(u32 status) 441825e992a4SHeiner Kallweit { 441925e992a4SHeiner Kallweit return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); 442025e992a4SHeiner Kallweit } 442125e992a4SHeiner Kallweit 442225e992a4SHeiner Kallweit static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) 442325e992a4SHeiner Kallweit { 442425e992a4SHeiner Kallweit u32 status = opts1 & RxProtoMask; 442525e992a4SHeiner Kallweit 442625e992a4SHeiner Kallweit if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || 442725e992a4SHeiner Kallweit ((status == RxProtoUDP) && !(opts1 & UDPFail))) 442825e992a4SHeiner Kallweit skb->ip_summed = CHECKSUM_UNNECESSARY; 442925e992a4SHeiner Kallweit else 443025e992a4SHeiner Kallweit skb_checksum_none_assert(skb); 443125e992a4SHeiner Kallweit } 443225e992a4SHeiner Kallweit 443325e992a4SHeiner Kallweit static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget) 443425e992a4SHeiner Kallweit { 4435588c7e5cSHeiner Kallweit unsigned int cur_rx, rx_left, count; 4436588c7e5cSHeiner Kallweit struct device *d = tp_to_dev(tp); 443725e992a4SHeiner Kallweit 443825e992a4SHeiner Kallweit cur_rx = tp->cur_rx; 443925e992a4SHeiner Kallweit 444025e992a4SHeiner Kallweit for (rx_left = min(budget, NUM_RX_DESC); rx_left > 0; rx_left--, cur_rx++) { 4441588c7e5cSHeiner Kallweit unsigned int pkt_size, entry = cur_rx % NUM_RX_DESC; 444225e992a4SHeiner Kallweit struct RxDesc *desc = tp->RxDescArray + entry; 4443588c7e5cSHeiner Kallweit struct sk_buff *skb; 4444588c7e5cSHeiner Kallweit const void *rx_buf; 4445588c7e5cSHeiner Kallweit dma_addr_t addr; 444625e992a4SHeiner Kallweit u32 status; 444725e992a4SHeiner Kallweit 444825e992a4SHeiner Kallweit status = le32_to_cpu(desc->opts1); 444925e992a4SHeiner Kallweit if (status & DescOwn) 445025e992a4SHeiner Kallweit break; 445125e992a4SHeiner Kallweit 445225e992a4SHeiner Kallweit /* This barrier is needed to keep us from reading 445325e992a4SHeiner Kallweit * any other fields out of the Rx descriptor until 445425e992a4SHeiner Kallweit * we know the status of DescOwn 445525e992a4SHeiner Kallweit */ 445625e992a4SHeiner Kallweit dma_rmb(); 445725e992a4SHeiner Kallweit 445825e992a4SHeiner Kallweit if (unlikely(status & RxRES)) { 445993882c6fSHeiner Kallweit if (net_ratelimit()) 446093882c6fSHeiner Kallweit netdev_warn(dev, "Rx ERROR. status = %08x\n", 446125e992a4SHeiner Kallweit status); 446225e992a4SHeiner Kallweit dev->stats.rx_errors++; 446325e992a4SHeiner Kallweit if (status & (RxRWT | RxRUNT)) 446425e992a4SHeiner Kallweit dev->stats.rx_length_errors++; 446525e992a4SHeiner Kallweit if (status & RxCRC) 446625e992a4SHeiner Kallweit dev->stats.rx_crc_errors++; 446725e992a4SHeiner Kallweit 4468588c7e5cSHeiner Kallweit if (!(dev->features & NETIF_F_RXALL)) 4469588c7e5cSHeiner Kallweit goto release_descriptor; 4470588c7e5cSHeiner Kallweit else if (status & RxRWT || !(status & (RxRUNT | RxCRC))) 4471588c7e5cSHeiner Kallweit goto release_descriptor; 4472588c7e5cSHeiner Kallweit } 4473588c7e5cSHeiner Kallweit 4474fcd4e608SHeiner Kallweit pkt_size = status & GENMASK(13, 0); 447525e992a4SHeiner Kallweit if (likely(!(dev->features & NETIF_F_RXFCS))) 4476fcd4e608SHeiner Kallweit pkt_size -= ETH_FCS_LEN; 4477588c7e5cSHeiner Kallweit 4478588c7e5cSHeiner Kallweit /* The driver does not support incoming fragmented frames. 4479588c7e5cSHeiner Kallweit * They are seen as a symptom of over-mtu sized frames. 448025e992a4SHeiner Kallweit */ 448125e992a4SHeiner Kallweit if (unlikely(rtl8169_fragmented_frame(status))) { 448225e992a4SHeiner Kallweit dev->stats.rx_dropped++; 448325e992a4SHeiner Kallweit dev->stats.rx_length_errors++; 448425e992a4SHeiner Kallweit goto release_descriptor; 448525e992a4SHeiner Kallweit } 448625e992a4SHeiner Kallweit 4487fcd4e608SHeiner Kallweit skb = napi_alloc_skb(&tp->napi, pkt_size); 4488fcd4e608SHeiner Kallweit if (unlikely(!skb)) { 448925e992a4SHeiner Kallweit dev->stats.rx_dropped++; 449025e992a4SHeiner Kallweit goto release_descriptor; 449125e992a4SHeiner Kallweit } 449225e992a4SHeiner Kallweit 4493588c7e5cSHeiner Kallweit addr = le64_to_cpu(desc->addr); 4494588c7e5cSHeiner Kallweit rx_buf = page_address(tp->Rx_databuff[entry]); 4495588c7e5cSHeiner Kallweit 4496588c7e5cSHeiner Kallweit dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); 449732879f00SHeiner Kallweit prefetch(rx_buf); 449832879f00SHeiner Kallweit skb_copy_to_linear_data(skb, rx_buf, pkt_size); 4499fcd4e608SHeiner Kallweit skb->tail += pkt_size; 4500fcd4e608SHeiner Kallweit skb->len = pkt_size; 4501588c7e5cSHeiner Kallweit dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE); 4502d4ed7463SHeiner Kallweit 450325e992a4SHeiner Kallweit rtl8169_rx_csum(skb, status); 450425e992a4SHeiner Kallweit skb->protocol = eth_type_trans(skb, dev); 450525e992a4SHeiner Kallweit 450625e992a4SHeiner Kallweit rtl8169_rx_vlan_tag(desc, skb); 450725e992a4SHeiner Kallweit 450825e992a4SHeiner Kallweit if (skb->pkt_type == PACKET_MULTICAST) 450925e992a4SHeiner Kallweit dev->stats.multicast++; 451025e992a4SHeiner Kallweit 451125e992a4SHeiner Kallweit napi_gro_receive(&tp->napi, skb); 451225e992a4SHeiner Kallweit 451325e992a4SHeiner Kallweit u64_stats_update_begin(&tp->rx_stats.syncp); 451425e992a4SHeiner Kallweit tp->rx_stats.packets++; 451525e992a4SHeiner Kallweit tp->rx_stats.bytes += pkt_size; 451625e992a4SHeiner Kallweit u64_stats_update_end(&tp->rx_stats.syncp); 4517588c7e5cSHeiner Kallweit 451825e992a4SHeiner Kallweit release_descriptor: 451925e992a4SHeiner Kallweit rtl8169_mark_to_asic(desc); 452025e992a4SHeiner Kallweit } 452125e992a4SHeiner Kallweit 452225e992a4SHeiner Kallweit count = cur_rx - tp->cur_rx; 452325e992a4SHeiner Kallweit tp->cur_rx = cur_rx; 452425e992a4SHeiner Kallweit 452525e992a4SHeiner Kallweit return count; 452625e992a4SHeiner Kallweit } 452725e992a4SHeiner Kallweit 452825e992a4SHeiner Kallweit static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) 452925e992a4SHeiner Kallweit { 453025e992a4SHeiner Kallweit struct rtl8169_private *tp = dev_instance; 4531c1d532d2SHeiner Kallweit u32 status = rtl_get_events(tp); 453225e992a4SHeiner Kallweit 4533c1d532d2SHeiner Kallweit if (!tp->irq_enabled || (status & 0xffff) == 0xffff || 4534c1d532d2SHeiner Kallweit !(status & tp->irq_mask)) 453525e992a4SHeiner Kallweit return IRQ_NONE; 453625e992a4SHeiner Kallweit 453725e992a4SHeiner Kallweit if (unlikely(status & SYSErr)) { 453825e992a4SHeiner Kallweit rtl8169_pcierr_interrupt(tp->dev); 453925e992a4SHeiner Kallweit goto out; 454025e992a4SHeiner Kallweit } 454125e992a4SHeiner Kallweit 454225e992a4SHeiner Kallweit if (status & LinkChg) 454325e992a4SHeiner Kallweit phy_mac_interrupt(tp->phydev); 454425e992a4SHeiner Kallweit 454525e992a4SHeiner Kallweit if (unlikely(status & RxFIFOOver && 454625e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_11)) { 454725e992a4SHeiner Kallweit netif_stop_queue(tp->dev); 45486b02e407SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 454925e992a4SHeiner Kallweit } 455025e992a4SHeiner Kallweit 455125e992a4SHeiner Kallweit rtl_irq_disable(tp); 455225e992a4SHeiner Kallweit napi_schedule_irqoff(&tp->napi); 455325e992a4SHeiner Kallweit out: 455425e992a4SHeiner Kallweit rtl_ack_events(tp, status); 455525e992a4SHeiner Kallweit 455625e992a4SHeiner Kallweit return IRQ_HANDLED; 455725e992a4SHeiner Kallweit } 455825e992a4SHeiner Kallweit 455925e992a4SHeiner Kallweit static void rtl_task(struct work_struct *work) 456025e992a4SHeiner Kallweit { 456125e992a4SHeiner Kallweit struct rtl8169_private *tp = 456225e992a4SHeiner Kallweit container_of(work, struct rtl8169_private, wk.work); 456325e992a4SHeiner Kallweit 456425e992a4SHeiner Kallweit rtl_lock_work(tp); 456525e992a4SHeiner Kallweit 4566e18958c6SHeiner Kallweit if (!netif_running(tp->dev) || 456725e992a4SHeiner Kallweit !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) 456825e992a4SHeiner Kallweit goto out_unlock; 456925e992a4SHeiner Kallweit 4570e18958c6SHeiner Kallweit if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) 4571e18958c6SHeiner Kallweit rtl_reset_work(tp); 457225e992a4SHeiner Kallweit out_unlock: 457325e992a4SHeiner Kallweit rtl_unlock_work(tp); 457425e992a4SHeiner Kallweit } 457525e992a4SHeiner Kallweit 457625e992a4SHeiner Kallweit static int rtl8169_poll(struct napi_struct *napi, int budget) 457725e992a4SHeiner Kallweit { 457825e992a4SHeiner Kallweit struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); 457925e992a4SHeiner Kallweit struct net_device *dev = tp->dev; 458025e992a4SHeiner Kallweit int work_done; 458125e992a4SHeiner Kallweit 458225e992a4SHeiner Kallweit work_done = rtl_rx(dev, tp, (u32) budget); 458325e992a4SHeiner Kallweit 458425e992a4SHeiner Kallweit rtl_tx(dev, tp, budget); 458525e992a4SHeiner Kallweit 458625e992a4SHeiner Kallweit if (work_done < budget) { 458725e992a4SHeiner Kallweit napi_complete_done(napi, work_done); 458825e992a4SHeiner Kallweit rtl_irq_enable(tp); 458925e992a4SHeiner Kallweit } 459025e992a4SHeiner Kallweit 459125e992a4SHeiner Kallweit return work_done; 459225e992a4SHeiner Kallweit } 459325e992a4SHeiner Kallweit 459425e992a4SHeiner Kallweit static void r8169_phylink_handler(struct net_device *ndev) 459525e992a4SHeiner Kallweit { 459625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(ndev); 459725e992a4SHeiner Kallweit 459825e992a4SHeiner Kallweit if (netif_carrier_ok(ndev)) { 459925e992a4SHeiner Kallweit rtl_link_chg_patch(tp); 460025e992a4SHeiner Kallweit pm_request_resume(&tp->pci_dev->dev); 460125e992a4SHeiner Kallweit } else { 460225e992a4SHeiner Kallweit pm_runtime_idle(&tp->pci_dev->dev); 460325e992a4SHeiner Kallweit } 460425e992a4SHeiner Kallweit 460525e992a4SHeiner Kallweit if (net_ratelimit()) 460625e992a4SHeiner Kallweit phy_print_status(tp->phydev); 460725e992a4SHeiner Kallweit } 460825e992a4SHeiner Kallweit 460925e992a4SHeiner Kallweit static int r8169_phy_connect(struct rtl8169_private *tp) 461025e992a4SHeiner Kallweit { 461125e992a4SHeiner Kallweit struct phy_device *phydev = tp->phydev; 461225e992a4SHeiner Kallweit phy_interface_t phy_mode; 461325e992a4SHeiner Kallweit int ret; 461425e992a4SHeiner Kallweit 461525e992a4SHeiner Kallweit phy_mode = tp->supports_gmii ? PHY_INTERFACE_MODE_GMII : 461625e992a4SHeiner Kallweit PHY_INTERFACE_MODE_MII; 461725e992a4SHeiner Kallweit 461825e992a4SHeiner Kallweit ret = phy_connect_direct(tp->dev, phydev, r8169_phylink_handler, 461925e992a4SHeiner Kallweit phy_mode); 462025e992a4SHeiner Kallweit if (ret) 462125e992a4SHeiner Kallweit return ret; 462225e992a4SHeiner Kallweit 462366058b1cSHeiner Kallweit if (!tp->supports_gmii) 462425e992a4SHeiner Kallweit phy_set_max_speed(phydev, SPEED_100); 462525e992a4SHeiner Kallweit 462625e992a4SHeiner Kallweit phy_support_asym_pause(phydev); 462725e992a4SHeiner Kallweit 462825e992a4SHeiner Kallweit phy_attached_info(phydev); 462925e992a4SHeiner Kallweit 463025e992a4SHeiner Kallweit return 0; 463125e992a4SHeiner Kallweit } 463225e992a4SHeiner Kallweit 46338ac8e8c6SHeiner Kallweit static void rtl8169_down(struct rtl8169_private *tp) 463425e992a4SHeiner Kallweit { 46358ac8e8c6SHeiner Kallweit rtl_lock_work(tp); 46368ac8e8c6SHeiner Kallweit 46378ac8e8c6SHeiner Kallweit /* Clear all task flags */ 46388ac8e8c6SHeiner Kallweit bitmap_zero(tp->wk.flags, RTL_FLAG_MAX); 463925e992a4SHeiner Kallweit 464025e992a4SHeiner Kallweit phy_stop(tp->phydev); 464125e992a4SHeiner Kallweit napi_disable(&tp->napi); 464225e992a4SHeiner Kallweit 464312006848SHeiner Kallweit rtl8169_hw_reset(tp, true); 464425e992a4SHeiner Kallweit 464525e992a4SHeiner Kallweit rtl_pll_power_down(tp); 46468ac8e8c6SHeiner Kallweit 46478ac8e8c6SHeiner Kallweit rtl_unlock_work(tp); 464825e992a4SHeiner Kallweit } 464925e992a4SHeiner Kallweit 465025e992a4SHeiner Kallweit static int rtl8169_close(struct net_device *dev) 465125e992a4SHeiner Kallweit { 465225e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 465325e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 465425e992a4SHeiner Kallweit 465525e992a4SHeiner Kallweit pm_runtime_get_sync(&pdev->dev); 465625e992a4SHeiner Kallweit 465725e992a4SHeiner Kallweit /* Update counters before going down */ 465825e992a4SHeiner Kallweit rtl8169_update_counters(tp); 465925e992a4SHeiner Kallweit 46608ac8e8c6SHeiner Kallweit netif_stop_queue(dev); 46618ac8e8c6SHeiner Kallweit rtl8169_down(tp); 46628ac8e8c6SHeiner Kallweit rtl8169_rx_clear(tp); 466325e992a4SHeiner Kallweit 466425e992a4SHeiner Kallweit cancel_work_sync(&tp->wk.work); 466525e992a4SHeiner Kallweit 466625e992a4SHeiner Kallweit phy_disconnect(tp->phydev); 466725e992a4SHeiner Kallweit 466825e992a4SHeiner Kallweit pci_free_irq(pdev, 0, tp); 466925e992a4SHeiner Kallweit 467025e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, 467125e992a4SHeiner Kallweit tp->RxPhyAddr); 467225e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, 467325e992a4SHeiner Kallweit tp->TxPhyAddr); 467425e992a4SHeiner Kallweit tp->TxDescArray = NULL; 467525e992a4SHeiner Kallweit tp->RxDescArray = NULL; 467625e992a4SHeiner Kallweit 467725e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev); 467825e992a4SHeiner Kallweit 467925e992a4SHeiner Kallweit return 0; 468025e992a4SHeiner Kallweit } 468125e992a4SHeiner Kallweit 468225e992a4SHeiner Kallweit #ifdef CONFIG_NET_POLL_CONTROLLER 468325e992a4SHeiner Kallweit static void rtl8169_netpoll(struct net_device *dev) 468425e992a4SHeiner Kallweit { 468525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 468625e992a4SHeiner Kallweit 468725e992a4SHeiner Kallweit rtl8169_interrupt(pci_irq_vector(tp->pci_dev, 0), tp); 468825e992a4SHeiner Kallweit } 468925e992a4SHeiner Kallweit #endif 469025e992a4SHeiner Kallweit 469125e992a4SHeiner Kallweit static int rtl_open(struct net_device *dev) 469225e992a4SHeiner Kallweit { 469325e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 469425e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 469525e992a4SHeiner Kallweit int retval = -ENOMEM; 469625e992a4SHeiner Kallweit 469725e992a4SHeiner Kallweit pm_runtime_get_sync(&pdev->dev); 469825e992a4SHeiner Kallweit 469925e992a4SHeiner Kallweit /* 470025e992a4SHeiner Kallweit * Rx and Tx descriptors needs 256 bytes alignment. 470125e992a4SHeiner Kallweit * dma_alloc_coherent provides more. 470225e992a4SHeiner Kallweit */ 470325e992a4SHeiner Kallweit tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES, 470425e992a4SHeiner Kallweit &tp->TxPhyAddr, GFP_KERNEL); 470525e992a4SHeiner Kallweit if (!tp->TxDescArray) 470625e992a4SHeiner Kallweit goto err_pm_runtime_put; 470725e992a4SHeiner Kallweit 470825e992a4SHeiner Kallweit tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES, 470925e992a4SHeiner Kallweit &tp->RxPhyAddr, GFP_KERNEL); 471025e992a4SHeiner Kallweit if (!tp->RxDescArray) 471125e992a4SHeiner Kallweit goto err_free_tx_0; 471225e992a4SHeiner Kallweit 471325e992a4SHeiner Kallweit retval = rtl8169_init_ring(tp); 471425e992a4SHeiner Kallweit if (retval < 0) 471525e992a4SHeiner Kallweit goto err_free_rx_1; 471625e992a4SHeiner Kallweit 471725e992a4SHeiner Kallweit rtl_request_firmware(tp); 471825e992a4SHeiner Kallweit 471925e992a4SHeiner Kallweit retval = pci_request_irq(pdev, 0, rtl8169_interrupt, NULL, tp, 472025e992a4SHeiner Kallweit dev->name); 472125e992a4SHeiner Kallweit if (retval < 0) 472225e992a4SHeiner Kallweit goto err_release_fw_2; 472325e992a4SHeiner Kallweit 472425e992a4SHeiner Kallweit retval = r8169_phy_connect(tp); 472525e992a4SHeiner Kallweit if (retval) 472625e992a4SHeiner Kallweit goto err_free_irq; 472725e992a4SHeiner Kallweit 472825e992a4SHeiner Kallweit rtl_lock_work(tp); 472925e992a4SHeiner Kallweit 473025e992a4SHeiner Kallweit set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); 473125e992a4SHeiner Kallweit 473225e992a4SHeiner Kallweit napi_enable(&tp->napi); 473325e992a4SHeiner Kallweit 4734b5aed0b3SHeiner Kallweit rtl8169_init_phy(tp); 473525e992a4SHeiner Kallweit 473625e992a4SHeiner Kallweit rtl_pll_power_up(tp); 473725e992a4SHeiner Kallweit 473825e992a4SHeiner Kallweit rtl_hw_start(tp); 473925e992a4SHeiner Kallweit 4740d56f58ceSHeiner Kallweit rtl8169_init_counter_offsets(tp); 474125e992a4SHeiner Kallweit 474225e992a4SHeiner Kallweit phy_start(tp->phydev); 474325e992a4SHeiner Kallweit netif_start_queue(dev); 474425e992a4SHeiner Kallweit 474525e992a4SHeiner Kallweit rtl_unlock_work(tp); 474625e992a4SHeiner Kallweit 474725e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev); 474825e992a4SHeiner Kallweit out: 474925e992a4SHeiner Kallweit return retval; 475025e992a4SHeiner Kallweit 475125e992a4SHeiner Kallweit err_free_irq: 475225e992a4SHeiner Kallweit pci_free_irq(pdev, 0, tp); 475325e992a4SHeiner Kallweit err_release_fw_2: 475425e992a4SHeiner Kallweit rtl_release_firmware(tp); 475525e992a4SHeiner Kallweit rtl8169_rx_clear(tp); 475625e992a4SHeiner Kallweit err_free_rx_1: 475725e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, 475825e992a4SHeiner Kallweit tp->RxPhyAddr); 475925e992a4SHeiner Kallweit tp->RxDescArray = NULL; 476025e992a4SHeiner Kallweit err_free_tx_0: 476125e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, 476225e992a4SHeiner Kallweit tp->TxPhyAddr); 476325e992a4SHeiner Kallweit tp->TxDescArray = NULL; 476425e992a4SHeiner Kallweit err_pm_runtime_put: 476525e992a4SHeiner Kallweit pm_runtime_put_noidle(&pdev->dev); 476625e992a4SHeiner Kallweit goto out; 476725e992a4SHeiner Kallweit } 476825e992a4SHeiner Kallweit 476925e992a4SHeiner Kallweit static void 477025e992a4SHeiner Kallweit rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 477125e992a4SHeiner Kallweit { 477225e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 477325e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 477425e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 477525e992a4SHeiner Kallweit unsigned int start; 477625e992a4SHeiner Kallweit 477725e992a4SHeiner Kallweit pm_runtime_get_noresume(&pdev->dev); 477825e992a4SHeiner Kallweit 4779314a9cbbSHeiner Kallweit netdev_stats_to_stats64(stats, &dev->stats); 4780314a9cbbSHeiner Kallweit 478125e992a4SHeiner Kallweit do { 478225e992a4SHeiner Kallweit start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp); 478325e992a4SHeiner Kallweit stats->rx_packets = tp->rx_stats.packets; 478425e992a4SHeiner Kallweit stats->rx_bytes = tp->rx_stats.bytes; 478525e992a4SHeiner Kallweit } while (u64_stats_fetch_retry_irq(&tp->rx_stats.syncp, start)); 478625e992a4SHeiner Kallweit 478725e992a4SHeiner Kallweit do { 478825e992a4SHeiner Kallweit start = u64_stats_fetch_begin_irq(&tp->tx_stats.syncp); 478925e992a4SHeiner Kallweit stats->tx_packets = tp->tx_stats.packets; 479025e992a4SHeiner Kallweit stats->tx_bytes = tp->tx_stats.bytes; 479125e992a4SHeiner Kallweit } while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start)); 479225e992a4SHeiner Kallweit 479325e992a4SHeiner Kallweit /* 4794ed72a9bbSCorentin Musard * Fetch additional counter values missing in stats collected by driver 479525e992a4SHeiner Kallweit * from tally counters. 479625e992a4SHeiner Kallweit */ 479725e992a4SHeiner Kallweit if (pm_runtime_active(&pdev->dev)) 479825e992a4SHeiner Kallweit rtl8169_update_counters(tp); 479925e992a4SHeiner Kallweit 480025e992a4SHeiner Kallweit /* 480125e992a4SHeiner Kallweit * Subtract values fetched during initalization. 480225e992a4SHeiner Kallweit * See rtl8169_init_counter_offsets for a description why we do that. 480325e992a4SHeiner Kallweit */ 480425e992a4SHeiner Kallweit stats->tx_errors = le64_to_cpu(counters->tx_errors) - 480525e992a4SHeiner Kallweit le64_to_cpu(tp->tc_offset.tx_errors); 480625e992a4SHeiner Kallweit stats->collisions = le32_to_cpu(counters->tx_multi_collision) - 480725e992a4SHeiner Kallweit le32_to_cpu(tp->tc_offset.tx_multi_collision); 480825e992a4SHeiner Kallweit stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) - 480925e992a4SHeiner Kallweit le16_to_cpu(tp->tc_offset.tx_aborted); 48100da3359aSHeiner Kallweit stats->rx_missed_errors = le16_to_cpu(counters->rx_missed) - 48110da3359aSHeiner Kallweit le16_to_cpu(tp->tc_offset.rx_missed); 481225e992a4SHeiner Kallweit 481325e992a4SHeiner Kallweit pm_runtime_put_noidle(&pdev->dev); 481425e992a4SHeiner Kallweit } 481525e992a4SHeiner Kallweit 481627dc36aeSHeiner Kallweit static void rtl8169_net_suspend(struct rtl8169_private *tp) 481725e992a4SHeiner Kallweit { 481827dc36aeSHeiner Kallweit if (!netif_running(tp->dev)) 481925e992a4SHeiner Kallweit return; 482025e992a4SHeiner Kallweit 482127dc36aeSHeiner Kallweit netif_device_detach(tp->dev); 48228ac8e8c6SHeiner Kallweit rtl8169_down(tp); 482325e992a4SHeiner Kallweit } 482425e992a4SHeiner Kallweit 482525e992a4SHeiner Kallweit #ifdef CONFIG_PM 482625e992a4SHeiner Kallweit 482767ee63efSHeiner Kallweit static int __maybe_unused rtl8169_suspend(struct device *device) 482825e992a4SHeiner Kallweit { 482927dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device); 483025e992a4SHeiner Kallweit 483127dc36aeSHeiner Kallweit rtl8169_net_suspend(tp); 483225e992a4SHeiner Kallweit clk_disable_unprepare(tp->clk); 483325e992a4SHeiner Kallweit 483425e992a4SHeiner Kallweit return 0; 483525e992a4SHeiner Kallweit } 483625e992a4SHeiner Kallweit 483727dc36aeSHeiner Kallweit static void __rtl8169_resume(struct rtl8169_private *tp) 483825e992a4SHeiner Kallweit { 483927dc36aeSHeiner Kallweit netif_device_attach(tp->dev); 484025e992a4SHeiner Kallweit 484125e992a4SHeiner Kallweit rtl_pll_power_up(tp); 4842b5aed0b3SHeiner Kallweit rtl8169_init_phy(tp); 484325e992a4SHeiner Kallweit 484425e992a4SHeiner Kallweit phy_start(tp->phydev); 484525e992a4SHeiner Kallweit 484625e992a4SHeiner Kallweit rtl_lock_work(tp); 484725e992a4SHeiner Kallweit napi_enable(&tp->napi); 484825e992a4SHeiner Kallweit set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); 484925e992a4SHeiner Kallweit rtl_reset_work(tp); 485025e992a4SHeiner Kallweit rtl_unlock_work(tp); 485125e992a4SHeiner Kallweit } 485225e992a4SHeiner Kallweit 485367ee63efSHeiner Kallweit static int __maybe_unused rtl8169_resume(struct device *device) 485425e992a4SHeiner Kallweit { 485527dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device); 485625e992a4SHeiner Kallweit 485727dc36aeSHeiner Kallweit rtl_rar_set(tp, tp->dev->dev_addr); 485825e992a4SHeiner Kallweit 485925e992a4SHeiner Kallweit clk_prepare_enable(tp->clk); 486025e992a4SHeiner Kallweit 486127dc36aeSHeiner Kallweit if (netif_running(tp->dev)) 486227dc36aeSHeiner Kallweit __rtl8169_resume(tp); 486325e992a4SHeiner Kallweit 486425e992a4SHeiner Kallweit return 0; 486525e992a4SHeiner Kallweit } 486625e992a4SHeiner Kallweit 486725e992a4SHeiner Kallweit static int rtl8169_runtime_suspend(struct device *device) 486825e992a4SHeiner Kallweit { 486927dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device); 487025e992a4SHeiner Kallweit 487125e992a4SHeiner Kallweit if (!tp->TxDescArray) 487225e992a4SHeiner Kallweit return 0; 487325e992a4SHeiner Kallweit 487425e992a4SHeiner Kallweit rtl_lock_work(tp); 487501bd753dSHeiner Kallweit __rtl8169_set_wol(tp, WAKE_PHY); 487625e992a4SHeiner Kallweit rtl_unlock_work(tp); 487725e992a4SHeiner Kallweit 487827dc36aeSHeiner Kallweit rtl8169_net_suspend(tp); 487925e992a4SHeiner Kallweit 488025e992a4SHeiner Kallweit /* Update counters before going runtime suspend */ 488125e992a4SHeiner Kallweit rtl8169_update_counters(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 if (!tp->TxDescArray) 489325e992a4SHeiner Kallweit return 0; 489425e992a4SHeiner Kallweit 489525e992a4SHeiner Kallweit rtl_lock_work(tp); 489625e992a4SHeiner Kallweit __rtl8169_set_wol(tp, tp->saved_wolopts); 489725e992a4SHeiner Kallweit rtl_unlock_work(tp); 489825e992a4SHeiner Kallweit 489927dc36aeSHeiner Kallweit __rtl8169_resume(tp); 490025e992a4SHeiner 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 5435*a38b7fbfSHeiner Kallweit if (r8168_check_dash(tp)) { 5436*a38b7fbfSHeiner Kallweit netdev_info(dev, "DASH enabled\n"); 543725e992a4SHeiner Kallweit rtl8168_driver_start(tp); 5438*a38b7fbfSHeiner 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