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/moduleparam.h> 1425e992a4SHeiner Kallweit #include <linux/pci.h> 1525e992a4SHeiner Kallweit #include <linux/netdevice.h> 1625e992a4SHeiner Kallweit #include <linux/etherdevice.h> 1725e992a4SHeiner Kallweit #include <linux/clk.h> 1825e992a4SHeiner Kallweit #include <linux/delay.h> 1925e992a4SHeiner Kallweit #include <linux/ethtool.h> 2025e992a4SHeiner Kallweit #include <linux/phy.h> 2125e992a4SHeiner Kallweit #include <linux/if_vlan.h> 2225e992a4SHeiner Kallweit #include <linux/in.h> 2325e992a4SHeiner Kallweit #include <linux/io.h> 2425e992a4SHeiner Kallweit #include <linux/ip.h> 2525e992a4SHeiner Kallweit #include <linux/tcp.h> 2625e992a4SHeiner Kallweit #include <linux/interrupt.h> 2725e992a4SHeiner Kallweit #include <linux/dma-mapping.h> 2825e992a4SHeiner Kallweit #include <linux/pm_runtime.h> 296cf96dd4SHeiner Kallweit #include <linux/bitfield.h> 3025e992a4SHeiner Kallweit #include <linux/prefetch.h> 3125e992a4SHeiner Kallweit #include <linux/ipv6.h> 3225e992a4SHeiner Kallweit #include <net/ip6_checksum.h> 3325e992a4SHeiner Kallweit 342992bdfaSHeiner Kallweit #include "r8169.h" 358197f9d2SHeiner Kallweit #include "r8169_firmware.h" 368197f9d2SHeiner Kallweit 3725e992a4SHeiner Kallweit #define MODULENAME "r8169" 3825e992a4SHeiner Kallweit 3925e992a4SHeiner Kallweit #define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw" 4025e992a4SHeiner Kallweit #define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw" 4125e992a4SHeiner Kallweit #define FIRMWARE_8168E_1 "rtl_nic/rtl8168e-1.fw" 4225e992a4SHeiner Kallweit #define FIRMWARE_8168E_2 "rtl_nic/rtl8168e-2.fw" 4325e992a4SHeiner Kallweit #define FIRMWARE_8168E_3 "rtl_nic/rtl8168e-3.fw" 4425e992a4SHeiner Kallweit #define FIRMWARE_8168F_1 "rtl_nic/rtl8168f-1.fw" 4525e992a4SHeiner Kallweit #define FIRMWARE_8168F_2 "rtl_nic/rtl8168f-2.fw" 4625e992a4SHeiner Kallweit #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" 4725e992a4SHeiner Kallweit #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" 4825e992a4SHeiner Kallweit #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" 4925e992a4SHeiner Kallweit #define FIRMWARE_8411_2 "rtl_nic/rtl8411-2.fw" 5025e992a4SHeiner Kallweit #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" 5125e992a4SHeiner Kallweit #define FIRMWARE_8106E_2 "rtl_nic/rtl8106e-2.fw" 5225e992a4SHeiner Kallweit #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" 5325e992a4SHeiner Kallweit #define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw" 5425e992a4SHeiner Kallweit #define FIRMWARE_8168H_1 "rtl_nic/rtl8168h-1.fw" 5525e992a4SHeiner Kallweit #define FIRMWARE_8168H_2 "rtl_nic/rtl8168h-2.fw" 56229c1e0dSHeiner Kallweit #define FIRMWARE_8168FP_3 "rtl_nic/rtl8168fp-3.fw" 5725e992a4SHeiner Kallweit #define FIRMWARE_8107E_1 "rtl_nic/rtl8107e-1.fw" 5825e992a4SHeiner Kallweit #define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw" 5902bf642bSHeiner Kallweit #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw" 6025e992a4SHeiner Kallweit 6125e992a4SHeiner Kallweit /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). 6225e992a4SHeiner Kallweit The RTL chips use a 64 element hash table based on the Ethernet CRC. */ 6381cd17a4SHeiner Kallweit #define MC_FILTER_LIMIT 32 6425e992a4SHeiner Kallweit 6525e992a4SHeiner Kallweit #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ 6625e992a4SHeiner Kallweit #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ 6725e992a4SHeiner Kallweit 6825e992a4SHeiner Kallweit #define R8169_REGS_SIZE 256 6925e992a4SHeiner Kallweit #define R8169_RX_BUF_SIZE (SZ_16K - 1) 7025e992a4SHeiner Kallweit #define NUM_TX_DESC 64 /* Number of Tx descriptor registers */ 7125e992a4SHeiner Kallweit #define NUM_RX_DESC 256U /* Number of Rx descriptor registers */ 7225e992a4SHeiner Kallweit #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) 7325e992a4SHeiner Kallweit #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) 7425e992a4SHeiner Kallweit 750360c046SHeiner Kallweit #define OCP_STD_PHY_BASE 0xa400 760360c046SHeiner Kallweit 77145a40e8SHeiner Kallweit #define RTL_CFG_NO_GBIT 1 78145a40e8SHeiner Kallweit 7925e992a4SHeiner Kallweit /* write/read MMIO register */ 8025e992a4SHeiner Kallweit #define RTL_W8(tp, reg, val8) writeb((val8), tp->mmio_addr + (reg)) 8125e992a4SHeiner Kallweit #define RTL_W16(tp, reg, val16) writew((val16), tp->mmio_addr + (reg)) 8225e992a4SHeiner Kallweit #define RTL_W32(tp, reg, val32) writel((val32), tp->mmio_addr + (reg)) 8325e992a4SHeiner Kallweit #define RTL_R8(tp, reg) readb(tp->mmio_addr + (reg)) 8425e992a4SHeiner Kallweit #define RTL_R16(tp, reg) readw(tp->mmio_addr + (reg)) 8525e992a4SHeiner Kallweit #define RTL_R32(tp, reg) readl(tp->mmio_addr + (reg)) 8625e992a4SHeiner Kallweit 87b410439cSHeiner Kallweit #define JUMBO_4K (4 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) 88b410439cSHeiner Kallweit #define JUMBO_6K (6 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) 89b410439cSHeiner Kallweit #define JUMBO_7K (7 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) 90b410439cSHeiner Kallweit #define JUMBO_9K (9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) 9125e992a4SHeiner Kallweit 9225e992a4SHeiner Kallweit static const struct { 9325e992a4SHeiner Kallweit const char *name; 9425e992a4SHeiner Kallweit const char *fw_name; 9525e992a4SHeiner Kallweit } rtl_chip_infos[] = { 9625e992a4SHeiner Kallweit /* PCI devices. */ 9725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_02] = {"RTL8169s" }, 9825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_03] = {"RTL8110s" }, 9925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_04] = {"RTL8169sb/8110sb" }, 10025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_05] = {"RTL8169sc/8110sc" }, 10125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_06] = {"RTL8169sc/8110sc" }, 10225e992a4SHeiner Kallweit /* PCI-E devices. */ 10325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_07] = {"RTL8102e" }, 10425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_08] = {"RTL8102e" }, 1059e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_09] = {"RTL8102e/RTL8103e" }, 10625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_10] = {"RTL8101e" }, 10725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_11] = {"RTL8168b/8111b" }, 10825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_12] = {"RTL8168b/8111b" }, 10925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_13] = {"RTL8101e" }, 11025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_14] = {"RTL8100e" }, 11125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_15] = {"RTL8100e" }, 11225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_16] = {"RTL8101e" }, 11325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b" }, 11425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp" }, 11525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_19] = {"RTL8168c/8111c" }, 11625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_20] = {"RTL8168c/8111c" }, 11725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_21] = {"RTL8168c/8111c" }, 11825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_22] = {"RTL8168c/8111c" }, 11925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_23] = {"RTL8168cp/8111cp" }, 12025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_24] = {"RTL8168cp/8111cp" }, 12125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_25] = {"RTL8168d/8111d", FIRMWARE_8168D_1}, 12225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_26] = {"RTL8168d/8111d", FIRMWARE_8168D_2}, 12325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_27] = {"RTL8168dp/8111dp" }, 12425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_28] = {"RTL8168dp/8111dp" }, 12525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_29] = {"RTL8105e", FIRMWARE_8105E_1}, 12625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_30] = {"RTL8105e", FIRMWARE_8105E_1}, 12725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_31] = {"RTL8168dp/8111dp" }, 12825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_32] = {"RTL8168e/8111e", FIRMWARE_8168E_1}, 12925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_33] = {"RTL8168e/8111e", FIRMWARE_8168E_2}, 13025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_34] = {"RTL8168evl/8111evl", FIRMWARE_8168E_3}, 13125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_35] = {"RTL8168f/8111f", FIRMWARE_8168F_1}, 13225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_36] = {"RTL8168f/8111f", FIRMWARE_8168F_2}, 13325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_37] = {"RTL8402", FIRMWARE_8402_1 }, 13425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_38] = {"RTL8411", FIRMWARE_8411_1 }, 13525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_39] = {"RTL8106e", FIRMWARE_8106E_1}, 13625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_40] = {"RTL8168g/8111g", FIRMWARE_8168G_2}, 13725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_41] = {"RTL8168g/8111g" }, 1389e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_42] = {"RTL8168gu/8111gu", FIRMWARE_8168G_3}, 1399e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_43] = {"RTL8106eus", FIRMWARE_8106E_2}, 1409e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_44] = {"RTL8411b", FIRMWARE_8411_2 }, 14125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_45] = {"RTL8168h/8111h", FIRMWARE_8168H_1}, 14225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_46] = {"RTL8168h/8111h", FIRMWARE_8168H_2}, 14325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_47] = {"RTL8107e", FIRMWARE_8107E_1}, 14425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_48] = {"RTL8107e", FIRMWARE_8107E_2}, 14525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_49] = {"RTL8168ep/8111ep" }, 14625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_50] = {"RTL8168ep/8111ep" }, 14725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep" }, 148229c1e0dSHeiner Kallweit [RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117", FIRMWARE_8168FP_3}, 149f1bce4adSHeiner Kallweit [RTL_GIGA_MAC_VER_60] = {"RTL8125" }, 15002bf642bSHeiner Kallweit [RTL_GIGA_MAC_VER_61] = {"RTL8125", FIRMWARE_8125A_3}, 15125e992a4SHeiner Kallweit }; 15225e992a4SHeiner Kallweit 15325e992a4SHeiner Kallweit static const struct pci_device_id rtl8169_pci_tbl[] = { 154145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x2502) }, 155145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x2600) }, 156145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8129) }, 157145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_NO_GBIT }, 158145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8161) }, 159145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8167) }, 160145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8168) }, 161145a40e8SHeiner Kallweit { PCI_VDEVICE(NCUBE, 0x8168) }, 162145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8169) }, 16325e992a4SHeiner Kallweit { PCI_VENDOR_ID_DLINK, 0x4300, 164145a40e8SHeiner Kallweit PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0 }, 1659d9f3fbaSHeiner Kallweit { PCI_VDEVICE(DLINK, 0x4300) }, 1669d9f3fbaSHeiner Kallweit { PCI_VDEVICE(DLINK, 0x4302) }, 1679d9f3fbaSHeiner Kallweit { PCI_VDEVICE(AT, 0xc107) }, 1689d9f3fbaSHeiner Kallweit { PCI_VDEVICE(USR, 0x0116) }, 1699d9f3fbaSHeiner Kallweit { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 }, 1709d9f3fbaSHeiner Kallweit { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 }, 171f1bce4adSHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8125) }, 172f1bce4adSHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x3000) }, 17325e992a4SHeiner Kallweit {} 17425e992a4SHeiner Kallweit }; 17525e992a4SHeiner Kallweit 17625e992a4SHeiner Kallweit MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); 17725e992a4SHeiner Kallweit 17825e992a4SHeiner Kallweit enum rtl_registers { 17925e992a4SHeiner Kallweit MAC0 = 0, /* Ethernet hardware address. */ 18025e992a4SHeiner Kallweit MAC4 = 4, 18125e992a4SHeiner Kallweit MAR0 = 8, /* Multicast filter. */ 18225e992a4SHeiner Kallweit CounterAddrLow = 0x10, 18325e992a4SHeiner Kallweit CounterAddrHigh = 0x14, 18425e992a4SHeiner Kallweit TxDescStartAddrLow = 0x20, 18525e992a4SHeiner Kallweit TxDescStartAddrHigh = 0x24, 18625e992a4SHeiner Kallweit TxHDescStartAddrLow = 0x28, 18725e992a4SHeiner Kallweit TxHDescStartAddrHigh = 0x2c, 18825e992a4SHeiner Kallweit FLASH = 0x30, 18925e992a4SHeiner Kallweit ERSR = 0x36, 19025e992a4SHeiner Kallweit ChipCmd = 0x37, 19125e992a4SHeiner Kallweit TxPoll = 0x38, 19225e992a4SHeiner Kallweit IntrMask = 0x3c, 19325e992a4SHeiner Kallweit IntrStatus = 0x3e, 19425e992a4SHeiner Kallweit 19525e992a4SHeiner Kallweit TxConfig = 0x40, 19625e992a4SHeiner Kallweit #define TXCFG_AUTO_FIFO (1 << 7) /* 8111e-vl */ 19725e992a4SHeiner Kallweit #define TXCFG_EMPTY (1 << 11) /* 8111e-vl */ 19825e992a4SHeiner Kallweit 19925e992a4SHeiner Kallweit RxConfig = 0x44, 20025e992a4SHeiner Kallweit #define RX128_INT_EN (1 << 15) /* 8111c and later */ 20125e992a4SHeiner Kallweit #define RX_MULTI_EN (1 << 14) /* 8111c only */ 20225e992a4SHeiner Kallweit #define RXCFG_FIFO_SHIFT 13 20325e992a4SHeiner Kallweit /* No threshold before first PCI xfer */ 20425e992a4SHeiner Kallweit #define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) 20525e992a4SHeiner Kallweit #define RX_EARLY_OFF (1 << 11) 20625e992a4SHeiner Kallweit #define RXCFG_DMA_SHIFT 8 20725e992a4SHeiner Kallweit /* Unlimited maximum PCI burst. */ 20825e992a4SHeiner Kallweit #define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) 20925e992a4SHeiner Kallweit 21025e992a4SHeiner Kallweit Cfg9346 = 0x50, 21125e992a4SHeiner Kallweit Config0 = 0x51, 21225e992a4SHeiner Kallweit Config1 = 0x52, 21325e992a4SHeiner Kallweit Config2 = 0x53, 21425e992a4SHeiner Kallweit #define PME_SIGNAL (1 << 5) /* 8168c and later */ 21525e992a4SHeiner Kallweit 21625e992a4SHeiner Kallweit Config3 = 0x54, 21725e992a4SHeiner Kallweit Config4 = 0x55, 21825e992a4SHeiner Kallweit Config5 = 0x56, 21925e992a4SHeiner Kallweit PHYAR = 0x60, 22025e992a4SHeiner Kallweit PHYstatus = 0x6c, 22125e992a4SHeiner Kallweit RxMaxSize = 0xda, 22225e992a4SHeiner Kallweit CPlusCmd = 0xe0, 22325e992a4SHeiner Kallweit IntrMitigate = 0xe2, 22425e992a4SHeiner Kallweit 2256cf96dd4SHeiner Kallweit #define RTL_COALESCE_TX_USECS GENMASK(15, 12) 2266cf96dd4SHeiner Kallweit #define RTL_COALESCE_TX_FRAMES GENMASK(11, 8) 2276cf96dd4SHeiner Kallweit #define RTL_COALESCE_RX_USECS GENMASK(7, 4) 2286cf96dd4SHeiner Kallweit #define RTL_COALESCE_RX_FRAMES GENMASK(3, 0) 2296cf96dd4SHeiner Kallweit 2302b3e48b6SHeiner Kallweit #define RTL_COALESCE_T_MAX 0x0fU 2312b3e48b6SHeiner Kallweit #define RTL_COALESCE_FRAME_MAX (RTL_COALESCE_T_MAX * 4) 23225e992a4SHeiner Kallweit 23325e992a4SHeiner Kallweit RxDescAddrLow = 0xe4, 23425e992a4SHeiner Kallweit RxDescAddrHigh = 0xe8, 23525e992a4SHeiner Kallweit EarlyTxThres = 0xec, /* 8169. Unit of 32 bytes. */ 23625e992a4SHeiner Kallweit 23725e992a4SHeiner Kallweit #define NoEarlyTx 0x3f /* Max value : no early transmit. */ 23825e992a4SHeiner Kallweit 23925e992a4SHeiner Kallweit MaxTxPacketSize = 0xec, /* 8101/8168. Unit of 128 bytes. */ 24025e992a4SHeiner Kallweit 24125e992a4SHeiner Kallweit #define TxPacketMax (8064 >> 7) 24225e992a4SHeiner Kallweit #define EarlySize 0x27 24325e992a4SHeiner Kallweit 24425e992a4SHeiner Kallweit FuncEvent = 0xf0, 24525e992a4SHeiner Kallweit FuncEventMask = 0xf4, 24625e992a4SHeiner Kallweit FuncPresetState = 0xf8, 24725e992a4SHeiner Kallweit IBCR0 = 0xf8, 24825e992a4SHeiner Kallweit IBCR2 = 0xf9, 24925e992a4SHeiner Kallweit IBIMR0 = 0xfa, 25025e992a4SHeiner Kallweit IBISR0 = 0xfb, 25125e992a4SHeiner Kallweit FuncForceEvent = 0xfc, 25225e992a4SHeiner Kallweit }; 25325e992a4SHeiner Kallweit 25425e992a4SHeiner Kallweit enum rtl8168_8101_registers { 25525e992a4SHeiner Kallweit CSIDR = 0x64, 25625e992a4SHeiner Kallweit CSIAR = 0x68, 25725e992a4SHeiner Kallweit #define CSIAR_FLAG 0x80000000 25825e992a4SHeiner Kallweit #define CSIAR_WRITE_CMD 0x80000000 25925e992a4SHeiner Kallweit #define CSIAR_BYTE_ENABLE 0x0000f000 26025e992a4SHeiner Kallweit #define CSIAR_ADDR_MASK 0x00000fff 26125e992a4SHeiner Kallweit PMCH = 0x6f, 26225e992a4SHeiner Kallweit EPHYAR = 0x80, 26325e992a4SHeiner Kallweit #define EPHYAR_FLAG 0x80000000 26425e992a4SHeiner Kallweit #define EPHYAR_WRITE_CMD 0x80000000 26525e992a4SHeiner Kallweit #define EPHYAR_REG_MASK 0x1f 26625e992a4SHeiner Kallweit #define EPHYAR_REG_SHIFT 16 26725e992a4SHeiner Kallweit #define EPHYAR_DATA_MASK 0xffff 26825e992a4SHeiner Kallweit DLLPR = 0xd0, 26925e992a4SHeiner Kallweit #define PFM_EN (1 << 6) 27025e992a4SHeiner Kallweit #define TX_10M_PS_EN (1 << 7) 27125e992a4SHeiner Kallweit DBG_REG = 0xd1, 27225e992a4SHeiner Kallweit #define FIX_NAK_1 (1 << 4) 27325e992a4SHeiner Kallweit #define FIX_NAK_2 (1 << 3) 27425e992a4SHeiner Kallweit TWSI = 0xd2, 27525e992a4SHeiner Kallweit MCU = 0xd3, 27625e992a4SHeiner Kallweit #define NOW_IS_OOB (1 << 7) 27725e992a4SHeiner Kallweit #define TX_EMPTY (1 << 5) 27825e992a4SHeiner Kallweit #define RX_EMPTY (1 << 4) 27925e992a4SHeiner Kallweit #define RXTX_EMPTY (TX_EMPTY | RX_EMPTY) 28025e992a4SHeiner Kallweit #define EN_NDP (1 << 3) 28125e992a4SHeiner Kallweit #define EN_OOB_RESET (1 << 2) 28225e992a4SHeiner Kallweit #define LINK_LIST_RDY (1 << 1) 28325e992a4SHeiner Kallweit EFUSEAR = 0xdc, 28425e992a4SHeiner Kallweit #define EFUSEAR_FLAG 0x80000000 28525e992a4SHeiner Kallweit #define EFUSEAR_WRITE_CMD 0x80000000 28625e992a4SHeiner Kallweit #define EFUSEAR_READ_CMD 0x00000000 28725e992a4SHeiner Kallweit #define EFUSEAR_REG_MASK 0x03ff 28825e992a4SHeiner Kallweit #define EFUSEAR_REG_SHIFT 8 28925e992a4SHeiner Kallweit #define EFUSEAR_DATA_MASK 0xff 29025e992a4SHeiner Kallweit MISC_1 = 0xf2, 29125e992a4SHeiner Kallweit #define PFM_D3COLD_EN (1 << 6) 29225e992a4SHeiner Kallweit }; 29325e992a4SHeiner Kallweit 29425e992a4SHeiner Kallweit enum rtl8168_registers { 29525e992a4SHeiner Kallweit LED_FREQ = 0x1a, 29625e992a4SHeiner Kallweit EEE_LED = 0x1b, 29725e992a4SHeiner Kallweit ERIDR = 0x70, 29825e992a4SHeiner Kallweit ERIAR = 0x74, 29925e992a4SHeiner Kallweit #define ERIAR_FLAG 0x80000000 30025e992a4SHeiner Kallweit #define ERIAR_WRITE_CMD 0x80000000 30125e992a4SHeiner Kallweit #define ERIAR_READ_CMD 0x00000000 30225e992a4SHeiner Kallweit #define ERIAR_ADDR_BYTE_ALIGN 4 30325e992a4SHeiner Kallweit #define ERIAR_TYPE_SHIFT 16 30425e992a4SHeiner Kallweit #define ERIAR_EXGMAC (0x00 << ERIAR_TYPE_SHIFT) 30525e992a4SHeiner Kallweit #define ERIAR_MSIX (0x01 << ERIAR_TYPE_SHIFT) 30625e992a4SHeiner Kallweit #define ERIAR_ASF (0x02 << ERIAR_TYPE_SHIFT) 30725e992a4SHeiner Kallweit #define ERIAR_OOB (0x02 << ERIAR_TYPE_SHIFT) 30825e992a4SHeiner Kallweit #define ERIAR_MASK_SHIFT 12 30925e992a4SHeiner Kallweit #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) 31025e992a4SHeiner Kallweit #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) 31125e992a4SHeiner Kallweit #define ERIAR_MASK_0100 (0x4 << ERIAR_MASK_SHIFT) 31225e992a4SHeiner Kallweit #define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT) 31325e992a4SHeiner Kallweit #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) 31425e992a4SHeiner Kallweit EPHY_RXER_NUM = 0x7c, 31525e992a4SHeiner Kallweit OCPDR = 0xb0, /* OCP GPHY access */ 31625e992a4SHeiner Kallweit #define OCPDR_WRITE_CMD 0x80000000 31725e992a4SHeiner Kallweit #define OCPDR_READ_CMD 0x00000000 31825e992a4SHeiner Kallweit #define OCPDR_REG_MASK 0x7f 31925e992a4SHeiner Kallweit #define OCPDR_GPHY_REG_SHIFT 16 32025e992a4SHeiner Kallweit #define OCPDR_DATA_MASK 0xffff 32125e992a4SHeiner Kallweit OCPAR = 0xb4, 32225e992a4SHeiner Kallweit #define OCPAR_FLAG 0x80000000 32325e992a4SHeiner Kallweit #define OCPAR_GPHY_WRITE_CMD 0x8000f060 32425e992a4SHeiner Kallweit #define OCPAR_GPHY_READ_CMD 0x0000f060 32525e992a4SHeiner Kallweit GPHY_OCP = 0xb8, 32625e992a4SHeiner Kallweit RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ 32725e992a4SHeiner Kallweit MISC = 0xf0, /* 8168e only. */ 32825e992a4SHeiner Kallweit #define TXPLA_RST (1 << 29) 32925e992a4SHeiner Kallweit #define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */ 33025e992a4SHeiner Kallweit #define PWM_EN (1 << 22) 33125e992a4SHeiner Kallweit #define RXDV_GATED_EN (1 << 19) 33225e992a4SHeiner Kallweit #define EARLY_TALLY_EN (1 << 16) 33325e992a4SHeiner Kallweit }; 33425e992a4SHeiner Kallweit 335f1bce4adSHeiner Kallweit enum rtl8125_registers { 336f1bce4adSHeiner Kallweit IntrMask_8125 = 0x38, 337f1bce4adSHeiner Kallweit IntrStatus_8125 = 0x3c, 338f1bce4adSHeiner Kallweit TxPoll_8125 = 0x90, 339f1bce4adSHeiner Kallweit MAC0_BKP = 0x19e0, 340f1bce4adSHeiner Kallweit }; 341f1bce4adSHeiner Kallweit 342f1bce4adSHeiner Kallweit #define RX_VLAN_INNER_8125 BIT(22) 343f1bce4adSHeiner Kallweit #define RX_VLAN_OUTER_8125 BIT(23) 344f1bce4adSHeiner Kallweit #define RX_VLAN_8125 (RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125) 345f1bce4adSHeiner Kallweit 346f1bce4adSHeiner Kallweit #define RX_FETCH_DFLT_8125 (8 << 27) 347f1bce4adSHeiner Kallweit 34825e992a4SHeiner Kallweit enum rtl_register_content { 34925e992a4SHeiner Kallweit /* InterruptStatusBits */ 35025e992a4SHeiner Kallweit SYSErr = 0x8000, 35125e992a4SHeiner Kallweit PCSTimeout = 0x4000, 35225e992a4SHeiner Kallweit SWInt = 0x0100, 35325e992a4SHeiner Kallweit TxDescUnavail = 0x0080, 35425e992a4SHeiner Kallweit RxFIFOOver = 0x0040, 35525e992a4SHeiner Kallweit LinkChg = 0x0020, 35625e992a4SHeiner Kallweit RxOverflow = 0x0010, 35725e992a4SHeiner Kallweit TxErr = 0x0008, 35825e992a4SHeiner Kallweit TxOK = 0x0004, 35925e992a4SHeiner Kallweit RxErr = 0x0002, 36025e992a4SHeiner Kallweit RxOK = 0x0001, 36125e992a4SHeiner Kallweit 36225e992a4SHeiner Kallweit /* RxStatusDesc */ 36325e992a4SHeiner Kallweit RxRWT = (1 << 22), 36425e992a4SHeiner Kallweit RxRES = (1 << 21), 36525e992a4SHeiner Kallweit RxRUNT = (1 << 20), 36625e992a4SHeiner Kallweit RxCRC = (1 << 19), 36725e992a4SHeiner Kallweit 36825e992a4SHeiner Kallweit /* ChipCmdBits */ 36925e992a4SHeiner Kallweit StopReq = 0x80, 37025e992a4SHeiner Kallweit CmdReset = 0x10, 37125e992a4SHeiner Kallweit CmdRxEnb = 0x08, 37225e992a4SHeiner Kallweit CmdTxEnb = 0x04, 37325e992a4SHeiner Kallweit RxBufEmpty = 0x01, 37425e992a4SHeiner Kallweit 37525e992a4SHeiner Kallweit /* TXPoll register p.5 */ 37625e992a4SHeiner Kallweit HPQ = 0x80, /* Poll cmd on the high prio queue */ 37725e992a4SHeiner Kallweit NPQ = 0x40, /* Poll cmd on the low prio queue */ 37825e992a4SHeiner Kallweit FSWInt = 0x01, /* Forced software interrupt */ 37925e992a4SHeiner Kallweit 38025e992a4SHeiner Kallweit /* Cfg9346Bits */ 38125e992a4SHeiner Kallweit Cfg9346_Lock = 0x00, 38225e992a4SHeiner Kallweit Cfg9346_Unlock = 0xc0, 38325e992a4SHeiner Kallweit 38425e992a4SHeiner Kallweit /* rx_mode_bits */ 38525e992a4SHeiner Kallweit AcceptErr = 0x20, 38625e992a4SHeiner Kallweit AcceptRunt = 0x10, 38710478283SHeiner Kallweit #define RX_CONFIG_ACCEPT_ERR_MASK 0x30 38825e992a4SHeiner Kallweit AcceptBroadcast = 0x08, 38925e992a4SHeiner Kallweit AcceptMulticast = 0x04, 39025e992a4SHeiner Kallweit AcceptMyPhys = 0x02, 39125e992a4SHeiner Kallweit AcceptAllPhys = 0x01, 39210478283SHeiner Kallweit #define RX_CONFIG_ACCEPT_OK_MASK 0x0f 39325e992a4SHeiner Kallweit #define RX_CONFIG_ACCEPT_MASK 0x3f 39425e992a4SHeiner Kallweit 39525e992a4SHeiner Kallweit /* TxConfigBits */ 39625e992a4SHeiner Kallweit TxInterFrameGapShift = 24, 39725e992a4SHeiner Kallweit TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ 39825e992a4SHeiner Kallweit 39925e992a4SHeiner Kallweit /* Config1 register p.24 */ 40025e992a4SHeiner Kallweit LEDS1 = (1 << 7), 40125e992a4SHeiner Kallweit LEDS0 = (1 << 6), 40225e992a4SHeiner Kallweit Speed_down = (1 << 4), 40325e992a4SHeiner Kallweit MEMMAP = (1 << 3), 40425e992a4SHeiner Kallweit IOMAP = (1 << 2), 40525e992a4SHeiner Kallweit VPD = (1 << 1), 40625e992a4SHeiner Kallweit PMEnable = (1 << 0), /* Power Management Enable */ 40725e992a4SHeiner Kallweit 40825e992a4SHeiner Kallweit /* Config2 register p. 25 */ 40925e992a4SHeiner Kallweit ClkReqEn = (1 << 7), /* Clock Request Enable */ 41025e992a4SHeiner Kallweit MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ 41125e992a4SHeiner Kallweit PCI_Clock_66MHz = 0x01, 41225e992a4SHeiner Kallweit PCI_Clock_33MHz = 0x00, 41325e992a4SHeiner Kallweit 41425e992a4SHeiner Kallweit /* Config3 register p.25 */ 41525e992a4SHeiner Kallweit MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ 41625e992a4SHeiner Kallweit LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ 41725e992a4SHeiner Kallweit Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */ 41825e992a4SHeiner Kallweit Rdy_to_L23 = (1 << 1), /* L23 Enable */ 41925e992a4SHeiner Kallweit Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ 42025e992a4SHeiner Kallweit 42125e992a4SHeiner Kallweit /* Config4 register */ 42225e992a4SHeiner Kallweit Jumbo_En1 = (1 << 1), /* 8168 only. Reserved in the 8168b */ 42325e992a4SHeiner Kallweit 42425e992a4SHeiner Kallweit /* Config5 register p.27 */ 42525e992a4SHeiner Kallweit BWF = (1 << 6), /* Accept Broadcast wakeup frame */ 42625e992a4SHeiner Kallweit MWF = (1 << 5), /* Accept Multicast wakeup frame */ 42725e992a4SHeiner Kallweit UWF = (1 << 4), /* Accept Unicast wakeup frame */ 42825e992a4SHeiner Kallweit Spi_en = (1 << 3), 42925e992a4SHeiner Kallweit LanWake = (1 << 1), /* LanWake enable/disable */ 43025e992a4SHeiner Kallweit PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ 43125e992a4SHeiner Kallweit ASPM_en = (1 << 0), /* ASPM enable */ 43225e992a4SHeiner Kallweit 43325e992a4SHeiner Kallweit /* CPlusCmd p.31 */ 43425e992a4SHeiner Kallweit EnableBist = (1 << 15), // 8168 8101 43525e992a4SHeiner Kallweit Mac_dbgo_oe = (1 << 14), // 8168 8101 43609e65335SHeiner Kallweit EnAnaPLL = (1 << 14), // 8169 43725e992a4SHeiner Kallweit Normal_mode = (1 << 13), // unused 43825e992a4SHeiner Kallweit Force_half_dup = (1 << 12), // 8168 8101 43925e992a4SHeiner Kallweit Force_rxflow_en = (1 << 11), // 8168 8101 44025e992a4SHeiner Kallweit Force_txflow_en = (1 << 10), // 8168 8101 44125e992a4SHeiner Kallweit Cxpl_dbg_sel = (1 << 9), // 8168 8101 44225e992a4SHeiner Kallweit ASF = (1 << 8), // 8168 8101 44325e992a4SHeiner Kallweit PktCntrDisable = (1 << 7), // 8168 8101 44425e992a4SHeiner Kallweit Mac_dbgo_sel = 0x001c, // 8168 44525e992a4SHeiner Kallweit RxVlan = (1 << 6), 44625e992a4SHeiner Kallweit RxChkSum = (1 << 5), 44725e992a4SHeiner Kallweit PCIDAC = (1 << 4), 44825e992a4SHeiner Kallweit PCIMulRW = (1 << 3), 44925e992a4SHeiner Kallweit #define INTT_MASK GENMASK(1, 0) 450bc73241eSHeiner Kallweit #define CPCMD_MASK (Normal_mode | RxVlan | RxChkSum | INTT_MASK) 45125e992a4SHeiner Kallweit 45225e992a4SHeiner Kallweit /* rtl8169_PHYstatus */ 45325e992a4SHeiner Kallweit TBI_Enable = 0x80, 45425e992a4SHeiner Kallweit TxFlowCtrl = 0x40, 45525e992a4SHeiner Kallweit RxFlowCtrl = 0x20, 45625e992a4SHeiner Kallweit _1000bpsF = 0x10, 45725e992a4SHeiner Kallweit _100bps = 0x08, 45825e992a4SHeiner Kallweit _10bps = 0x04, 45925e992a4SHeiner Kallweit LinkStatus = 0x02, 46025e992a4SHeiner Kallweit FullDup = 0x01, 46125e992a4SHeiner Kallweit 46225e992a4SHeiner Kallweit /* ResetCounterCommand */ 46325e992a4SHeiner Kallweit CounterReset = 0x1, 46425e992a4SHeiner Kallweit 46525e992a4SHeiner Kallweit /* DumpCounterCommand */ 46625e992a4SHeiner Kallweit CounterDump = 0x8, 46725e992a4SHeiner Kallweit 46825e992a4SHeiner Kallweit /* magic enable v2 */ 46925e992a4SHeiner Kallweit MagicPacket_v2 = (1 << 16), /* Wake up when receives a Magic Packet */ 47025e992a4SHeiner Kallweit }; 47125e992a4SHeiner Kallweit 47225e992a4SHeiner Kallweit enum rtl_desc_bit { 47325e992a4SHeiner Kallweit /* First doubleword. */ 47425e992a4SHeiner Kallweit DescOwn = (1 << 31), /* Descriptor is owned by NIC */ 47525e992a4SHeiner Kallweit RingEnd = (1 << 30), /* End of descriptor ring */ 47625e992a4SHeiner Kallweit FirstFrag = (1 << 29), /* First segment of a packet */ 47725e992a4SHeiner Kallweit LastFrag = (1 << 28), /* Final segment of a packet */ 47825e992a4SHeiner Kallweit }; 47925e992a4SHeiner Kallweit 48025e992a4SHeiner Kallweit /* Generic case. */ 48125e992a4SHeiner Kallweit enum rtl_tx_desc_bit { 48225e992a4SHeiner Kallweit /* First doubleword. */ 48325e992a4SHeiner Kallweit TD_LSO = (1 << 27), /* Large Send Offload */ 48425e992a4SHeiner Kallweit #define TD_MSS_MAX 0x07ffu /* MSS value */ 48525e992a4SHeiner Kallweit 48625e992a4SHeiner Kallweit /* Second doubleword. */ 48725e992a4SHeiner Kallweit TxVlanTag = (1 << 17), /* Add VLAN tag */ 48825e992a4SHeiner Kallweit }; 48925e992a4SHeiner Kallweit 49025e992a4SHeiner Kallweit /* 8169, 8168b and 810x except 8102e. */ 49125e992a4SHeiner Kallweit enum rtl_tx_desc_bit_0 { 49225e992a4SHeiner Kallweit /* First doubleword. */ 49325e992a4SHeiner Kallweit #define TD0_MSS_SHIFT 16 /* MSS position (11 bits) */ 49425e992a4SHeiner Kallweit TD0_TCP_CS = (1 << 16), /* Calculate TCP/IP checksum */ 49525e992a4SHeiner Kallweit TD0_UDP_CS = (1 << 17), /* Calculate UDP/IP checksum */ 49625e992a4SHeiner Kallweit TD0_IP_CS = (1 << 18), /* Calculate IP checksum */ 49725e992a4SHeiner Kallweit }; 49825e992a4SHeiner Kallweit 49925e992a4SHeiner Kallweit /* 8102e, 8168c and beyond. */ 50025e992a4SHeiner Kallweit enum rtl_tx_desc_bit_1 { 50125e992a4SHeiner Kallweit /* First doubleword. */ 50225e992a4SHeiner Kallweit TD1_GTSENV4 = (1 << 26), /* Giant Send for IPv4 */ 50325e992a4SHeiner Kallweit TD1_GTSENV6 = (1 << 25), /* Giant Send for IPv6 */ 50425e992a4SHeiner Kallweit #define GTTCPHO_SHIFT 18 505e64e0c89SHeiner Kallweit #define GTTCPHO_MAX 0x7f 50625e992a4SHeiner Kallweit 50725e992a4SHeiner Kallweit /* Second doubleword. */ 50825e992a4SHeiner Kallweit #define TCPHO_SHIFT 18 509e64e0c89SHeiner Kallweit #define TCPHO_MAX 0x3ff 51025e992a4SHeiner Kallweit #define TD1_MSS_SHIFT 18 /* MSS position (11 bits) */ 51125e992a4SHeiner Kallweit TD1_IPv6_CS = (1 << 28), /* Calculate IPv6 checksum */ 51225e992a4SHeiner Kallweit TD1_IPv4_CS = (1 << 29), /* Calculate IPv4 checksum */ 51325e992a4SHeiner Kallweit TD1_TCP_CS = (1 << 30), /* Calculate TCP/IP checksum */ 51425e992a4SHeiner Kallweit TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */ 51525e992a4SHeiner Kallweit }; 51625e992a4SHeiner Kallweit 51725e992a4SHeiner Kallweit enum rtl_rx_desc_bit { 51825e992a4SHeiner Kallweit /* Rx private */ 51925e992a4SHeiner Kallweit PID1 = (1 << 18), /* Protocol ID bit 1/2 */ 52025e992a4SHeiner Kallweit PID0 = (1 << 17), /* Protocol ID bit 0/2 */ 52125e992a4SHeiner Kallweit 52225e992a4SHeiner Kallweit #define RxProtoUDP (PID1) 52325e992a4SHeiner Kallweit #define RxProtoTCP (PID0) 52425e992a4SHeiner Kallweit #define RxProtoIP (PID1 | PID0) 52525e992a4SHeiner Kallweit #define RxProtoMask RxProtoIP 52625e992a4SHeiner Kallweit 52725e992a4SHeiner Kallweit IPFail = (1 << 16), /* IP checksum failed */ 52825e992a4SHeiner Kallweit UDPFail = (1 << 15), /* UDP/IP checksum failed */ 52925e992a4SHeiner Kallweit TCPFail = (1 << 14), /* TCP/IP checksum failed */ 53025e992a4SHeiner Kallweit RxVlanTag = (1 << 16), /* VLAN tag available */ 53125e992a4SHeiner Kallweit }; 53225e992a4SHeiner Kallweit 53325e992a4SHeiner Kallweit #define RsvdMask 0x3fffc000 53425e992a4SHeiner Kallweit 5350170d594SHeiner Kallweit #define RTL_GSO_MAX_SIZE_V1 32000 5360170d594SHeiner Kallweit #define RTL_GSO_MAX_SEGS_V1 24 5370170d594SHeiner Kallweit #define RTL_GSO_MAX_SIZE_V2 64000 5380170d594SHeiner Kallweit #define RTL_GSO_MAX_SEGS_V2 64 5390170d594SHeiner Kallweit 54025e992a4SHeiner Kallweit struct TxDesc { 54125e992a4SHeiner Kallweit __le32 opts1; 54225e992a4SHeiner Kallweit __le32 opts2; 54325e992a4SHeiner Kallweit __le64 addr; 54425e992a4SHeiner Kallweit }; 54525e992a4SHeiner Kallweit 54625e992a4SHeiner Kallweit struct RxDesc { 54725e992a4SHeiner Kallweit __le32 opts1; 54825e992a4SHeiner Kallweit __le32 opts2; 54925e992a4SHeiner Kallweit __le64 addr; 55025e992a4SHeiner Kallweit }; 55125e992a4SHeiner Kallweit 55225e992a4SHeiner Kallweit struct ring_info { 55325e992a4SHeiner Kallweit struct sk_buff *skb; 55425e992a4SHeiner Kallweit u32 len; 55525e992a4SHeiner Kallweit }; 55625e992a4SHeiner Kallweit 55725e992a4SHeiner Kallweit struct rtl8169_counters { 55825e992a4SHeiner Kallweit __le64 tx_packets; 55925e992a4SHeiner Kallweit __le64 rx_packets; 56025e992a4SHeiner Kallweit __le64 tx_errors; 56125e992a4SHeiner Kallweit __le32 rx_errors; 56225e992a4SHeiner Kallweit __le16 rx_missed; 56325e992a4SHeiner Kallweit __le16 align_errors; 56425e992a4SHeiner Kallweit __le32 tx_one_collision; 56525e992a4SHeiner Kallweit __le32 tx_multi_collision; 56625e992a4SHeiner Kallweit __le64 rx_unicast; 56725e992a4SHeiner Kallweit __le64 rx_broadcast; 56825e992a4SHeiner Kallweit __le32 rx_multicast; 56925e992a4SHeiner Kallweit __le16 tx_aborted; 57025e992a4SHeiner Kallweit __le16 tx_underun; 57125e992a4SHeiner Kallweit }; 57225e992a4SHeiner Kallweit 57325e992a4SHeiner Kallweit struct rtl8169_tc_offsets { 57425e992a4SHeiner Kallweit bool inited; 57525e992a4SHeiner Kallweit __le64 tx_errors; 57625e992a4SHeiner Kallweit __le32 tx_multi_collision; 57725e992a4SHeiner Kallweit __le16 tx_aborted; 5780da3359aSHeiner Kallweit __le16 rx_missed; 57925e992a4SHeiner Kallweit }; 58025e992a4SHeiner Kallweit 58125e992a4SHeiner Kallweit enum rtl_flag { 58225e992a4SHeiner Kallweit RTL_FLAG_TASK_ENABLED = 0, 58325e992a4SHeiner Kallweit RTL_FLAG_TASK_RESET_PENDING, 58425e992a4SHeiner Kallweit RTL_FLAG_MAX 58525e992a4SHeiner Kallweit }; 58625e992a4SHeiner Kallweit 58725e992a4SHeiner Kallweit struct rtl8169_stats { 58825e992a4SHeiner Kallweit u64 packets; 58925e992a4SHeiner Kallweit u64 bytes; 59025e992a4SHeiner Kallweit struct u64_stats_sync syncp; 59125e992a4SHeiner Kallweit }; 59225e992a4SHeiner Kallweit 59325e992a4SHeiner Kallweit struct rtl8169_private { 59425e992a4SHeiner Kallweit void __iomem *mmio_addr; /* memory map physical address */ 59525e992a4SHeiner Kallweit struct pci_dev *pci_dev; 59625e992a4SHeiner Kallweit struct net_device *dev; 59725e992a4SHeiner Kallweit struct phy_device *phydev; 59825e992a4SHeiner Kallweit struct napi_struct napi; 59925e992a4SHeiner Kallweit enum mac_version mac_version; 60025e992a4SHeiner Kallweit u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ 60125e992a4SHeiner Kallweit u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ 60225e992a4SHeiner Kallweit u32 dirty_tx; 60325e992a4SHeiner Kallweit struct rtl8169_stats rx_stats; 60425e992a4SHeiner Kallweit struct rtl8169_stats tx_stats; 60525e992a4SHeiner Kallweit struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ 60625e992a4SHeiner Kallweit struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ 60725e992a4SHeiner Kallweit dma_addr_t TxPhyAddr; 60825e992a4SHeiner Kallweit dma_addr_t RxPhyAddr; 60932879f00SHeiner Kallweit struct page *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */ 61025e992a4SHeiner Kallweit struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ 61125e992a4SHeiner Kallweit u16 cp_cmd; 612c1d532d2SHeiner Kallweit u32 irq_mask; 61325e992a4SHeiner Kallweit struct clk *clk; 61425e992a4SHeiner Kallweit 61525e992a4SHeiner Kallweit struct { 61625e992a4SHeiner Kallweit DECLARE_BITMAP(flags, RTL_FLAG_MAX); 61725e992a4SHeiner Kallweit struct mutex mutex; 61825e992a4SHeiner Kallweit struct work_struct work; 61925e992a4SHeiner Kallweit } wk; 62025e992a4SHeiner Kallweit 62125e992a4SHeiner Kallweit unsigned irq_enabled:1; 62225e992a4SHeiner Kallweit unsigned supports_gmii:1; 62362b1b3b3SHeiner Kallweit unsigned aspm_manageable:1; 62425e992a4SHeiner Kallweit dma_addr_t counters_phys_addr; 62525e992a4SHeiner Kallweit struct rtl8169_counters *counters; 62625e992a4SHeiner Kallweit struct rtl8169_tc_offsets tc_offset; 62725e992a4SHeiner Kallweit u32 saved_wolopts; 6287ec3f872SHeiner Kallweit int eee_adv; 62925e992a4SHeiner Kallweit 63025e992a4SHeiner Kallweit const char *fw_name; 6318197f9d2SHeiner Kallweit struct rtl_fw *rtl_fw; 63225e992a4SHeiner Kallweit 63325e992a4SHeiner Kallweit u32 ocp_base; 63425e992a4SHeiner Kallweit }; 63525e992a4SHeiner Kallweit 63625e992a4SHeiner Kallweit typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); 63725e992a4SHeiner Kallweit 63825e992a4SHeiner Kallweit MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); 63925e992a4SHeiner Kallweit MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); 64025e992a4SHeiner Kallweit MODULE_SOFTDEP("pre: realtek"); 64125e992a4SHeiner Kallweit MODULE_LICENSE("GPL"); 64225e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168D_1); 64325e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168D_2); 64425e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_1); 64525e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_2); 64625e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_3); 64725e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8105E_1); 64825e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168F_1); 64925e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168F_2); 65025e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8402_1); 65125e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8411_1); 65225e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8411_2); 65325e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8106E_1); 65425e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8106E_2); 65525e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168G_2); 65625e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168G_3); 65725e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168H_1); 65825e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168H_2); 659229c1e0dSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168FP_3); 66025e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8107E_1); 66125e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8107E_2); 66202bf642bSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8125A_3); 66325e992a4SHeiner Kallweit 66425e992a4SHeiner Kallweit static inline struct device *tp_to_dev(struct rtl8169_private *tp) 66525e992a4SHeiner Kallweit { 66625e992a4SHeiner Kallweit return &tp->pci_dev->dev; 66725e992a4SHeiner Kallweit } 66825e992a4SHeiner Kallweit 66925e992a4SHeiner Kallweit static void rtl_lock_work(struct rtl8169_private *tp) 67025e992a4SHeiner Kallweit { 67125e992a4SHeiner Kallweit mutex_lock(&tp->wk.mutex); 67225e992a4SHeiner Kallweit } 67325e992a4SHeiner Kallweit 67425e992a4SHeiner Kallweit static void rtl_unlock_work(struct rtl8169_private *tp) 67525e992a4SHeiner Kallweit { 67625e992a4SHeiner Kallweit mutex_unlock(&tp->wk.mutex); 67725e992a4SHeiner Kallweit } 67825e992a4SHeiner Kallweit 67925e992a4SHeiner Kallweit static void rtl_lock_config_regs(struct rtl8169_private *tp) 68025e992a4SHeiner Kallweit { 68125e992a4SHeiner Kallweit RTL_W8(tp, Cfg9346, Cfg9346_Lock); 68225e992a4SHeiner Kallweit } 68325e992a4SHeiner Kallweit 68425e992a4SHeiner Kallweit static void rtl_unlock_config_regs(struct rtl8169_private *tp) 68525e992a4SHeiner Kallweit { 68625e992a4SHeiner Kallweit RTL_W8(tp, Cfg9346, Cfg9346_Unlock); 68725e992a4SHeiner Kallweit } 68825e992a4SHeiner Kallweit 689711463f8SHeiner Kallweit static void rtl_pci_commit(struct rtl8169_private *tp) 690711463f8SHeiner Kallweit { 691711463f8SHeiner Kallweit /* Read an arbitrary register to commit a preceding PCI write */ 692711463f8SHeiner Kallweit RTL_R8(tp, ChipCmd); 693711463f8SHeiner Kallweit } 694711463f8SHeiner Kallweit 695f1bce4adSHeiner Kallweit static bool rtl_is_8125(struct rtl8169_private *tp) 696f1bce4adSHeiner Kallweit { 697f1bce4adSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_60; 698f1bce4adSHeiner Kallweit } 699f1bce4adSHeiner Kallweit 7009e9f33baSHeiner Kallweit static bool rtl_is_8168evl_up(struct rtl8169_private *tp) 7019e9f33baSHeiner Kallweit { 7029e9f33baSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_34 && 703c623305bSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_39 && 7041287723aSHeiner Kallweit tp->mac_version <= RTL_GIGA_MAC_VER_52; 7059e9f33baSHeiner Kallweit } 7069e9f33baSHeiner Kallweit 7072e779ddbSHeiner Kallweit static bool rtl_supports_eee(struct rtl8169_private *tp) 7082e779ddbSHeiner Kallweit { 7092e779ddbSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_34 && 7102e779ddbSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_37 && 7112e779ddbSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_39; 7122e779ddbSHeiner Kallweit } 7132e779ddbSHeiner Kallweit 714ce37115eSHeiner Kallweit static void rtl_read_mac_from_reg(struct rtl8169_private *tp, u8 *mac, int reg) 715ce37115eSHeiner Kallweit { 716ce37115eSHeiner Kallweit int i; 717ce37115eSHeiner Kallweit 718ce37115eSHeiner Kallweit for (i = 0; i < ETH_ALEN; i++) 719ce37115eSHeiner Kallweit mac[i] = RTL_R8(tp, reg + i); 720ce37115eSHeiner Kallweit } 721ce37115eSHeiner Kallweit 72225e992a4SHeiner Kallweit struct rtl_cond { 72325e992a4SHeiner Kallweit bool (*check)(struct rtl8169_private *); 72425e992a4SHeiner Kallweit const char *msg; 72525e992a4SHeiner Kallweit }; 72625e992a4SHeiner Kallweit 72725e992a4SHeiner Kallweit static bool rtl_loop_wait(struct rtl8169_private *tp, const struct rtl_cond *c, 728d6836ef0SHeiner Kallweit unsigned long usecs, int n, bool high) 72925e992a4SHeiner Kallweit { 73025e992a4SHeiner Kallweit int i; 73125e992a4SHeiner Kallweit 73225e992a4SHeiner Kallweit for (i = 0; i < n; i++) { 73325e992a4SHeiner Kallweit if (c->check(tp) == high) 73425e992a4SHeiner Kallweit return true; 735d6836ef0SHeiner Kallweit fsleep(usecs); 73625e992a4SHeiner Kallweit } 73793882c6fSHeiner Kallweit 73893882c6fSHeiner Kallweit if (net_ratelimit()) 739d6836ef0SHeiner Kallweit netdev_err(tp->dev, "%s == %d (loop: %d, delay: %lu).\n", 740d6836ef0SHeiner Kallweit c->msg, !high, n, usecs); 74125e992a4SHeiner Kallweit return false; 74225e992a4SHeiner Kallweit } 74325e992a4SHeiner Kallweit 744d6836ef0SHeiner Kallweit static bool rtl_loop_wait_high(struct rtl8169_private *tp, 74525e992a4SHeiner Kallweit const struct rtl_cond *c, 746d6836ef0SHeiner Kallweit unsigned long d, int n) 74725e992a4SHeiner Kallweit { 748d6836ef0SHeiner Kallweit return rtl_loop_wait(tp, c, d, n, true); 74925e992a4SHeiner Kallweit } 75025e992a4SHeiner Kallweit 751d6836ef0SHeiner Kallweit static bool rtl_loop_wait_low(struct rtl8169_private *tp, 75225e992a4SHeiner Kallweit const struct rtl_cond *c, 753d6836ef0SHeiner Kallweit unsigned long d, int n) 75425e992a4SHeiner Kallweit { 755d6836ef0SHeiner Kallweit return rtl_loop_wait(tp, c, d, n, false); 75625e992a4SHeiner Kallweit } 75725e992a4SHeiner Kallweit 75825e992a4SHeiner Kallweit #define DECLARE_RTL_COND(name) \ 75925e992a4SHeiner Kallweit static bool name ## _check(struct rtl8169_private *); \ 76025e992a4SHeiner Kallweit \ 76125e992a4SHeiner Kallweit static const struct rtl_cond name = { \ 76225e992a4SHeiner Kallweit .check = name ## _check, \ 76325e992a4SHeiner Kallweit .msg = #name \ 76425e992a4SHeiner Kallweit }; \ 76525e992a4SHeiner Kallweit \ 76625e992a4SHeiner Kallweit static bool name ## _check(struct rtl8169_private *tp) 76725e992a4SHeiner Kallweit 76825e992a4SHeiner Kallweit static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg) 76925e992a4SHeiner Kallweit { 77025e992a4SHeiner Kallweit if (reg & 0xffff0001) { 77193882c6fSHeiner Kallweit if (net_ratelimit()) 77293882c6fSHeiner Kallweit netdev_err(tp->dev, "Invalid ocp reg %x!\n", reg); 77325e992a4SHeiner Kallweit return true; 77425e992a4SHeiner Kallweit } 77525e992a4SHeiner Kallweit return false; 77625e992a4SHeiner Kallweit } 77725e992a4SHeiner Kallweit 77825e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocp_gphy_cond) 77925e992a4SHeiner Kallweit { 78025e992a4SHeiner Kallweit return RTL_R32(tp, GPHY_OCP) & OCPAR_FLAG; 78125e992a4SHeiner Kallweit } 78225e992a4SHeiner Kallweit 78325e992a4SHeiner Kallweit static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) 78425e992a4SHeiner Kallweit { 78525e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 78625e992a4SHeiner Kallweit return; 78725e992a4SHeiner Kallweit 78825e992a4SHeiner Kallweit RTL_W32(tp, GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); 78925e992a4SHeiner Kallweit 790d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10); 79125e992a4SHeiner Kallweit } 79225e992a4SHeiner Kallweit 7939b994b4aSHeiner Kallweit static int r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) 79425e992a4SHeiner Kallweit { 79525e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 79625e992a4SHeiner Kallweit return 0; 79725e992a4SHeiner Kallweit 79825e992a4SHeiner Kallweit RTL_W32(tp, GPHY_OCP, reg << 15); 79925e992a4SHeiner Kallweit 800d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ? 8019b994b4aSHeiner Kallweit (RTL_R32(tp, GPHY_OCP) & 0xffff) : -ETIMEDOUT; 80225e992a4SHeiner Kallweit } 80325e992a4SHeiner Kallweit 80425e992a4SHeiner Kallweit static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) 80525e992a4SHeiner Kallweit { 80625e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 80725e992a4SHeiner Kallweit return; 80825e992a4SHeiner Kallweit 80925e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, OCPAR_FLAG | (reg << 15) | data); 81025e992a4SHeiner Kallweit } 81125e992a4SHeiner Kallweit 81225e992a4SHeiner Kallweit static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) 81325e992a4SHeiner Kallweit { 81425e992a4SHeiner Kallweit if (rtl_ocp_reg_failure(tp, reg)) 81525e992a4SHeiner Kallweit return 0; 81625e992a4SHeiner Kallweit 81725e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, reg << 15); 81825e992a4SHeiner Kallweit 81925e992a4SHeiner Kallweit return RTL_R32(tp, OCPDR); 82025e992a4SHeiner Kallweit } 82125e992a4SHeiner Kallweit 822ef712edeSHeiner Kallweit static void r8168_mac_ocp_modify(struct rtl8169_private *tp, u32 reg, u16 mask, 823ef712edeSHeiner Kallweit u16 set) 824ef712edeSHeiner Kallweit { 825ef712edeSHeiner Kallweit u16 data = r8168_mac_ocp_read(tp, reg); 826ef712edeSHeiner Kallweit 827ef712edeSHeiner Kallweit r8168_mac_ocp_write(tp, reg, (data & ~mask) | set); 828ef712edeSHeiner Kallweit } 829ef712edeSHeiner Kallweit 83025e992a4SHeiner Kallweit static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) 83125e992a4SHeiner Kallweit { 83225e992a4SHeiner Kallweit if (reg == 0x1f) { 83325e992a4SHeiner Kallweit tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE; 83425e992a4SHeiner Kallweit return; 83525e992a4SHeiner Kallweit } 83625e992a4SHeiner Kallweit 83725e992a4SHeiner Kallweit if (tp->ocp_base != OCP_STD_PHY_BASE) 83825e992a4SHeiner Kallweit reg -= 0x10; 83925e992a4SHeiner Kallweit 84025e992a4SHeiner Kallweit r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value); 84125e992a4SHeiner Kallweit } 84225e992a4SHeiner Kallweit 84325e992a4SHeiner Kallweit static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) 84425e992a4SHeiner Kallweit { 8459c6850feSHeiner Kallweit if (reg == 0x1f) 8469c6850feSHeiner Kallweit return tp->ocp_base == OCP_STD_PHY_BASE ? 0 : tp->ocp_base >> 4; 8479c6850feSHeiner Kallweit 84825e992a4SHeiner Kallweit if (tp->ocp_base != OCP_STD_PHY_BASE) 84925e992a4SHeiner Kallweit reg -= 0x10; 85025e992a4SHeiner Kallweit 85125e992a4SHeiner Kallweit return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); 85225e992a4SHeiner Kallweit } 85325e992a4SHeiner Kallweit 85425e992a4SHeiner Kallweit static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value) 85525e992a4SHeiner Kallweit { 85625e992a4SHeiner Kallweit if (reg == 0x1f) { 85725e992a4SHeiner Kallweit tp->ocp_base = value << 4; 85825e992a4SHeiner Kallweit return; 85925e992a4SHeiner Kallweit } 86025e992a4SHeiner Kallweit 86125e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, tp->ocp_base + reg, value); 86225e992a4SHeiner Kallweit } 86325e992a4SHeiner Kallweit 86425e992a4SHeiner Kallweit static int mac_mcu_read(struct rtl8169_private *tp, int reg) 86525e992a4SHeiner Kallweit { 86625e992a4SHeiner Kallweit return r8168_mac_ocp_read(tp, tp->ocp_base + reg); 86725e992a4SHeiner Kallweit } 86825e992a4SHeiner Kallweit 86925e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_phyar_cond) 87025e992a4SHeiner Kallweit { 87125e992a4SHeiner Kallweit return RTL_R32(tp, PHYAR) & 0x80000000; 87225e992a4SHeiner Kallweit } 87325e992a4SHeiner Kallweit 87425e992a4SHeiner Kallweit static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value) 87525e992a4SHeiner Kallweit { 87625e992a4SHeiner Kallweit RTL_W32(tp, PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff)); 87725e992a4SHeiner Kallweit 878d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_phyar_cond, 25, 20); 87925e992a4SHeiner Kallweit /* 88025e992a4SHeiner Kallweit * According to hardware specs a 20us delay is required after write 88125e992a4SHeiner Kallweit * complete indication, but before sending next command. 88225e992a4SHeiner Kallweit */ 88325e992a4SHeiner Kallweit udelay(20); 88425e992a4SHeiner Kallweit } 88525e992a4SHeiner Kallweit 88625e992a4SHeiner Kallweit static int r8169_mdio_read(struct rtl8169_private *tp, int reg) 88725e992a4SHeiner Kallweit { 88825e992a4SHeiner Kallweit int value; 88925e992a4SHeiner Kallweit 89025e992a4SHeiner Kallweit RTL_W32(tp, PHYAR, 0x0 | (reg & 0x1f) << 16); 89125e992a4SHeiner Kallweit 892d6836ef0SHeiner Kallweit value = rtl_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ? 8939b994b4aSHeiner Kallweit RTL_R32(tp, PHYAR) & 0xffff : -ETIMEDOUT; 89425e992a4SHeiner Kallweit 89525e992a4SHeiner Kallweit /* 89625e992a4SHeiner Kallweit * According to hardware specs a 20us delay is required after read 89725e992a4SHeiner Kallweit * complete indication, but before sending next command. 89825e992a4SHeiner Kallweit */ 89925e992a4SHeiner Kallweit udelay(20); 90025e992a4SHeiner Kallweit 90125e992a4SHeiner Kallweit return value; 90225e992a4SHeiner Kallweit } 90325e992a4SHeiner Kallweit 90425e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocpar_cond) 90525e992a4SHeiner Kallweit { 90625e992a4SHeiner Kallweit return RTL_R32(tp, OCPAR) & OCPAR_FLAG; 90725e992a4SHeiner Kallweit } 90825e992a4SHeiner Kallweit 90925e992a4SHeiner Kallweit static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data) 91025e992a4SHeiner Kallweit { 91125e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT)); 91225e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_GPHY_WRITE_CMD); 91325e992a4SHeiner Kallweit RTL_W32(tp, EPHY_RXER_NUM, 0); 91425e992a4SHeiner Kallweit 915d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100); 91625e992a4SHeiner Kallweit } 91725e992a4SHeiner Kallweit 91825e992a4SHeiner Kallweit static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value) 91925e992a4SHeiner Kallweit { 92025e992a4SHeiner Kallweit r8168dp_1_mdio_access(tp, reg, 92125e992a4SHeiner Kallweit OCPDR_WRITE_CMD | (value & OCPDR_DATA_MASK)); 92225e992a4SHeiner Kallweit } 92325e992a4SHeiner Kallweit 92425e992a4SHeiner Kallweit static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg) 92525e992a4SHeiner Kallweit { 92625e992a4SHeiner Kallweit r8168dp_1_mdio_access(tp, reg, OCPDR_READ_CMD); 92725e992a4SHeiner Kallweit 92825e992a4SHeiner Kallweit mdelay(1); 92925e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_GPHY_READ_CMD); 93025e992a4SHeiner Kallweit RTL_W32(tp, EPHY_RXER_NUM, 0); 93125e992a4SHeiner Kallweit 932d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ? 9339b994b4aSHeiner Kallweit RTL_R32(tp, OCPDR) & OCPDR_DATA_MASK : -ETIMEDOUT; 93425e992a4SHeiner Kallweit } 93525e992a4SHeiner Kallweit 93625e992a4SHeiner Kallweit #define R8168DP_1_MDIO_ACCESS_BIT 0x00020000 93725e992a4SHeiner Kallweit 93825e992a4SHeiner Kallweit static void r8168dp_2_mdio_start(struct rtl8169_private *tp) 93925e992a4SHeiner Kallweit { 94025e992a4SHeiner Kallweit RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT); 94125e992a4SHeiner Kallweit } 94225e992a4SHeiner Kallweit 94325e992a4SHeiner Kallweit static void r8168dp_2_mdio_stop(struct rtl8169_private *tp) 94425e992a4SHeiner Kallweit { 94525e992a4SHeiner Kallweit RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) | R8168DP_1_MDIO_ACCESS_BIT); 94625e992a4SHeiner Kallweit } 94725e992a4SHeiner Kallweit 94825e992a4SHeiner Kallweit static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value) 94925e992a4SHeiner Kallweit { 95025e992a4SHeiner Kallweit r8168dp_2_mdio_start(tp); 95125e992a4SHeiner Kallweit 95225e992a4SHeiner Kallweit r8169_mdio_write(tp, reg, value); 95325e992a4SHeiner Kallweit 95425e992a4SHeiner Kallweit r8168dp_2_mdio_stop(tp); 95525e992a4SHeiner Kallweit } 95625e992a4SHeiner Kallweit 95725e992a4SHeiner Kallweit static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) 95825e992a4SHeiner Kallweit { 95925e992a4SHeiner Kallweit int value; 96025e992a4SHeiner Kallweit 96162bdc8fdSHeiner Kallweit /* Work around issue with chip reporting wrong PHY ID */ 96262bdc8fdSHeiner Kallweit if (reg == MII_PHYSID2) 96362bdc8fdSHeiner Kallweit return 0xc912; 96462bdc8fdSHeiner Kallweit 96525e992a4SHeiner Kallweit r8168dp_2_mdio_start(tp); 96625e992a4SHeiner Kallweit 96725e992a4SHeiner Kallweit value = r8169_mdio_read(tp, reg); 96825e992a4SHeiner Kallweit 96925e992a4SHeiner Kallweit r8168dp_2_mdio_stop(tp); 97025e992a4SHeiner Kallweit 97125e992a4SHeiner Kallweit return value; 97225e992a4SHeiner Kallweit } 97325e992a4SHeiner Kallweit 97425e992a4SHeiner Kallweit static void rtl_writephy(struct rtl8169_private *tp, int location, int val) 97525e992a4SHeiner Kallweit { 97625e992a4SHeiner Kallweit switch (tp->mac_version) { 97725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 97825e992a4SHeiner Kallweit r8168dp_1_mdio_write(tp, location, val); 97925e992a4SHeiner Kallweit break; 98025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 98125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 98225e992a4SHeiner Kallweit r8168dp_2_mdio_write(tp, location, val); 98325e992a4SHeiner Kallweit break; 984f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61: 98525e992a4SHeiner Kallweit r8168g_mdio_write(tp, location, val); 98625e992a4SHeiner Kallweit break; 98725e992a4SHeiner Kallweit default: 98825e992a4SHeiner Kallweit r8169_mdio_write(tp, location, val); 98925e992a4SHeiner Kallweit break; 99025e992a4SHeiner Kallweit } 99125e992a4SHeiner Kallweit } 99225e992a4SHeiner Kallweit 99325e992a4SHeiner Kallweit static int rtl_readphy(struct rtl8169_private *tp, int location) 99425e992a4SHeiner Kallweit { 99525e992a4SHeiner Kallweit switch (tp->mac_version) { 99625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 99725e992a4SHeiner Kallweit return r8168dp_1_mdio_read(tp, location); 99825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 99925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 100025e992a4SHeiner Kallweit return r8168dp_2_mdio_read(tp, location); 1001f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61: 100225e992a4SHeiner Kallweit return r8168g_mdio_read(tp, location); 100325e992a4SHeiner Kallweit default: 100425e992a4SHeiner Kallweit return r8169_mdio_read(tp, location); 100525e992a4SHeiner Kallweit } 100625e992a4SHeiner Kallweit } 100725e992a4SHeiner Kallweit 100825e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ephyar_cond) 100925e992a4SHeiner Kallweit { 101025e992a4SHeiner Kallweit return RTL_R32(tp, EPHYAR) & EPHYAR_FLAG; 101125e992a4SHeiner Kallweit } 101225e992a4SHeiner Kallweit 101325e992a4SHeiner Kallweit static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value) 101425e992a4SHeiner Kallweit { 101525e992a4SHeiner Kallweit RTL_W32(tp, EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) | 101625e992a4SHeiner Kallweit (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 101725e992a4SHeiner Kallweit 1018d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100); 101925e992a4SHeiner Kallweit 102025e992a4SHeiner Kallweit udelay(10); 102125e992a4SHeiner Kallweit } 102225e992a4SHeiner Kallweit 102325e992a4SHeiner Kallweit static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr) 102425e992a4SHeiner Kallweit { 102525e992a4SHeiner Kallweit RTL_W32(tp, EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 102625e992a4SHeiner Kallweit 1027d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ? 102825e992a4SHeiner Kallweit RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0; 102925e992a4SHeiner Kallweit } 103025e992a4SHeiner Kallweit 103125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_eriar_cond) 103225e992a4SHeiner Kallweit { 103325e992a4SHeiner Kallweit return RTL_R32(tp, ERIAR) & ERIAR_FLAG; 103425e992a4SHeiner Kallweit } 103525e992a4SHeiner Kallweit 103625e992a4SHeiner Kallweit static void _rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 103725e992a4SHeiner Kallweit u32 val, int type) 103825e992a4SHeiner Kallweit { 103925e992a4SHeiner Kallweit BUG_ON((addr & 3) || (mask == 0)); 104025e992a4SHeiner Kallweit RTL_W32(tp, ERIDR, val); 104125e992a4SHeiner Kallweit RTL_W32(tp, ERIAR, ERIAR_WRITE_CMD | type | mask | addr); 104225e992a4SHeiner Kallweit 1043d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); 104425e992a4SHeiner Kallweit } 104525e992a4SHeiner Kallweit 104625e992a4SHeiner Kallweit static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 104725e992a4SHeiner Kallweit u32 val) 104825e992a4SHeiner Kallweit { 104925e992a4SHeiner Kallweit _rtl_eri_write(tp, addr, mask, val, ERIAR_EXGMAC); 105025e992a4SHeiner Kallweit } 105125e992a4SHeiner Kallweit 105225e992a4SHeiner Kallweit static u32 _rtl_eri_read(struct rtl8169_private *tp, int addr, int type) 105325e992a4SHeiner Kallweit { 105425e992a4SHeiner Kallweit RTL_W32(tp, ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr); 105525e992a4SHeiner Kallweit 1056d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? 105725e992a4SHeiner Kallweit RTL_R32(tp, ERIDR) : ~0; 105825e992a4SHeiner Kallweit } 105925e992a4SHeiner Kallweit 106025e992a4SHeiner Kallweit static u32 rtl_eri_read(struct rtl8169_private *tp, int addr) 106125e992a4SHeiner Kallweit { 106225e992a4SHeiner Kallweit return _rtl_eri_read(tp, addr, ERIAR_EXGMAC); 106325e992a4SHeiner Kallweit } 106425e992a4SHeiner Kallweit 106525e992a4SHeiner Kallweit static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p, 106625e992a4SHeiner Kallweit u32 m) 106725e992a4SHeiner Kallweit { 106825e992a4SHeiner Kallweit u32 val; 106925e992a4SHeiner Kallweit 107025e992a4SHeiner Kallweit val = rtl_eri_read(tp, addr); 107125e992a4SHeiner Kallweit rtl_eri_write(tp, addr, mask, (val & ~m) | p); 107225e992a4SHeiner Kallweit } 107325e992a4SHeiner Kallweit 107425e992a4SHeiner Kallweit static void rtl_eri_set_bits(struct rtl8169_private *tp, int addr, u32 mask, 107525e992a4SHeiner Kallweit u32 p) 107625e992a4SHeiner Kallweit { 107725e992a4SHeiner Kallweit rtl_w0w1_eri(tp, addr, mask, p, 0); 107825e992a4SHeiner Kallweit } 107925e992a4SHeiner Kallweit 108025e992a4SHeiner Kallweit static void rtl_eri_clear_bits(struct rtl8169_private *tp, int addr, u32 mask, 108125e992a4SHeiner Kallweit u32 m) 108225e992a4SHeiner Kallweit { 108325e992a4SHeiner Kallweit rtl_w0w1_eri(tp, addr, mask, 0, m); 108425e992a4SHeiner Kallweit } 108525e992a4SHeiner Kallweit 108625e992a4SHeiner Kallweit static u32 r8168dp_ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) 108725e992a4SHeiner Kallweit { 108825e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); 1089d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ? 109025e992a4SHeiner Kallweit RTL_R32(tp, OCPDR) : ~0; 109125e992a4SHeiner Kallweit } 109225e992a4SHeiner Kallweit 109325e992a4SHeiner Kallweit static u32 r8168ep_ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) 109425e992a4SHeiner Kallweit { 109525e992a4SHeiner Kallweit return _rtl_eri_read(tp, reg, ERIAR_OOB); 109625e992a4SHeiner Kallweit } 109725e992a4SHeiner Kallweit 109825e992a4SHeiner Kallweit static void r8168dp_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, 109925e992a4SHeiner Kallweit u32 data) 110025e992a4SHeiner Kallweit { 110125e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, data); 110225e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); 1103d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20); 110425e992a4SHeiner Kallweit } 110525e992a4SHeiner Kallweit 110625e992a4SHeiner Kallweit static void r8168ep_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, 110725e992a4SHeiner Kallweit u32 data) 110825e992a4SHeiner Kallweit { 110925e992a4SHeiner Kallweit _rtl_eri_write(tp, reg, ((u32)mask & 0x0f) << ERIAR_MASK_SHIFT, 111025e992a4SHeiner Kallweit data, ERIAR_OOB); 111125e992a4SHeiner Kallweit } 111225e992a4SHeiner Kallweit 111325e992a4SHeiner Kallweit static void r8168dp_oob_notify(struct rtl8169_private *tp, u8 cmd) 111425e992a4SHeiner Kallweit { 111525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe8, ERIAR_MASK_0001, cmd); 111625e992a4SHeiner Kallweit 111725e992a4SHeiner Kallweit r8168dp_ocp_write(tp, 0x1, 0x30, 0x00000001); 111825e992a4SHeiner Kallweit } 111925e992a4SHeiner Kallweit 112025e992a4SHeiner Kallweit #define OOB_CMD_RESET 0x00 112125e992a4SHeiner Kallweit #define OOB_CMD_DRIVER_START 0x05 112225e992a4SHeiner Kallweit #define OOB_CMD_DRIVER_STOP 0x06 112325e992a4SHeiner Kallweit 112425e992a4SHeiner Kallweit static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp) 112525e992a4SHeiner Kallweit { 112625e992a4SHeiner Kallweit return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10; 112725e992a4SHeiner Kallweit } 112825e992a4SHeiner Kallweit 112925e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_dp_ocp_read_cond) 113025e992a4SHeiner Kallweit { 113125e992a4SHeiner Kallweit u16 reg; 113225e992a4SHeiner Kallweit 113325e992a4SHeiner Kallweit reg = rtl8168_get_ocp_reg(tp); 113425e992a4SHeiner Kallweit 113525e992a4SHeiner Kallweit return r8168dp_ocp_read(tp, 0x0f, reg) & 0x00000800; 113625e992a4SHeiner Kallweit } 113725e992a4SHeiner Kallweit 113825e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ep_ocp_read_cond) 113925e992a4SHeiner Kallweit { 114025e992a4SHeiner Kallweit return r8168ep_ocp_read(tp, 0x0f, 0x124) & 0x00000001; 114125e992a4SHeiner Kallweit } 114225e992a4SHeiner Kallweit 114325e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocp_tx_cond) 114425e992a4SHeiner Kallweit { 114525e992a4SHeiner Kallweit return RTL_R8(tp, IBISR0) & 0x20; 114625e992a4SHeiner Kallweit } 114725e992a4SHeiner Kallweit 114825e992a4SHeiner Kallweit static void rtl8168ep_stop_cmac(struct rtl8169_private *tp) 114925e992a4SHeiner Kallweit { 115025e992a4SHeiner Kallweit RTL_W8(tp, IBCR2, RTL_R8(tp, IBCR2) & ~0x01); 1151d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_ocp_tx_cond, 50000, 2000); 115225e992a4SHeiner Kallweit RTL_W8(tp, IBISR0, RTL_R8(tp, IBISR0) | 0x20); 115325e992a4SHeiner Kallweit RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01); 115425e992a4SHeiner Kallweit } 115525e992a4SHeiner Kallweit 115625e992a4SHeiner Kallweit static void rtl8168dp_driver_start(struct rtl8169_private *tp) 115725e992a4SHeiner Kallweit { 115825e992a4SHeiner Kallweit r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START); 1159d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10); 116025e992a4SHeiner Kallweit } 116125e992a4SHeiner Kallweit 116225e992a4SHeiner Kallweit static void rtl8168ep_driver_start(struct rtl8169_private *tp) 116325e992a4SHeiner Kallweit { 116425e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START); 116525e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x30, 116625e992a4SHeiner Kallweit r8168ep_ocp_read(tp, 0x01, 0x30) | 0x01); 1167d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 10); 116825e992a4SHeiner Kallweit } 116925e992a4SHeiner Kallweit 117025e992a4SHeiner Kallweit static void rtl8168_driver_start(struct rtl8169_private *tp) 117125e992a4SHeiner Kallweit { 117225e992a4SHeiner Kallweit switch (tp->mac_version) { 117325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 117425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 117525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 117625e992a4SHeiner Kallweit rtl8168dp_driver_start(tp); 117725e992a4SHeiner Kallweit break; 11781287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 117925e992a4SHeiner Kallweit rtl8168ep_driver_start(tp); 118025e992a4SHeiner Kallweit break; 118125e992a4SHeiner Kallweit default: 118225e992a4SHeiner Kallweit BUG(); 118325e992a4SHeiner Kallweit break; 118425e992a4SHeiner Kallweit } 118525e992a4SHeiner Kallweit } 118625e992a4SHeiner Kallweit 118725e992a4SHeiner Kallweit static void rtl8168dp_driver_stop(struct rtl8169_private *tp) 118825e992a4SHeiner Kallweit { 118925e992a4SHeiner Kallweit r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP); 1190d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10); 119125e992a4SHeiner Kallweit } 119225e992a4SHeiner Kallweit 119325e992a4SHeiner Kallweit static void rtl8168ep_driver_stop(struct rtl8169_private *tp) 119425e992a4SHeiner Kallweit { 119525e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp); 119625e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP); 119725e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x30, 119825e992a4SHeiner Kallweit r8168ep_ocp_read(tp, 0x01, 0x30) | 0x01); 1199d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10); 120025e992a4SHeiner Kallweit } 120125e992a4SHeiner Kallweit 120225e992a4SHeiner Kallweit static void rtl8168_driver_stop(struct rtl8169_private *tp) 120325e992a4SHeiner Kallweit { 120425e992a4SHeiner Kallweit switch (tp->mac_version) { 120525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 120625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 120725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 120825e992a4SHeiner Kallweit rtl8168dp_driver_stop(tp); 120925e992a4SHeiner Kallweit break; 12101287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 121125e992a4SHeiner Kallweit rtl8168ep_driver_stop(tp); 121225e992a4SHeiner Kallweit break; 121325e992a4SHeiner Kallweit default: 121425e992a4SHeiner Kallweit BUG(); 121525e992a4SHeiner Kallweit break; 121625e992a4SHeiner Kallweit } 121725e992a4SHeiner Kallweit } 121825e992a4SHeiner Kallweit 121925e992a4SHeiner Kallweit static bool r8168dp_check_dash(struct rtl8169_private *tp) 122025e992a4SHeiner Kallweit { 122125e992a4SHeiner Kallweit u16 reg = rtl8168_get_ocp_reg(tp); 122225e992a4SHeiner Kallweit 122325e992a4SHeiner Kallweit return !!(r8168dp_ocp_read(tp, 0x0f, reg) & 0x00008000); 122425e992a4SHeiner Kallweit } 122525e992a4SHeiner Kallweit 122625e992a4SHeiner Kallweit static bool r8168ep_check_dash(struct rtl8169_private *tp) 122725e992a4SHeiner Kallweit { 122825e992a4SHeiner Kallweit return !!(r8168ep_ocp_read(tp, 0x0f, 0x128) & 0x00000001); 122925e992a4SHeiner Kallweit } 123025e992a4SHeiner Kallweit 123125e992a4SHeiner Kallweit static bool r8168_check_dash(struct rtl8169_private *tp) 123225e992a4SHeiner Kallweit { 123325e992a4SHeiner Kallweit switch (tp->mac_version) { 123425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 123525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 123625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 123725e992a4SHeiner Kallweit return r8168dp_check_dash(tp); 12381287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 123925e992a4SHeiner Kallweit return r8168ep_check_dash(tp); 124025e992a4SHeiner Kallweit default: 124125e992a4SHeiner Kallweit return false; 124225e992a4SHeiner Kallweit } 124325e992a4SHeiner Kallweit } 124425e992a4SHeiner Kallweit 124525e992a4SHeiner Kallweit static void rtl_reset_packet_filter(struct rtl8169_private *tp) 124625e992a4SHeiner Kallweit { 124725e992a4SHeiner Kallweit rtl_eri_clear_bits(tp, 0xdc, ERIAR_MASK_0001, BIT(0)); 124825e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0xdc, ERIAR_MASK_0001, BIT(0)); 124925e992a4SHeiner Kallweit } 125025e992a4SHeiner Kallweit 125125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_efusear_cond) 125225e992a4SHeiner Kallweit { 125325e992a4SHeiner Kallweit return RTL_R32(tp, EFUSEAR) & EFUSEAR_FLAG; 125425e992a4SHeiner Kallweit } 125525e992a4SHeiner Kallweit 12562992bdfaSHeiner Kallweit u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr) 125725e992a4SHeiner Kallweit { 125825e992a4SHeiner Kallweit RTL_W32(tp, EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT); 125925e992a4SHeiner Kallweit 1260d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ? 126125e992a4SHeiner Kallweit RTL_R32(tp, EFUSEAR) & EFUSEAR_DATA_MASK : ~0; 126225e992a4SHeiner Kallweit } 126325e992a4SHeiner Kallweit 1264c1d532d2SHeiner Kallweit static u32 rtl_get_events(struct rtl8169_private *tp) 1265c1d532d2SHeiner Kallweit { 1266f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1267f1bce4adSHeiner Kallweit return RTL_R32(tp, IntrStatus_8125); 1268f1bce4adSHeiner Kallweit else 1269c1d532d2SHeiner Kallweit return RTL_R16(tp, IntrStatus); 1270c1d532d2SHeiner Kallweit } 1271c1d532d2SHeiner Kallweit 1272c1d532d2SHeiner Kallweit static void rtl_ack_events(struct rtl8169_private *tp, u32 bits) 127325e992a4SHeiner Kallweit { 1274f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1275f1bce4adSHeiner Kallweit RTL_W32(tp, IntrStatus_8125, bits); 1276f1bce4adSHeiner Kallweit else 127725e992a4SHeiner Kallweit RTL_W16(tp, IntrStatus, bits); 127825e992a4SHeiner Kallweit } 127925e992a4SHeiner Kallweit 128025e992a4SHeiner Kallweit static void rtl_irq_disable(struct rtl8169_private *tp) 128125e992a4SHeiner Kallweit { 1282f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1283f1bce4adSHeiner Kallweit RTL_W32(tp, IntrMask_8125, 0); 1284f1bce4adSHeiner Kallweit else 128525e992a4SHeiner Kallweit RTL_W16(tp, IntrMask, 0); 128625e992a4SHeiner Kallweit tp->irq_enabled = 0; 128725e992a4SHeiner Kallweit } 128825e992a4SHeiner Kallweit 128925e992a4SHeiner Kallweit static void rtl_irq_enable(struct rtl8169_private *tp) 129025e992a4SHeiner Kallweit { 129125e992a4SHeiner Kallweit tp->irq_enabled = 1; 1292f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1293f1bce4adSHeiner Kallweit RTL_W32(tp, IntrMask_8125, tp->irq_mask); 1294f1bce4adSHeiner Kallweit else 129525e992a4SHeiner Kallweit RTL_W16(tp, IntrMask, tp->irq_mask); 129625e992a4SHeiner Kallweit } 129725e992a4SHeiner Kallweit 129825e992a4SHeiner Kallweit static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) 129925e992a4SHeiner Kallweit { 130025e992a4SHeiner Kallweit rtl_irq_disable(tp); 1301c1d532d2SHeiner Kallweit rtl_ack_events(tp, 0xffffffff); 1302711463f8SHeiner Kallweit rtl_pci_commit(tp); 130325e992a4SHeiner Kallweit } 130425e992a4SHeiner Kallweit 130525e992a4SHeiner Kallweit static void rtl_link_chg_patch(struct rtl8169_private *tp) 130625e992a4SHeiner Kallweit { 130725e992a4SHeiner Kallweit struct phy_device *phydev = tp->phydev; 130825e992a4SHeiner Kallweit 130925e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34 || 131025e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_38) { 131125e992a4SHeiner Kallweit if (phydev->speed == SPEED_1000) { 131225e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011); 131325e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 131425e992a4SHeiner Kallweit } else if (phydev->speed == SPEED_100) { 131525e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 131625e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 131725e992a4SHeiner Kallweit } else { 131825e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 131925e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f); 132025e992a4SHeiner Kallweit } 132125e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 132225e992a4SHeiner Kallweit } else if (tp->mac_version == RTL_GIGA_MAC_VER_35 || 132325e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_36) { 132425e992a4SHeiner Kallweit if (phydev->speed == SPEED_1000) { 132525e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011); 132625e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005); 132725e992a4SHeiner Kallweit } else { 132825e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f); 132925e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f); 133025e992a4SHeiner Kallweit } 133125e992a4SHeiner Kallweit } else if (tp->mac_version == RTL_GIGA_MAC_VER_37) { 133225e992a4SHeiner Kallweit if (phydev->speed == SPEED_10) { 133325e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02); 133425e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060a); 133525e992a4SHeiner Kallweit } else { 133625e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000); 133725e992a4SHeiner Kallweit } 133825e992a4SHeiner Kallweit } 133925e992a4SHeiner Kallweit } 134025e992a4SHeiner Kallweit 134125e992a4SHeiner Kallweit #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) 134225e992a4SHeiner Kallweit 134325e992a4SHeiner Kallweit static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 134425e992a4SHeiner Kallweit { 134525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 134625e992a4SHeiner Kallweit 134725e992a4SHeiner Kallweit rtl_lock_work(tp); 134825e992a4SHeiner Kallweit wol->supported = WAKE_ANY; 134925e992a4SHeiner Kallweit wol->wolopts = tp->saved_wolopts; 135025e992a4SHeiner Kallweit rtl_unlock_work(tp); 135125e992a4SHeiner Kallweit } 135225e992a4SHeiner Kallweit 135325e992a4SHeiner Kallweit static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) 135425e992a4SHeiner Kallweit { 135525e992a4SHeiner Kallweit static const struct { 135625e992a4SHeiner Kallweit u32 opt; 135725e992a4SHeiner Kallweit u16 reg; 135825e992a4SHeiner Kallweit u8 mask; 135925e992a4SHeiner Kallweit } cfg[] = { 136025e992a4SHeiner Kallweit { WAKE_PHY, Config3, LinkUp }, 136125e992a4SHeiner Kallweit { WAKE_UCAST, Config5, UWF }, 136225e992a4SHeiner Kallweit { WAKE_BCAST, Config5, BWF }, 136325e992a4SHeiner Kallweit { WAKE_MCAST, Config5, MWF }, 136425e992a4SHeiner Kallweit { WAKE_ANY, Config5, LanWake }, 136525e992a4SHeiner Kallweit { WAKE_MAGIC, Config3, MagicPacket } 136625e992a4SHeiner Kallweit }; 1367f1bce4adSHeiner Kallweit unsigned int i, tmp = ARRAY_SIZE(cfg); 136825e992a4SHeiner Kallweit u8 options; 136925e992a4SHeiner Kallweit 137025e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 137125e992a4SHeiner Kallweit 13729e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp)) { 1373f1bce4adSHeiner Kallweit tmp--; 137425e992a4SHeiner Kallweit if (wolopts & WAKE_MAGIC) 137525e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0x0dc, ERIAR_MASK_0100, 137625e992a4SHeiner Kallweit MagicPacket_v2); 137725e992a4SHeiner Kallweit else 137825e992a4SHeiner Kallweit rtl_eri_clear_bits(tp, 0x0dc, ERIAR_MASK_0100, 137925e992a4SHeiner Kallweit MagicPacket_v2); 1380f1bce4adSHeiner Kallweit } else if (rtl_is_8125(tp)) { 1381f1bce4adSHeiner Kallweit tmp--; 1382f1bce4adSHeiner Kallweit if (wolopts & WAKE_MAGIC) 1383f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b6, 0, BIT(0)); 1384f1bce4adSHeiner Kallweit else 1385f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0); 138625e992a4SHeiner Kallweit } 138725e992a4SHeiner Kallweit 138825e992a4SHeiner Kallweit for (i = 0; i < tmp; i++) { 138925e992a4SHeiner Kallweit options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; 139025e992a4SHeiner Kallweit if (wolopts & cfg[i].opt) 139125e992a4SHeiner Kallweit options |= cfg[i].mask; 139225e992a4SHeiner Kallweit RTL_W8(tp, cfg[i].reg, options); 139325e992a4SHeiner Kallweit } 139425e992a4SHeiner Kallweit 139525e992a4SHeiner Kallweit switch (tp->mac_version) { 1396edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 139725e992a4SHeiner Kallweit options = RTL_R8(tp, Config1) & ~PMEnable; 139825e992a4SHeiner Kallweit if (wolopts) 139925e992a4SHeiner Kallweit options |= PMEnable; 140025e992a4SHeiner Kallweit RTL_W8(tp, Config1, options); 140125e992a4SHeiner Kallweit break; 1402edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_34: 1403edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_37: 1404838974e1SHeiner Kallweit case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_61: 140525e992a4SHeiner Kallweit options = RTL_R8(tp, Config2) & ~PME_SIGNAL; 140625e992a4SHeiner Kallweit if (wolopts) 140725e992a4SHeiner Kallweit options |= PME_SIGNAL; 140825e992a4SHeiner Kallweit RTL_W8(tp, Config2, options); 140925e992a4SHeiner Kallweit break; 1410edcde3eeSHeiner Kallweit default: 1411edcde3eeSHeiner Kallweit break; 141225e992a4SHeiner Kallweit } 141325e992a4SHeiner Kallweit 141425e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 141525e992a4SHeiner Kallweit 141625e992a4SHeiner Kallweit device_set_wakeup_enable(tp_to_dev(tp), wolopts); 1417398fd408SHeiner Kallweit tp->dev->wol_enabled = wolopts ? 1 : 0; 141825e992a4SHeiner Kallweit } 141925e992a4SHeiner Kallweit 142025e992a4SHeiner Kallweit static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 142125e992a4SHeiner Kallweit { 142225e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 142325e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 142425e992a4SHeiner Kallweit 142525e992a4SHeiner Kallweit if (wol->wolopts & ~WAKE_ANY) 142625e992a4SHeiner Kallweit return -EINVAL; 142725e992a4SHeiner Kallweit 142825e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 142925e992a4SHeiner Kallweit 143025e992a4SHeiner Kallweit rtl_lock_work(tp); 143125e992a4SHeiner Kallweit 143225e992a4SHeiner Kallweit tp->saved_wolopts = wol->wolopts; 143325e992a4SHeiner Kallweit 143425e992a4SHeiner Kallweit if (pm_runtime_active(d)) 143525e992a4SHeiner Kallweit __rtl8169_set_wol(tp, tp->saved_wolopts); 143625e992a4SHeiner Kallweit 143725e992a4SHeiner Kallweit rtl_unlock_work(tp); 143825e992a4SHeiner Kallweit 143925e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 144025e992a4SHeiner Kallweit 144125e992a4SHeiner Kallweit return 0; 144225e992a4SHeiner Kallweit } 144325e992a4SHeiner Kallweit 144425e992a4SHeiner Kallweit static void rtl8169_get_drvinfo(struct net_device *dev, 144525e992a4SHeiner Kallweit struct ethtool_drvinfo *info) 144625e992a4SHeiner Kallweit { 144725e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 144825e992a4SHeiner Kallweit struct rtl_fw *rtl_fw = tp->rtl_fw; 144925e992a4SHeiner Kallweit 145025e992a4SHeiner Kallweit strlcpy(info->driver, MODULENAME, sizeof(info->driver)); 145125e992a4SHeiner Kallweit strlcpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); 145225e992a4SHeiner Kallweit BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); 145325e992a4SHeiner Kallweit if (rtl_fw) 145425e992a4SHeiner Kallweit strlcpy(info->fw_version, rtl_fw->version, 145525e992a4SHeiner Kallweit sizeof(info->fw_version)); 145625e992a4SHeiner Kallweit } 145725e992a4SHeiner Kallweit 145825e992a4SHeiner Kallweit static int rtl8169_get_regs_len(struct net_device *dev) 145925e992a4SHeiner Kallweit { 146025e992a4SHeiner Kallweit return R8169_REGS_SIZE; 146125e992a4SHeiner Kallweit } 146225e992a4SHeiner Kallweit 146325e992a4SHeiner Kallweit static netdev_features_t rtl8169_fix_features(struct net_device *dev, 146425e992a4SHeiner Kallweit netdev_features_t features) 146525e992a4SHeiner Kallweit { 146625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 146725e992a4SHeiner Kallweit 146825e992a4SHeiner Kallweit if (dev->mtu > TD_MSS_MAX) 146925e992a4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 147025e992a4SHeiner Kallweit 1471a8ec173aSHeiner Kallweit if (dev->mtu > ETH_DATA_LEN && 147225e992a4SHeiner Kallweit tp->mac_version > RTL_GIGA_MAC_VER_06) 14737cb83b21SHeiner Kallweit features &= ~(NETIF_F_CSUM_MASK | NETIF_F_ALL_TSO); 147425e992a4SHeiner Kallweit 147525e992a4SHeiner Kallweit return features; 147625e992a4SHeiner Kallweit } 147725e992a4SHeiner Kallweit 147810478283SHeiner Kallweit static void rtl_set_rx_config_features(struct rtl8169_private *tp, 147925e992a4SHeiner Kallweit netdev_features_t features) 148025e992a4SHeiner Kallweit { 148110478283SHeiner Kallweit u32 rx_config = RTL_R32(tp, RxConfig); 148225e992a4SHeiner Kallweit 148325e992a4SHeiner Kallweit if (features & NETIF_F_RXALL) 148410478283SHeiner Kallweit rx_config |= RX_CONFIG_ACCEPT_ERR_MASK; 148525e992a4SHeiner Kallweit else 148610478283SHeiner Kallweit rx_config &= ~RX_CONFIG_ACCEPT_ERR_MASK; 148725e992a4SHeiner Kallweit 1488f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) { 1489f1bce4adSHeiner Kallweit if (features & NETIF_F_HW_VLAN_CTAG_RX) 1490f1bce4adSHeiner Kallweit rx_config |= RX_VLAN_8125; 1491f1bce4adSHeiner Kallweit else 1492f1bce4adSHeiner Kallweit rx_config &= ~RX_VLAN_8125; 1493f1bce4adSHeiner Kallweit } 1494f1bce4adSHeiner Kallweit 149525e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, rx_config); 149610478283SHeiner Kallweit } 149710478283SHeiner Kallweit 149810478283SHeiner Kallweit static int rtl8169_set_features(struct net_device *dev, 149910478283SHeiner Kallweit netdev_features_t features) 150010478283SHeiner Kallweit { 150110478283SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 150210478283SHeiner Kallweit 150310478283SHeiner Kallweit rtl_lock_work(tp); 150410478283SHeiner Kallweit 150510478283SHeiner Kallweit rtl_set_rx_config_features(tp, features); 150625e992a4SHeiner Kallweit 150725e992a4SHeiner Kallweit if (features & NETIF_F_RXCSUM) 150825e992a4SHeiner Kallweit tp->cp_cmd |= RxChkSum; 150925e992a4SHeiner Kallweit else 151025e992a4SHeiner Kallweit tp->cp_cmd &= ~RxChkSum; 151125e992a4SHeiner Kallweit 1512f1bce4adSHeiner Kallweit if (!rtl_is_8125(tp)) { 151325e992a4SHeiner Kallweit if (features & NETIF_F_HW_VLAN_CTAG_RX) 151425e992a4SHeiner Kallweit tp->cp_cmd |= RxVlan; 151525e992a4SHeiner Kallweit else 151625e992a4SHeiner Kallweit tp->cp_cmd &= ~RxVlan; 1517f1bce4adSHeiner Kallweit } 151825e992a4SHeiner Kallweit 151925e992a4SHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 1520711463f8SHeiner Kallweit rtl_pci_commit(tp); 152125e992a4SHeiner Kallweit 152225e992a4SHeiner Kallweit rtl_unlock_work(tp); 152325e992a4SHeiner Kallweit 152425e992a4SHeiner Kallweit return 0; 152525e992a4SHeiner Kallweit } 152625e992a4SHeiner Kallweit 152725e992a4SHeiner Kallweit static inline u32 rtl8169_tx_vlan_tag(struct sk_buff *skb) 152825e992a4SHeiner Kallweit { 152925e992a4SHeiner Kallweit return (skb_vlan_tag_present(skb)) ? 15307424edbbSHeiner Kallweit TxVlanTag | swab16(skb_vlan_tag_get(skb)) : 0x00; 153125e992a4SHeiner Kallweit } 153225e992a4SHeiner Kallweit 153325e992a4SHeiner Kallweit static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) 153425e992a4SHeiner Kallweit { 153525e992a4SHeiner Kallweit u32 opts2 = le32_to_cpu(desc->opts2); 153625e992a4SHeiner Kallweit 153725e992a4SHeiner Kallweit if (opts2 & RxVlanTag) 15387424edbbSHeiner Kallweit __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), swab16(opts2 & 0xffff)); 153925e992a4SHeiner Kallweit } 154025e992a4SHeiner Kallweit 154125e992a4SHeiner Kallweit static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, 154225e992a4SHeiner Kallweit void *p) 154325e992a4SHeiner Kallweit { 154425e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 154525e992a4SHeiner Kallweit u32 __iomem *data = tp->mmio_addr; 154625e992a4SHeiner Kallweit u32 *dw = p; 154725e992a4SHeiner Kallweit int i; 154825e992a4SHeiner Kallweit 154925e992a4SHeiner Kallweit rtl_lock_work(tp); 155025e992a4SHeiner Kallweit for (i = 0; i < R8169_REGS_SIZE; i += 4) 155125e992a4SHeiner Kallweit memcpy_fromio(dw++, data++, 4); 155225e992a4SHeiner Kallweit rtl_unlock_work(tp); 155325e992a4SHeiner Kallweit } 155425e992a4SHeiner Kallweit 155525e992a4SHeiner Kallweit static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = { 155625e992a4SHeiner Kallweit "tx_packets", 155725e992a4SHeiner Kallweit "rx_packets", 155825e992a4SHeiner Kallweit "tx_errors", 155925e992a4SHeiner Kallweit "rx_errors", 156025e992a4SHeiner Kallweit "rx_missed", 156125e992a4SHeiner Kallweit "align_errors", 156225e992a4SHeiner Kallweit "tx_single_collisions", 156325e992a4SHeiner Kallweit "tx_multi_collisions", 156425e992a4SHeiner Kallweit "unicast", 156525e992a4SHeiner Kallweit "broadcast", 156625e992a4SHeiner Kallweit "multicast", 156725e992a4SHeiner Kallweit "tx_aborted", 156825e992a4SHeiner Kallweit "tx_underrun", 156925e992a4SHeiner Kallweit }; 157025e992a4SHeiner Kallweit 157125e992a4SHeiner Kallweit static int rtl8169_get_sset_count(struct net_device *dev, int sset) 157225e992a4SHeiner Kallweit { 157325e992a4SHeiner Kallweit switch (sset) { 157425e992a4SHeiner Kallweit case ETH_SS_STATS: 157525e992a4SHeiner Kallweit return ARRAY_SIZE(rtl8169_gstrings); 157625e992a4SHeiner Kallweit default: 157725e992a4SHeiner Kallweit return -EOPNOTSUPP; 157825e992a4SHeiner Kallweit } 157925e992a4SHeiner Kallweit } 158025e992a4SHeiner Kallweit 158125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_counters_cond) 158225e992a4SHeiner Kallweit { 158325e992a4SHeiner Kallweit return RTL_R32(tp, CounterAddrLow) & (CounterReset | CounterDump); 158425e992a4SHeiner Kallweit } 158525e992a4SHeiner Kallweit 1586d56f58ceSHeiner Kallweit static void rtl8169_do_counters(struct rtl8169_private *tp, u32 counter_cmd) 158725e992a4SHeiner Kallweit { 158825e992a4SHeiner Kallweit dma_addr_t paddr = tp->counters_phys_addr; 158925e992a4SHeiner Kallweit u32 cmd; 159025e992a4SHeiner Kallweit 159125e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32); 1592711463f8SHeiner Kallweit rtl_pci_commit(tp); 159325e992a4SHeiner Kallweit cmd = (u64)paddr & DMA_BIT_MASK(32); 159425e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrLow, cmd); 159525e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrLow, cmd | counter_cmd); 159625e992a4SHeiner Kallweit 1597d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_counters_cond, 10, 1000); 159825e992a4SHeiner Kallweit } 159925e992a4SHeiner Kallweit 1600d56f58ceSHeiner Kallweit static void rtl8169_reset_counters(struct rtl8169_private *tp) 160125e992a4SHeiner Kallweit { 160225e992a4SHeiner Kallweit /* 160325e992a4SHeiner Kallweit * Versions prior to RTL_GIGA_MAC_VER_19 don't support resetting the 160425e992a4SHeiner Kallweit * tally counters. 160525e992a4SHeiner Kallweit */ 1606d56f58ceSHeiner Kallweit if (tp->mac_version >= RTL_GIGA_MAC_VER_19) 1607d56f58ceSHeiner Kallweit rtl8169_do_counters(tp, CounterReset); 160825e992a4SHeiner Kallweit } 160925e992a4SHeiner Kallweit 1610d56f58ceSHeiner Kallweit static void rtl8169_update_counters(struct rtl8169_private *tp) 161125e992a4SHeiner Kallweit { 161225e992a4SHeiner Kallweit u8 val = RTL_R8(tp, ChipCmd); 161325e992a4SHeiner Kallweit 161425e992a4SHeiner Kallweit /* 161525e992a4SHeiner Kallweit * Some chips are unable to dump tally counters when the receiver 161625e992a4SHeiner Kallweit * is disabled. If 0xff chip may be in a PCI power-save state. 161725e992a4SHeiner Kallweit */ 1618d56f58ceSHeiner Kallweit if (val & CmdRxEnb && val != 0xff) 1619d56f58ceSHeiner Kallweit rtl8169_do_counters(tp, CounterDump); 162025e992a4SHeiner Kallweit } 162125e992a4SHeiner Kallweit 1622d56f58ceSHeiner Kallweit static void rtl8169_init_counter_offsets(struct rtl8169_private *tp) 162325e992a4SHeiner Kallweit { 162425e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 162525e992a4SHeiner Kallweit 162625e992a4SHeiner Kallweit /* 162725e992a4SHeiner Kallweit * rtl8169_init_counter_offsets is called from rtl_open. On chip 162825e992a4SHeiner Kallweit * versions prior to RTL_GIGA_MAC_VER_19 the tally counters are only 162925e992a4SHeiner Kallweit * reset by a power cycle, while the counter values collected by the 163025e992a4SHeiner Kallweit * driver are reset at every driver unload/load cycle. 163125e992a4SHeiner Kallweit * 163225e992a4SHeiner Kallweit * To make sure the HW values returned by @get_stats64 match the SW 163325e992a4SHeiner Kallweit * values, we collect the initial values at first open(*) and use them 163425e992a4SHeiner Kallweit * as offsets to normalize the values returned by @get_stats64. 163525e992a4SHeiner Kallweit * 163625e992a4SHeiner Kallweit * (*) We can't call rtl8169_init_counter_offsets from rtl_init_one 163725e992a4SHeiner Kallweit * for the reason stated in rtl8169_update_counters; CmdRxEnb is only 163825e992a4SHeiner Kallweit * set at open time by rtl_hw_start. 163925e992a4SHeiner Kallweit */ 164025e992a4SHeiner Kallweit 164125e992a4SHeiner Kallweit if (tp->tc_offset.inited) 1642d56f58ceSHeiner Kallweit return; 164325e992a4SHeiner Kallweit 1644d56f58ceSHeiner Kallweit rtl8169_reset_counters(tp); 1645d56f58ceSHeiner Kallweit rtl8169_update_counters(tp); 164625e992a4SHeiner Kallweit 164725e992a4SHeiner Kallweit tp->tc_offset.tx_errors = counters->tx_errors; 164825e992a4SHeiner Kallweit tp->tc_offset.tx_multi_collision = counters->tx_multi_collision; 164925e992a4SHeiner Kallweit tp->tc_offset.tx_aborted = counters->tx_aborted; 16500da3359aSHeiner Kallweit tp->tc_offset.rx_missed = counters->rx_missed; 165125e992a4SHeiner Kallweit tp->tc_offset.inited = true; 165225e992a4SHeiner Kallweit } 165325e992a4SHeiner Kallweit 165425e992a4SHeiner Kallweit static void rtl8169_get_ethtool_stats(struct net_device *dev, 165525e992a4SHeiner Kallweit struct ethtool_stats *stats, u64 *data) 165625e992a4SHeiner Kallweit { 165725e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 165825e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 165925e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 166025e992a4SHeiner Kallweit 166125e992a4SHeiner Kallweit ASSERT_RTNL(); 166225e992a4SHeiner Kallweit 166325e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 166425e992a4SHeiner Kallweit 166525e992a4SHeiner Kallweit if (pm_runtime_active(d)) 166625e992a4SHeiner Kallweit rtl8169_update_counters(tp); 166725e992a4SHeiner Kallweit 166825e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 166925e992a4SHeiner Kallweit 167025e992a4SHeiner Kallweit data[0] = le64_to_cpu(counters->tx_packets); 167125e992a4SHeiner Kallweit data[1] = le64_to_cpu(counters->rx_packets); 167225e992a4SHeiner Kallweit data[2] = le64_to_cpu(counters->tx_errors); 167325e992a4SHeiner Kallweit data[3] = le32_to_cpu(counters->rx_errors); 167425e992a4SHeiner Kallweit data[4] = le16_to_cpu(counters->rx_missed); 167525e992a4SHeiner Kallweit data[5] = le16_to_cpu(counters->align_errors); 167625e992a4SHeiner Kallweit data[6] = le32_to_cpu(counters->tx_one_collision); 167725e992a4SHeiner Kallweit data[7] = le32_to_cpu(counters->tx_multi_collision); 167825e992a4SHeiner Kallweit data[8] = le64_to_cpu(counters->rx_unicast); 167925e992a4SHeiner Kallweit data[9] = le64_to_cpu(counters->rx_broadcast); 168025e992a4SHeiner Kallweit data[10] = le32_to_cpu(counters->rx_multicast); 168125e992a4SHeiner Kallweit data[11] = le16_to_cpu(counters->tx_aborted); 168225e992a4SHeiner Kallweit data[12] = le16_to_cpu(counters->tx_underun); 168325e992a4SHeiner Kallweit } 168425e992a4SHeiner Kallweit 168525e992a4SHeiner Kallweit static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) 168625e992a4SHeiner Kallweit { 168725e992a4SHeiner Kallweit switch(stringset) { 168825e992a4SHeiner Kallweit case ETH_SS_STATS: 168925e992a4SHeiner Kallweit memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings)); 169025e992a4SHeiner Kallweit break; 169125e992a4SHeiner Kallweit } 169225e992a4SHeiner Kallweit } 169325e992a4SHeiner Kallweit 169425e992a4SHeiner Kallweit /* 169525e992a4SHeiner Kallweit * Interrupt coalescing 169625e992a4SHeiner Kallweit * 169725e992a4SHeiner Kallweit * > 1 - the availability of the IntrMitigate (0xe2) register through the 169825e992a4SHeiner Kallweit * > 8169, 8168 and 810x line of chipsets 169925e992a4SHeiner Kallweit * 170025e992a4SHeiner Kallweit * 8169, 8168, and 8136(810x) serial chipsets support it. 170125e992a4SHeiner Kallweit * 170225e992a4SHeiner Kallweit * > 2 - the Tx timer unit at gigabit speed 170325e992a4SHeiner Kallweit * 170425e992a4SHeiner Kallweit * The unit of the timer depends on both the speed and the setting of CPlusCmd 170525e992a4SHeiner Kallweit * (0xe0) bit 1 and bit 0. 170625e992a4SHeiner Kallweit * 170725e992a4SHeiner Kallweit * For 8169 170825e992a4SHeiner Kallweit * bit[1:0] \ speed 1000M 100M 10M 170925e992a4SHeiner Kallweit * 0 0 320ns 2.56us 40.96us 171025e992a4SHeiner Kallweit * 0 1 2.56us 20.48us 327.7us 171125e992a4SHeiner Kallweit * 1 0 5.12us 40.96us 655.4us 171225e992a4SHeiner Kallweit * 1 1 10.24us 81.92us 1.31ms 171325e992a4SHeiner Kallweit * 171425e992a4SHeiner Kallweit * For the other 171525e992a4SHeiner Kallweit * bit[1:0] \ speed 1000M 100M 10M 171625e992a4SHeiner Kallweit * 0 0 5us 2.56us 40.96us 171725e992a4SHeiner Kallweit * 0 1 40us 20.48us 327.7us 171825e992a4SHeiner Kallweit * 1 0 80us 40.96us 655.4us 171925e992a4SHeiner Kallweit * 1 1 160us 81.92us 1.31ms 172025e992a4SHeiner Kallweit */ 172125e992a4SHeiner Kallweit 172225e992a4SHeiner Kallweit /* rx/tx scale factors for all CPlusCmd[0:1] cases */ 172325e992a4SHeiner Kallweit struct rtl_coalesce_info { 172425e992a4SHeiner Kallweit u32 speed; 17252815b305SHeiner Kallweit u32 scale_nsecs[4]; 172625e992a4SHeiner Kallweit }; 172725e992a4SHeiner Kallweit 17282815b305SHeiner Kallweit /* produce array with base delay *1, *8, *8*2, *8*2*2 */ 17292815b305SHeiner Kallweit #define COALESCE_DELAY(d) { (d), 8 * (d), 16 * (d), 32 * (d) } 17302815b305SHeiner Kallweit 173125e992a4SHeiner Kallweit static const struct rtl_coalesce_info rtl_coalesce_info_8169[] = { 17322815b305SHeiner Kallweit { SPEED_10, COALESCE_DELAY(40960) }, 17332815b305SHeiner Kallweit { SPEED_100, COALESCE_DELAY(2560) }, 17342815b305SHeiner Kallweit { SPEED_1000, COALESCE_DELAY(320) }, 173525e992a4SHeiner Kallweit { 0 }, 173625e992a4SHeiner Kallweit }; 173725e992a4SHeiner Kallweit 173825e992a4SHeiner Kallweit static const struct rtl_coalesce_info rtl_coalesce_info_8168_8136[] = { 17392815b305SHeiner Kallweit { SPEED_10, COALESCE_DELAY(40960) }, 17402815b305SHeiner Kallweit { SPEED_100, COALESCE_DELAY(2560) }, 17412815b305SHeiner Kallweit { SPEED_1000, COALESCE_DELAY(5000) }, 174225e992a4SHeiner Kallweit { 0 }, 174325e992a4SHeiner Kallweit }; 17442815b305SHeiner Kallweit #undef COALESCE_DELAY 174525e992a4SHeiner Kallweit 174625e992a4SHeiner Kallweit /* get rx/tx scale vector corresponding to current speed */ 1747ef2c0a78SHeiner Kallweit static const struct rtl_coalesce_info * 1748ef2c0a78SHeiner Kallweit rtl_coalesce_info(struct rtl8169_private *tp) 174925e992a4SHeiner Kallweit { 175025e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 175125e992a4SHeiner Kallweit 175220023d3eSHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 175320023d3eSHeiner Kallweit ci = rtl_coalesce_info_8169; 175420023d3eSHeiner Kallweit else 175520023d3eSHeiner Kallweit ci = rtl_coalesce_info_8168_8136; 175625e992a4SHeiner Kallweit 175720023d3eSHeiner Kallweit for (; ci->speed; ci++) { 175820023d3eSHeiner Kallweit if (tp->phydev->speed == ci->speed) 175925e992a4SHeiner Kallweit return ci; 176025e992a4SHeiner Kallweit } 176125e992a4SHeiner Kallweit 176225e992a4SHeiner Kallweit return ERR_PTR(-ELNRNG); 176325e992a4SHeiner Kallweit } 176425e992a4SHeiner Kallweit 176525e992a4SHeiner Kallweit static int rtl_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) 176625e992a4SHeiner Kallweit { 176725e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 176825e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 17696cf96dd4SHeiner Kallweit u32 scale, c_us, c_fr; 17706cf96dd4SHeiner Kallweit u16 intrmit; 177125e992a4SHeiner Kallweit 1772f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1773f1bce4adSHeiner Kallweit return -EOPNOTSUPP; 1774f1bce4adSHeiner Kallweit 177525e992a4SHeiner Kallweit memset(ec, 0, sizeof(*ec)); 177625e992a4SHeiner Kallweit 177725e992a4SHeiner Kallweit /* get rx/tx scale corresponding to current speed and CPlusCmd[0:1] */ 1778ef2c0a78SHeiner Kallweit ci = rtl_coalesce_info(tp); 177925e992a4SHeiner Kallweit if (IS_ERR(ci)) 178025e992a4SHeiner Kallweit return PTR_ERR(ci); 178125e992a4SHeiner Kallweit 17822815b305SHeiner Kallweit scale = ci->scale_nsecs[tp->cp_cmd & INTT_MASK]; 178325e992a4SHeiner Kallweit 17846cf96dd4SHeiner Kallweit intrmit = RTL_R16(tp, IntrMitigate); 178525e992a4SHeiner Kallweit 17866cf96dd4SHeiner Kallweit c_us = FIELD_GET(RTL_COALESCE_TX_USECS, intrmit); 17876cf96dd4SHeiner Kallweit ec->tx_coalesce_usecs = DIV_ROUND_UP(c_us * scale, 1000); 178825e992a4SHeiner Kallweit 17896cf96dd4SHeiner Kallweit c_fr = FIELD_GET(RTL_COALESCE_TX_FRAMES, intrmit); 17906cf96dd4SHeiner Kallweit /* ethtool_coalesce states usecs and max_frames must not both be 0 */ 17916cf96dd4SHeiner Kallweit ec->tx_max_coalesced_frames = (c_us || c_fr) ? c_fr * 4 : 1; 17926cf96dd4SHeiner Kallweit 17936cf96dd4SHeiner Kallweit c_us = FIELD_GET(RTL_COALESCE_RX_USECS, intrmit); 17946cf96dd4SHeiner Kallweit ec->rx_coalesce_usecs = DIV_ROUND_UP(c_us * scale, 1000); 17956cf96dd4SHeiner Kallweit 17966cf96dd4SHeiner Kallweit c_fr = FIELD_GET(RTL_COALESCE_RX_FRAMES, intrmit); 17976cf96dd4SHeiner Kallweit ec->rx_max_coalesced_frames = (c_us || c_fr) ? c_fr * 4 : 1; 179825e992a4SHeiner Kallweit 179925e992a4SHeiner Kallweit return 0; 180025e992a4SHeiner Kallweit } 180125e992a4SHeiner Kallweit 1802cb9d97deSHeiner Kallweit /* choose appropriate scale factor and CPlusCmd[0:1] for (speed, usec) */ 1803cb9d97deSHeiner Kallweit static int rtl_coalesce_choose_scale(struct rtl8169_private *tp, u32 usec, 18042815b305SHeiner Kallweit u16 *cp01) 180525e992a4SHeiner Kallweit { 180625e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci; 180725e992a4SHeiner Kallweit u16 i; 180825e992a4SHeiner Kallweit 1809ef2c0a78SHeiner Kallweit ci = rtl_coalesce_info(tp); 181025e992a4SHeiner Kallweit if (IS_ERR(ci)) 18112815b305SHeiner Kallweit return PTR_ERR(ci); 181225e992a4SHeiner Kallweit 181325e992a4SHeiner Kallweit for (i = 0; i < 4; i++) { 1814cb9d97deSHeiner Kallweit if (usec <= ci->scale_nsecs[i] * RTL_COALESCE_T_MAX / 1000U) { 181525e992a4SHeiner Kallweit *cp01 = i; 18162815b305SHeiner Kallweit return ci->scale_nsecs[i]; 181725e992a4SHeiner Kallweit } 181825e992a4SHeiner Kallweit } 181925e992a4SHeiner Kallweit 1820cb9d97deSHeiner Kallweit return -ERANGE; 182125e992a4SHeiner Kallweit } 182225e992a4SHeiner Kallweit 182325e992a4SHeiner Kallweit static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) 182425e992a4SHeiner Kallweit { 182525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 18262b3e48b6SHeiner Kallweit u32 tx_fr = ec->tx_max_coalesced_frames; 18272b3e48b6SHeiner Kallweit u32 rx_fr = ec->rx_max_coalesced_frames; 18282b3e48b6SHeiner Kallweit u32 coal_usec_max, units; 18292815b305SHeiner Kallweit u16 w = 0, cp01 = 0; 18302b3e48b6SHeiner Kallweit int scale; 183125e992a4SHeiner Kallweit 1832f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 1833f1bce4adSHeiner Kallweit return -EOPNOTSUPP; 1834f1bce4adSHeiner Kallweit 18352b3e48b6SHeiner Kallweit if (rx_fr > RTL_COALESCE_FRAME_MAX || tx_fr > RTL_COALESCE_FRAME_MAX) 18362b3e48b6SHeiner Kallweit return -ERANGE; 18372b3e48b6SHeiner Kallweit 1838cb9d97deSHeiner Kallweit coal_usec_max = max(ec->rx_coalesce_usecs, ec->tx_coalesce_usecs); 1839cb9d97deSHeiner Kallweit scale = rtl_coalesce_choose_scale(tp, coal_usec_max, &cp01); 18402815b305SHeiner Kallweit if (scale < 0) 18412815b305SHeiner Kallweit return scale; 184225e992a4SHeiner Kallweit 18432b3e48b6SHeiner Kallweit /* Accept max_frames=1 we returned in rtl_get_coalesce. Accept it 18442b3e48b6SHeiner Kallweit * not only when usecs=0 because of e.g. the following scenario: 184525e992a4SHeiner Kallweit * 184625e992a4SHeiner Kallweit * - both rx_usecs=0 & rx_frames=0 in hardware (no delay on RX) 184725e992a4SHeiner Kallweit * - rtl_get_coalesce returns rx_usecs=0, rx_frames=1 184825e992a4SHeiner Kallweit * - then user does `ethtool -C eth0 rx-usecs 100` 184925e992a4SHeiner Kallweit * 18502b3e48b6SHeiner Kallweit * Since ethtool sends to kernel whole ethtool_coalesce settings, 18512b3e48b6SHeiner Kallweit * if we want to ignore rx_frames then it has to be set to 0. 185225e992a4SHeiner Kallweit */ 18532b3e48b6SHeiner Kallweit if (rx_fr == 1) 18542b3e48b6SHeiner Kallweit rx_fr = 0; 18552b3e48b6SHeiner Kallweit if (tx_fr == 1) 18562b3e48b6SHeiner Kallweit tx_fr = 0; 185725e992a4SHeiner Kallweit 185881496b72SHeiner Kallweit /* HW requires time limit to be set if frame limit is set */ 185981496b72SHeiner Kallweit if ((tx_fr && !ec->tx_coalesce_usecs) || 186081496b72SHeiner Kallweit (rx_fr && !ec->rx_coalesce_usecs)) 186181496b72SHeiner Kallweit return -EINVAL; 186281496b72SHeiner Kallweit 18632b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_TX_FRAMES, DIV_ROUND_UP(tx_fr, 4)); 18642b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_RX_FRAMES, DIV_ROUND_UP(rx_fr, 4)); 186525e992a4SHeiner Kallweit 18662b3e48b6SHeiner Kallweit units = DIV_ROUND_UP(ec->tx_coalesce_usecs * 1000U, scale); 18672b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_TX_USECS, units); 18682b3e48b6SHeiner Kallweit units = DIV_ROUND_UP(ec->rx_coalesce_usecs * 1000U, scale); 18692b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_RX_USECS, units); 187025e992a4SHeiner Kallweit 187125e992a4SHeiner Kallweit rtl_lock_work(tp); 187225e992a4SHeiner Kallweit 18732b3e48b6SHeiner Kallweit RTL_W16(tp, IntrMitigate, w); 187425e992a4SHeiner Kallweit 187525e992a4SHeiner Kallweit tp->cp_cmd = (tp->cp_cmd & ~INTT_MASK) | cp01; 187625e992a4SHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 1877711463f8SHeiner Kallweit rtl_pci_commit(tp); 187825e992a4SHeiner Kallweit 187925e992a4SHeiner Kallweit rtl_unlock_work(tp); 188025e992a4SHeiner Kallweit 188125e992a4SHeiner Kallweit return 0; 188225e992a4SHeiner Kallweit } 188325e992a4SHeiner Kallweit 188425e992a4SHeiner Kallweit static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data) 188525e992a4SHeiner Kallweit { 188625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 188725e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 188825e992a4SHeiner Kallweit int ret; 188925e992a4SHeiner Kallweit 18902e779ddbSHeiner Kallweit if (!rtl_supports_eee(tp)) 18912e779ddbSHeiner Kallweit return -EOPNOTSUPP; 18922e779ddbSHeiner Kallweit 189325e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 189425e992a4SHeiner Kallweit 189525e992a4SHeiner Kallweit if (!pm_runtime_active(d)) { 189625e992a4SHeiner Kallweit ret = -EOPNOTSUPP; 18972e779ddbSHeiner Kallweit } else { 18982e779ddbSHeiner Kallweit ret = phy_ethtool_get_eee(tp->phydev, data); 189925e992a4SHeiner Kallweit } 190025e992a4SHeiner Kallweit 190125e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 19022e779ddbSHeiner Kallweit 19032e779ddbSHeiner Kallweit return ret; 190425e992a4SHeiner Kallweit } 190525e992a4SHeiner Kallweit 190625e992a4SHeiner Kallweit static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data) 190725e992a4SHeiner Kallweit { 190825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 190925e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 19102e779ddbSHeiner Kallweit int ret; 19112e779ddbSHeiner Kallweit 19122e779ddbSHeiner Kallweit if (!rtl_supports_eee(tp)) 19132e779ddbSHeiner Kallweit return -EOPNOTSUPP; 191425e992a4SHeiner Kallweit 191525e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 191625e992a4SHeiner Kallweit 19172e779ddbSHeiner Kallweit if (!pm_runtime_active(d)) { 191825e992a4SHeiner Kallweit ret = -EOPNOTSUPP; 191925e992a4SHeiner Kallweit goto out; 192025e992a4SHeiner Kallweit } 192125e992a4SHeiner Kallweit 192225e992a4SHeiner Kallweit if (dev->phydev->autoneg == AUTONEG_DISABLE || 192325e992a4SHeiner Kallweit dev->phydev->duplex != DUPLEX_FULL) { 192425e992a4SHeiner Kallweit ret = -EPROTONOSUPPORT; 192525e992a4SHeiner Kallweit goto out; 192625e992a4SHeiner Kallweit } 192725e992a4SHeiner Kallweit 19282e779ddbSHeiner Kallweit ret = phy_ethtool_set_eee(tp->phydev, data); 19297ec3f872SHeiner Kallweit 19307ec3f872SHeiner Kallweit if (!ret) 19317ec3f872SHeiner Kallweit tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN, 19327ec3f872SHeiner Kallweit MDIO_AN_EEE_ADV); 193325e992a4SHeiner Kallweit out: 193425e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 19352e779ddbSHeiner Kallweit return ret; 193625e992a4SHeiner Kallweit } 193725e992a4SHeiner Kallweit 193825e992a4SHeiner Kallweit static const struct ethtool_ops rtl8169_ethtool_ops = { 1939b604eb31SJakub Kicinski .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 1940b604eb31SJakub Kicinski ETHTOOL_COALESCE_MAX_FRAMES, 194125e992a4SHeiner Kallweit .get_drvinfo = rtl8169_get_drvinfo, 194225e992a4SHeiner Kallweit .get_regs_len = rtl8169_get_regs_len, 194325e992a4SHeiner Kallweit .get_link = ethtool_op_get_link, 194425e992a4SHeiner Kallweit .get_coalesce = rtl_get_coalesce, 194525e992a4SHeiner Kallweit .set_coalesce = rtl_set_coalesce, 194625e992a4SHeiner Kallweit .get_regs = rtl8169_get_regs, 194725e992a4SHeiner Kallweit .get_wol = rtl8169_get_wol, 194825e992a4SHeiner Kallweit .set_wol = rtl8169_set_wol, 194925e992a4SHeiner Kallweit .get_strings = rtl8169_get_strings, 195025e992a4SHeiner Kallweit .get_sset_count = rtl8169_get_sset_count, 195125e992a4SHeiner Kallweit .get_ethtool_stats = rtl8169_get_ethtool_stats, 195225e992a4SHeiner Kallweit .get_ts_info = ethtool_op_get_ts_info, 195325e992a4SHeiner Kallweit .nway_reset = phy_ethtool_nway_reset, 195425e992a4SHeiner Kallweit .get_eee = rtl8169_get_eee, 195525e992a4SHeiner Kallweit .set_eee = rtl8169_set_eee, 195625e992a4SHeiner Kallweit .get_link_ksettings = phy_ethtool_get_link_ksettings, 195725e992a4SHeiner Kallweit .set_link_ksettings = phy_ethtool_set_link_ksettings, 195825e992a4SHeiner Kallweit }; 195925e992a4SHeiner Kallweit 196025e992a4SHeiner Kallweit static void rtl_enable_eee(struct rtl8169_private *tp) 196125e992a4SHeiner Kallweit { 19622e779ddbSHeiner Kallweit struct phy_device *phydev = tp->phydev; 19637ec3f872SHeiner Kallweit int adv; 196425e992a4SHeiner Kallweit 19657ec3f872SHeiner Kallweit /* respect EEE advertisement the user may have set */ 19667ec3f872SHeiner Kallweit if (tp->eee_adv >= 0) 19677ec3f872SHeiner Kallweit adv = tp->eee_adv; 19687ec3f872SHeiner Kallweit else 19697ec3f872SHeiner Kallweit adv = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); 19707ec3f872SHeiner Kallweit 19717ec3f872SHeiner Kallweit if (adv >= 0) 19727ec3f872SHeiner Kallweit phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv); 197325e992a4SHeiner Kallweit } 197425e992a4SHeiner Kallweit 1975f1f9ca28SHeiner Kallweit static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) 197625e992a4SHeiner Kallweit { 197725e992a4SHeiner Kallweit /* 197825e992a4SHeiner Kallweit * The driver currently handles the 8168Bf and the 8168Be identically 197925e992a4SHeiner Kallweit * but they can be identified more specifically through the test below 198025e992a4SHeiner Kallweit * if needed: 198125e992a4SHeiner Kallweit * 198225e992a4SHeiner Kallweit * (RTL_R32(tp, TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be 198325e992a4SHeiner Kallweit * 198425e992a4SHeiner Kallweit * Same thing for the 8101Eb and the 8101Ec: 198525e992a4SHeiner Kallweit * 198625e992a4SHeiner Kallweit * (RTL_R32(tp, TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec 198725e992a4SHeiner Kallweit */ 198825e992a4SHeiner Kallweit static const struct rtl_mac_info { 198925e992a4SHeiner Kallweit u16 mask; 199025e992a4SHeiner Kallweit u16 val; 1991f1f9ca28SHeiner Kallweit enum mac_version ver; 199225e992a4SHeiner Kallweit } mac_info[] = { 1993f1bce4adSHeiner Kallweit /* 8125 family. */ 1994f1bce4adSHeiner Kallweit { 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 }, 1995f1bce4adSHeiner Kallweit { 0x7c8, 0x608, RTL_GIGA_MAC_VER_61 }, 1996f1bce4adSHeiner Kallweit 19971287723aSHeiner Kallweit /* RTL8117 */ 19981287723aSHeiner Kallweit { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52 }, 19991287723aSHeiner Kallweit 200025e992a4SHeiner Kallweit /* 8168EP family. */ 200125e992a4SHeiner Kallweit { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51 }, 200225e992a4SHeiner Kallweit { 0x7cf, 0x501, RTL_GIGA_MAC_VER_50 }, 200325e992a4SHeiner Kallweit { 0x7cf, 0x500, RTL_GIGA_MAC_VER_49 }, 200425e992a4SHeiner Kallweit 200525e992a4SHeiner Kallweit /* 8168H family. */ 200625e992a4SHeiner Kallweit { 0x7cf, 0x541, RTL_GIGA_MAC_VER_46 }, 200725e992a4SHeiner Kallweit { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 }, 200825e992a4SHeiner Kallweit 200925e992a4SHeiner Kallweit /* 8168G family. */ 201025e992a4SHeiner Kallweit { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 }, 201125e992a4SHeiner Kallweit { 0x7cf, 0x509, RTL_GIGA_MAC_VER_42 }, 201225e992a4SHeiner Kallweit { 0x7cf, 0x4c1, RTL_GIGA_MAC_VER_41 }, 201325e992a4SHeiner Kallweit { 0x7cf, 0x4c0, RTL_GIGA_MAC_VER_40 }, 201425e992a4SHeiner Kallweit 201525e992a4SHeiner Kallweit /* 8168F family. */ 201625e992a4SHeiner Kallweit { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38 }, 201725e992a4SHeiner Kallweit { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36 }, 201825e992a4SHeiner Kallweit { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35 }, 201925e992a4SHeiner Kallweit 202025e992a4SHeiner Kallweit /* 8168E family. */ 202125e992a4SHeiner Kallweit { 0x7c8, 0x2c8, RTL_GIGA_MAC_VER_34 }, 202225e992a4SHeiner Kallweit { 0x7cf, 0x2c1, RTL_GIGA_MAC_VER_32 }, 202325e992a4SHeiner Kallweit { 0x7c8, 0x2c0, RTL_GIGA_MAC_VER_33 }, 202425e992a4SHeiner Kallweit 202525e992a4SHeiner Kallweit /* 8168D family. */ 202625e992a4SHeiner Kallweit { 0x7cf, 0x281, RTL_GIGA_MAC_VER_25 }, 202725e992a4SHeiner Kallweit { 0x7c8, 0x280, RTL_GIGA_MAC_VER_26 }, 202825e992a4SHeiner Kallweit 202925e992a4SHeiner Kallweit /* 8168DP family. */ 203025e992a4SHeiner Kallweit { 0x7cf, 0x288, RTL_GIGA_MAC_VER_27 }, 203125e992a4SHeiner Kallweit { 0x7cf, 0x28a, RTL_GIGA_MAC_VER_28 }, 203225e992a4SHeiner Kallweit { 0x7cf, 0x28b, RTL_GIGA_MAC_VER_31 }, 203325e992a4SHeiner Kallweit 203425e992a4SHeiner Kallweit /* 8168C family. */ 203525e992a4SHeiner Kallweit { 0x7cf, 0x3c9, RTL_GIGA_MAC_VER_23 }, 203625e992a4SHeiner Kallweit { 0x7cf, 0x3c8, RTL_GIGA_MAC_VER_18 }, 203725e992a4SHeiner Kallweit { 0x7c8, 0x3c8, RTL_GIGA_MAC_VER_24 }, 203825e992a4SHeiner Kallweit { 0x7cf, 0x3c0, RTL_GIGA_MAC_VER_19 }, 203925e992a4SHeiner Kallweit { 0x7cf, 0x3c2, RTL_GIGA_MAC_VER_20 }, 204025e992a4SHeiner Kallweit { 0x7cf, 0x3c3, RTL_GIGA_MAC_VER_21 }, 204125e992a4SHeiner Kallweit { 0x7c8, 0x3c0, RTL_GIGA_MAC_VER_22 }, 204225e992a4SHeiner Kallweit 204325e992a4SHeiner Kallweit /* 8168B family. */ 204425e992a4SHeiner Kallweit { 0x7cf, 0x380, RTL_GIGA_MAC_VER_12 }, 204525e992a4SHeiner Kallweit { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 }, 204625e992a4SHeiner Kallweit { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 }, 204725e992a4SHeiner Kallweit 204825e992a4SHeiner Kallweit /* 8101 family. */ 204925e992a4SHeiner Kallweit { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 }, 205025e992a4SHeiner Kallweit { 0x7c8, 0x440, RTL_GIGA_MAC_VER_37 }, 205125e992a4SHeiner Kallweit { 0x7cf, 0x409, RTL_GIGA_MAC_VER_29 }, 205225e992a4SHeiner Kallweit { 0x7c8, 0x408, RTL_GIGA_MAC_VER_30 }, 205325e992a4SHeiner Kallweit { 0x7cf, 0x349, RTL_GIGA_MAC_VER_08 }, 205425e992a4SHeiner Kallweit { 0x7cf, 0x249, RTL_GIGA_MAC_VER_08 }, 205525e992a4SHeiner Kallweit { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 }, 205625e992a4SHeiner Kallweit { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 }, 205725e992a4SHeiner Kallweit { 0x7cf, 0x340, RTL_GIGA_MAC_VER_13 }, 205825e992a4SHeiner Kallweit { 0x7cf, 0x343, RTL_GIGA_MAC_VER_10 }, 205925e992a4SHeiner Kallweit { 0x7cf, 0x342, RTL_GIGA_MAC_VER_16 }, 206025e992a4SHeiner Kallweit { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 }, 206125e992a4SHeiner Kallweit { 0x7c8, 0x248, RTL_GIGA_MAC_VER_09 }, 206225e992a4SHeiner Kallweit { 0x7c8, 0x340, RTL_GIGA_MAC_VER_16 }, 206325e992a4SHeiner Kallweit /* FIXME: where did these entries come from ? -- FR */ 206425e992a4SHeiner Kallweit { 0xfc8, 0x388, RTL_GIGA_MAC_VER_15 }, 206525e992a4SHeiner Kallweit { 0xfc8, 0x308, RTL_GIGA_MAC_VER_14 }, 206625e992a4SHeiner Kallweit 206725e992a4SHeiner Kallweit /* 8110 family. */ 206825e992a4SHeiner Kallweit { 0xfc8, 0x980, RTL_GIGA_MAC_VER_06 }, 206925e992a4SHeiner Kallweit { 0xfc8, 0x180, RTL_GIGA_MAC_VER_05 }, 207025e992a4SHeiner Kallweit { 0xfc8, 0x100, RTL_GIGA_MAC_VER_04 }, 207125e992a4SHeiner Kallweit { 0xfc8, 0x040, RTL_GIGA_MAC_VER_03 }, 207225e992a4SHeiner Kallweit { 0xfc8, 0x008, RTL_GIGA_MAC_VER_02 }, 207325e992a4SHeiner Kallweit 207425e992a4SHeiner Kallweit /* Catch-all */ 207525e992a4SHeiner Kallweit { 0x000, 0x000, RTL_GIGA_MAC_NONE } 207625e992a4SHeiner Kallweit }; 207725e992a4SHeiner Kallweit const struct rtl_mac_info *p = mac_info; 2078f1f9ca28SHeiner Kallweit enum mac_version ver; 207925e992a4SHeiner Kallweit 2080f1f9ca28SHeiner Kallweit while ((xid & p->mask) != p->val) 208125e992a4SHeiner Kallweit p++; 2082f1f9ca28SHeiner Kallweit ver = p->ver; 208325e992a4SHeiner Kallweit 2084f1f9ca28SHeiner Kallweit if (ver != RTL_GIGA_MAC_NONE && !gmii) { 2085f1f9ca28SHeiner Kallweit if (ver == RTL_GIGA_MAC_VER_42) 2086f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_43; 2087f1f9ca28SHeiner Kallweit else if (ver == RTL_GIGA_MAC_VER_45) 2088f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_47; 2089f1f9ca28SHeiner Kallweit else if (ver == RTL_GIGA_MAC_VER_46) 2090f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_48; 209125e992a4SHeiner Kallweit } 2092f1f9ca28SHeiner Kallweit 2093f1f9ca28SHeiner Kallweit return ver; 209425e992a4SHeiner Kallweit } 209525e992a4SHeiner Kallweit 209625e992a4SHeiner Kallweit static void rtl_release_firmware(struct rtl8169_private *tp) 209725e992a4SHeiner Kallweit { 209825e992a4SHeiner Kallweit if (tp->rtl_fw) { 209925e992a4SHeiner Kallweit rtl_fw_release_firmware(tp->rtl_fw); 210025e992a4SHeiner Kallweit kfree(tp->rtl_fw); 210125e992a4SHeiner Kallweit tp->rtl_fw = NULL; 210225e992a4SHeiner Kallweit } 210325e992a4SHeiner Kallweit } 210425e992a4SHeiner Kallweit 21052992bdfaSHeiner Kallweit void r8169_apply_firmware(struct rtl8169_private *tp) 210625e992a4SHeiner Kallweit { 210725e992a4SHeiner Kallweit /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ 210825e992a4SHeiner Kallweit if (tp->rtl_fw) 210925e992a4SHeiner Kallweit rtl_fw_write_firmware(tp, tp->rtl_fw); 211025e992a4SHeiner Kallweit } 211125e992a4SHeiner Kallweit 211225e992a4SHeiner Kallweit static void rtl8168_config_eee_mac(struct rtl8169_private *tp) 211325e992a4SHeiner Kallweit { 211425e992a4SHeiner Kallweit /* Adjust EEE LED frequency */ 211525e992a4SHeiner Kallweit if (tp->mac_version != RTL_GIGA_MAC_VER_38) 211625e992a4SHeiner Kallweit RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07); 211725e992a4SHeiner Kallweit 211825e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, ERIAR_MASK_1111, 0x0003); 211925e992a4SHeiner Kallweit } 212025e992a4SHeiner Kallweit 2121b3a42e3aSHeiner Kallweit static void rtl8125_config_eee_mac(struct rtl8169_private *tp) 2122b3a42e3aSHeiner Kallweit { 2123b3a42e3aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0)); 2124b3a42e3aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb62, 0, BIT(2) | BIT(1)); 2125b3a42e3aSHeiner Kallweit } 2126b3a42e3aSHeiner Kallweit 212725e992a4SHeiner Kallweit static void rtl_rar_exgmac_set(struct rtl8169_private *tp, u8 *addr) 212825e992a4SHeiner Kallweit { 212925e992a4SHeiner Kallweit const u16 w[] = { 213025e992a4SHeiner Kallweit addr[0] | (addr[1] << 8), 213125e992a4SHeiner Kallweit addr[2] | (addr[3] << 8), 213225e992a4SHeiner Kallweit addr[4] | (addr[5] << 8) 213325e992a4SHeiner Kallweit }; 213425e992a4SHeiner Kallweit 213525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe0, ERIAR_MASK_1111, w[0] | (w[1] << 16)); 213625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe4, ERIAR_MASK_1111, w[2]); 213725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xf0, ERIAR_MASK_1111, w[0] << 16); 213825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xf4, ERIAR_MASK_1111, w[1] | (w[2] << 16)); 213925e992a4SHeiner Kallweit } 214025e992a4SHeiner Kallweit 21412992bdfaSHeiner Kallweit u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp) 21423127f7c9SHeiner Kallweit { 21433127f7c9SHeiner Kallweit u16 data1, data2, ioffset; 21443127f7c9SHeiner Kallweit 21453127f7c9SHeiner Kallweit r8168_mac_ocp_write(tp, 0xdd02, 0x807d); 21463127f7c9SHeiner Kallweit data1 = r8168_mac_ocp_read(tp, 0xdd02); 21473127f7c9SHeiner Kallweit data2 = r8168_mac_ocp_read(tp, 0xdd00); 21483127f7c9SHeiner Kallweit 21493127f7c9SHeiner Kallweit ioffset = (data2 >> 1) & 0x7ff8; 21503127f7c9SHeiner Kallweit ioffset |= data2 & 0x0007; 21513127f7c9SHeiner Kallweit if (data1 & BIT(7)) 21523127f7c9SHeiner Kallweit ioffset |= BIT(15); 21533127f7c9SHeiner Kallweit 21543127f7c9SHeiner Kallweit return ioffset; 21553127f7c9SHeiner Kallweit } 21563127f7c9SHeiner Kallweit 215725e992a4SHeiner Kallweit static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) 215825e992a4SHeiner Kallweit { 21593f6ca6c7SHeiner Kallweit set_bit(flag, tp->wk.flags); 216025e992a4SHeiner Kallweit schedule_work(&tp->wk.work); 216125e992a4SHeiner Kallweit } 216225e992a4SHeiner Kallweit 2163b5aed0b3SHeiner Kallweit static void rtl8169_init_phy(struct rtl8169_private *tp) 216425e992a4SHeiner Kallweit { 2165becd837eSHeiner Kallweit r8169_hw_phy_config(tp, tp->phydev, tp->mac_version); 216625e992a4SHeiner Kallweit 216725e992a4SHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { 216825e992a4SHeiner Kallweit pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); 216925e992a4SHeiner Kallweit pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); 2170b5aed0b3SHeiner Kallweit /* set undocumented MAC Reg C+CR Offset 0x82h */ 217125e992a4SHeiner Kallweit RTL_W8(tp, 0x82, 0x01); 217225e992a4SHeiner Kallweit } 217325e992a4SHeiner Kallweit 2174fc712387SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05 && 2175fc712387SHeiner Kallweit tp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_GIGABYTE && 2176fc712387SHeiner Kallweit tp->pci_dev->subsystem_device == 0xe000) 2177fc712387SHeiner Kallweit phy_write_paged(tp->phydev, 0x0001, 0x10, 0xf01b); 2178fc712387SHeiner Kallweit 217925e992a4SHeiner Kallweit /* We may have called phy_speed_down before */ 218025e992a4SHeiner Kallweit phy_speed_up(tp->phydev); 218125e992a4SHeiner Kallweit 2182af779778SHeiner Kallweit if (rtl_supports_eee(tp)) 2183af779778SHeiner Kallweit rtl_enable_eee(tp); 2184af779778SHeiner Kallweit 218525e992a4SHeiner Kallweit genphy_soft_reset(tp->phydev); 218625e992a4SHeiner Kallweit } 218725e992a4SHeiner Kallweit 218825e992a4SHeiner Kallweit static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) 218925e992a4SHeiner Kallweit { 219025e992a4SHeiner Kallweit rtl_lock_work(tp); 219125e992a4SHeiner Kallweit 219225e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 219325e992a4SHeiner Kallweit 219425e992a4SHeiner Kallweit RTL_W32(tp, MAC4, addr[4] | addr[5] << 8); 2195711463f8SHeiner Kallweit rtl_pci_commit(tp); 219625e992a4SHeiner Kallweit 219725e992a4SHeiner Kallweit RTL_W32(tp, MAC0, addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); 2198711463f8SHeiner Kallweit rtl_pci_commit(tp); 219925e992a4SHeiner Kallweit 220025e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34) 220125e992a4SHeiner Kallweit rtl_rar_exgmac_set(tp, addr); 220225e992a4SHeiner Kallweit 220325e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 220425e992a4SHeiner Kallweit 220525e992a4SHeiner Kallweit rtl_unlock_work(tp); 220625e992a4SHeiner Kallweit } 220725e992a4SHeiner Kallweit 220825e992a4SHeiner Kallweit static int rtl_set_mac_address(struct net_device *dev, void *p) 220925e992a4SHeiner Kallweit { 221025e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 221125e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 221225e992a4SHeiner Kallweit int ret; 221325e992a4SHeiner Kallweit 221425e992a4SHeiner Kallweit ret = eth_mac_addr(dev, p); 221525e992a4SHeiner Kallweit if (ret) 221625e992a4SHeiner Kallweit return ret; 221725e992a4SHeiner Kallweit 221825e992a4SHeiner Kallweit pm_runtime_get_noresume(d); 221925e992a4SHeiner Kallweit 222025e992a4SHeiner Kallweit if (pm_runtime_active(d)) 222125e992a4SHeiner Kallweit rtl_rar_set(tp, dev->dev_addr); 222225e992a4SHeiner Kallweit 222325e992a4SHeiner Kallweit pm_runtime_put_noidle(d); 222425e992a4SHeiner Kallweit 222525e992a4SHeiner Kallweit return 0; 222625e992a4SHeiner Kallweit } 222725e992a4SHeiner Kallweit 222825e992a4SHeiner Kallweit static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) 222925e992a4SHeiner Kallweit { 223025e992a4SHeiner Kallweit switch (tp->mac_version) { 223125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25: 223225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_26: 223325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_29: 223425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_30: 223525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_32: 223625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_33: 223725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_34: 223800222d13SHeiner Kallweit case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_61: 223925e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | 224025e992a4SHeiner Kallweit AcceptBroadcast | AcceptMulticast | AcceptMyPhys); 224125e992a4SHeiner Kallweit break; 224225e992a4SHeiner Kallweit default: 224325e992a4SHeiner Kallweit break; 224425e992a4SHeiner Kallweit } 224525e992a4SHeiner Kallweit } 224625e992a4SHeiner Kallweit 224725e992a4SHeiner Kallweit static void rtl_pll_power_down(struct rtl8169_private *tp) 224825e992a4SHeiner Kallweit { 224925e992a4SHeiner Kallweit if (r8168_check_dash(tp)) 225025e992a4SHeiner Kallweit return; 225125e992a4SHeiner Kallweit 225225e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_32 || 225325e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_33) 225425e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x19, 0xff64); 225525e992a4SHeiner Kallweit 225625e992a4SHeiner Kallweit if (device_may_wakeup(tp_to_dev(tp))) { 225725e992a4SHeiner Kallweit phy_speed_down(tp->phydev, false); 225825e992a4SHeiner Kallweit rtl_wol_suspend_quirk(tp); 225925e992a4SHeiner Kallweit return; 226025e992a4SHeiner Kallweit } 226125e992a4SHeiner Kallweit 226225e992a4SHeiner Kallweit switch (tp->mac_version) { 226325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: 226425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_37: 226525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_39: 226625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_43: 226725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_44: 226825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_45: 226925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_46: 227025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_47: 227125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_48: 227225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_50: 227325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_51: 22741287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_52: 2275f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60: 2276f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_61: 227725e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); 227825e992a4SHeiner Kallweit break; 227925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40: 228025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_41: 228125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_49: 228225e992a4SHeiner Kallweit rtl_eri_clear_bits(tp, 0x1a8, ERIAR_MASK_1111, 0xfc000000); 228325e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); 228425e992a4SHeiner Kallweit break; 228525e992a4SHeiner Kallweit default: 228625e992a4SHeiner Kallweit break; 228725e992a4SHeiner Kallweit } 228825e992a4SHeiner Kallweit } 228925e992a4SHeiner Kallweit 229025e992a4SHeiner Kallweit static void rtl_pll_power_up(struct rtl8169_private *tp) 229125e992a4SHeiner Kallweit { 229225e992a4SHeiner Kallweit switch (tp->mac_version) { 229325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: 229425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_37: 229525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_39: 229625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_43: 229725e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0x80); 229825e992a4SHeiner Kallweit break; 229925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_44: 230025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_45: 230125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_46: 230225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_47: 230325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_48: 230425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_50: 230525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_51: 23061287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_52: 2307f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60: 2308f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_61: 230925e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); 231025e992a4SHeiner Kallweit break; 231125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40: 231225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_41: 231325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_49: 231425e992a4SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); 231525e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0x1a8, ERIAR_MASK_1111, 0xfc000000); 231625e992a4SHeiner Kallweit break; 231725e992a4SHeiner Kallweit default: 231825e992a4SHeiner Kallweit break; 231925e992a4SHeiner Kallweit } 232025e992a4SHeiner Kallweit 232125e992a4SHeiner Kallweit phy_resume(tp->phydev); 232225e992a4SHeiner Kallweit } 232325e992a4SHeiner Kallweit 232425e992a4SHeiner Kallweit static void rtl_init_rxcfg(struct rtl8169_private *tp) 232525e992a4SHeiner Kallweit { 232625e992a4SHeiner Kallweit switch (tp->mac_version) { 232725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 232825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17: 232925e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX_FIFO_THRESH | RX_DMA_BURST); 233025e992a4SHeiner Kallweit break; 233125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: 233225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_36: 233325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_38: 233425e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); 233525e992a4SHeiner Kallweit break; 23361287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: 233725e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); 233825e992a4SHeiner Kallweit break; 2339f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: 234010478283SHeiner Kallweit RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST); 2341f1bce4adSHeiner Kallweit break; 234225e992a4SHeiner Kallweit default: 234325e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST); 234425e992a4SHeiner Kallweit break; 234525e992a4SHeiner Kallweit } 234625e992a4SHeiner Kallweit } 234725e992a4SHeiner Kallweit 234825e992a4SHeiner Kallweit static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) 234925e992a4SHeiner Kallweit { 235025e992a4SHeiner Kallweit tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0; 235125e992a4SHeiner Kallweit } 235225e992a4SHeiner Kallweit 235325e992a4SHeiner Kallweit static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) 235425e992a4SHeiner Kallweit { 235525e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 235625e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); 235725e992a4SHeiner Kallweit } 235825e992a4SHeiner Kallweit 235925e992a4SHeiner Kallweit static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) 236025e992a4SHeiner Kallweit { 236125e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); 236225e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); 236325e992a4SHeiner Kallweit } 236425e992a4SHeiner Kallweit 236525e992a4SHeiner Kallweit static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) 236625e992a4SHeiner Kallweit { 236725e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 236825e992a4SHeiner Kallweit } 236925e992a4SHeiner Kallweit 237025e992a4SHeiner Kallweit static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) 237125e992a4SHeiner Kallweit { 237225e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); 237325e992a4SHeiner Kallweit } 237425e992a4SHeiner Kallweit 237525e992a4SHeiner Kallweit static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) 237625e992a4SHeiner Kallweit { 237725e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, 0x3f); 237825e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); 237925e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01); 238025e992a4SHeiner Kallweit } 238125e992a4SHeiner Kallweit 238225e992a4SHeiner Kallweit static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) 238325e992a4SHeiner Kallweit { 238425e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, 0x0c); 238525e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); 238625e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01); 238725e992a4SHeiner Kallweit } 238825e992a4SHeiner Kallweit 238925e992a4SHeiner Kallweit static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) 239025e992a4SHeiner Kallweit { 239125e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0)); 239225e992a4SHeiner Kallweit } 239325e992a4SHeiner Kallweit 239425e992a4SHeiner Kallweit static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) 239525e992a4SHeiner Kallweit { 239625e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0)); 239725e992a4SHeiner Kallweit } 239825e992a4SHeiner Kallweit 23999db0ac57SHeiner Kallweit static void rtl_jumbo_config(struct rtl8169_private *tp) 240025e992a4SHeiner Kallweit { 24019db0ac57SHeiner Kallweit bool jumbo = tp->dev->mtu > ETH_DATA_LEN; 24029db0ac57SHeiner Kallweit 240325e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 240425e992a4SHeiner Kallweit switch (tp->mac_version) { 240525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 240625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 24079db0ac57SHeiner Kallweit if (jumbo) { 240821b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 240925e992a4SHeiner Kallweit r8168b_1_hw_jumbo_enable(tp); 24109db0ac57SHeiner Kallweit } else { 24119db0ac57SHeiner Kallweit r8168b_1_hw_jumbo_disable(tp); 24129db0ac57SHeiner Kallweit } 241325e992a4SHeiner Kallweit break; 241425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26: 24159db0ac57SHeiner Kallweit if (jumbo) { 241621b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 241725e992a4SHeiner Kallweit r8168c_hw_jumbo_enable(tp); 24189db0ac57SHeiner Kallweit } else { 241925e992a4SHeiner Kallweit r8168c_hw_jumbo_disable(tp); 24209db0ac57SHeiner Kallweit } 242125e992a4SHeiner Kallweit break; 242225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28: 24239db0ac57SHeiner Kallweit if (jumbo) 24249db0ac57SHeiner Kallweit r8168dp_hw_jumbo_enable(tp); 24259db0ac57SHeiner Kallweit else 242625e992a4SHeiner Kallweit r8168dp_hw_jumbo_disable(tp); 242725e992a4SHeiner Kallweit break; 24280fc75219SHeiner Kallweit case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33: 24299db0ac57SHeiner Kallweit if (jumbo) { 24309db0ac57SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 512); 24319db0ac57SHeiner Kallweit r8168e_hw_jumbo_enable(tp); 24329db0ac57SHeiner Kallweit } else { 243325e992a4SHeiner Kallweit r8168e_hw_jumbo_disable(tp); 24349db0ac57SHeiner Kallweit } 243525e992a4SHeiner Kallweit break; 243625e992a4SHeiner Kallweit default: 243725e992a4SHeiner Kallweit break; 243825e992a4SHeiner Kallweit } 243925e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 244021b5f672SHeiner Kallweit 24419db0ac57SHeiner Kallweit if (!jumbo && pci_is_pcie(tp->pci_dev) && tp->supports_gmii) 244221b5f672SHeiner Kallweit pcie_set_readrq(tp->pci_dev, 4096); 244325e992a4SHeiner Kallweit } 244425e992a4SHeiner Kallweit 244525e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_chipcmd_cond) 244625e992a4SHeiner Kallweit { 244725e992a4SHeiner Kallweit return RTL_R8(tp, ChipCmd) & CmdReset; 244825e992a4SHeiner Kallweit } 244925e992a4SHeiner Kallweit 245025e992a4SHeiner Kallweit static void rtl_hw_reset(struct rtl8169_private *tp) 245125e992a4SHeiner Kallweit { 245225e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, CmdReset); 245325e992a4SHeiner Kallweit 2454d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100); 245525e992a4SHeiner Kallweit } 245625e992a4SHeiner Kallweit 245725e992a4SHeiner Kallweit static void rtl_request_firmware(struct rtl8169_private *tp) 245825e992a4SHeiner Kallweit { 245925e992a4SHeiner Kallweit struct rtl_fw *rtl_fw; 246025e992a4SHeiner Kallweit 246125e992a4SHeiner Kallweit /* firmware loaded already or no firmware available */ 246225e992a4SHeiner Kallweit if (tp->rtl_fw || !tp->fw_name) 246325e992a4SHeiner Kallweit return; 246425e992a4SHeiner Kallweit 246525e992a4SHeiner Kallweit rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL); 24663bf6ff3cSHeiner Kallweit if (!rtl_fw) 246725e992a4SHeiner Kallweit return; 246825e992a4SHeiner Kallweit 246925e992a4SHeiner Kallweit rtl_fw->phy_write = rtl_writephy; 247025e992a4SHeiner Kallweit rtl_fw->phy_read = rtl_readphy; 247125e992a4SHeiner Kallweit rtl_fw->mac_mcu_write = mac_mcu_write; 247225e992a4SHeiner Kallweit rtl_fw->mac_mcu_read = mac_mcu_read; 247325e992a4SHeiner Kallweit rtl_fw->fw_name = tp->fw_name; 247425e992a4SHeiner Kallweit rtl_fw->dev = tp_to_dev(tp); 247525e992a4SHeiner Kallweit 247625e992a4SHeiner Kallweit if (rtl_fw_request_firmware(rtl_fw)) 247725e992a4SHeiner Kallweit kfree(rtl_fw); 247825e992a4SHeiner Kallweit else 247925e992a4SHeiner Kallweit tp->rtl_fw = rtl_fw; 248025e992a4SHeiner Kallweit } 248125e992a4SHeiner Kallweit 248225e992a4SHeiner Kallweit static void rtl_rx_close(struct rtl8169_private *tp) 248325e992a4SHeiner Kallweit { 248425e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~RX_CONFIG_ACCEPT_MASK); 248525e992a4SHeiner Kallweit } 248625e992a4SHeiner Kallweit 248725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_npq_cond) 248825e992a4SHeiner Kallweit { 248925e992a4SHeiner Kallweit return RTL_R8(tp, TxPoll) & NPQ; 249025e992a4SHeiner Kallweit } 249125e992a4SHeiner Kallweit 249225e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_txcfg_empty_cond) 249325e992a4SHeiner Kallweit { 249425e992a4SHeiner Kallweit return RTL_R32(tp, TxConfig) & TXCFG_EMPTY; 249525e992a4SHeiner Kallweit } 249625e992a4SHeiner Kallweit 249725e992a4SHeiner Kallweit static void rtl8169_hw_reset(struct rtl8169_private *tp) 249825e992a4SHeiner Kallweit { 249925e992a4SHeiner Kallweit /* Disable interrupts */ 250025e992a4SHeiner Kallweit rtl8169_irq_mask_and_ack(tp); 250125e992a4SHeiner Kallweit 250225e992a4SHeiner Kallweit rtl_rx_close(tp); 250325e992a4SHeiner Kallweit 250425e992a4SHeiner Kallweit switch (tp->mac_version) { 250525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_27: 250625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28: 250725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31: 2508d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_npq_cond, 20, 2000); 250925e992a4SHeiner Kallweit break; 251025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38: 25111287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: 251225e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); 2513d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); 251425e992a4SHeiner Kallweit break; 251525e992a4SHeiner Kallweit default: 251625e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); 251725e992a4SHeiner Kallweit udelay(100); 251825e992a4SHeiner Kallweit break; 251925e992a4SHeiner Kallweit } 252025e992a4SHeiner Kallweit 252125e992a4SHeiner Kallweit rtl_hw_reset(tp); 252225e992a4SHeiner Kallweit } 252325e992a4SHeiner Kallweit 252425e992a4SHeiner Kallweit static void rtl_set_tx_config_registers(struct rtl8169_private *tp) 252525e992a4SHeiner Kallweit { 252625e992a4SHeiner Kallweit u32 val = TX_DMA_BURST << TxDMAShift | 252725e992a4SHeiner Kallweit InterFrameGap << TxInterFrameGapShift; 252825e992a4SHeiner Kallweit 25299e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp)) 253025e992a4SHeiner Kallweit val |= TXCFG_AUTO_FIFO; 253125e992a4SHeiner Kallweit 253225e992a4SHeiner Kallweit RTL_W32(tp, TxConfig, val); 253325e992a4SHeiner Kallweit } 253425e992a4SHeiner Kallweit 253525e992a4SHeiner Kallweit static void rtl_set_rx_max_size(struct rtl8169_private *tp) 253625e992a4SHeiner Kallweit { 253725e992a4SHeiner Kallweit /* Low hurts. Let's disable the filtering. */ 253825e992a4SHeiner Kallweit RTL_W16(tp, RxMaxSize, R8169_RX_BUF_SIZE + 1); 253925e992a4SHeiner Kallweit } 254025e992a4SHeiner Kallweit 254125e992a4SHeiner Kallweit static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp) 254225e992a4SHeiner Kallweit { 254325e992a4SHeiner Kallweit /* 254425e992a4SHeiner Kallweit * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh 254525e992a4SHeiner Kallweit * register to be written before TxDescAddrLow to work. 254625e992a4SHeiner Kallweit * Switching from MMIO to I/O access fixes the issue as well. 254725e992a4SHeiner Kallweit */ 254825e992a4SHeiner Kallweit RTL_W32(tp, TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32); 254925e992a4SHeiner Kallweit RTL_W32(tp, TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32)); 255025e992a4SHeiner Kallweit RTL_W32(tp, RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32); 255125e992a4SHeiner Kallweit RTL_W32(tp, RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32)); 255225e992a4SHeiner Kallweit } 255325e992a4SHeiner Kallweit 2554ef891284SHeiner Kallweit static void rtl8169_set_magic_reg(struct rtl8169_private *tp) 255525e992a4SHeiner Kallweit { 255625e992a4SHeiner Kallweit u32 val; 255725e992a4SHeiner Kallweit 255825e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05) 255925e992a4SHeiner Kallweit val = 0x000fff00; 256025e992a4SHeiner Kallweit else if (tp->mac_version == RTL_GIGA_MAC_VER_06) 256125e992a4SHeiner Kallweit val = 0x00ffff00; 256225e992a4SHeiner Kallweit else 256325e992a4SHeiner Kallweit return; 256425e992a4SHeiner Kallweit 256525e992a4SHeiner Kallweit if (RTL_R8(tp, Config2) & PCI_Clock_66MHz) 256625e992a4SHeiner Kallweit val |= 0xff; 256725e992a4SHeiner Kallweit 256825e992a4SHeiner Kallweit RTL_W32(tp, 0x7c, val); 256925e992a4SHeiner Kallweit } 257025e992a4SHeiner Kallweit 257125e992a4SHeiner Kallweit static void rtl_set_rx_mode(struct net_device *dev) 257225e992a4SHeiner Kallweit { 257381cd17a4SHeiner Kallweit u32 rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast; 257481cd17a4SHeiner Kallweit /* Multicast hash filter */ 257581cd17a4SHeiner Kallweit u32 mc_filter[2] = { 0xffffffff, 0xffffffff }; 257625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 257781cd17a4SHeiner Kallweit u32 tmp; 257825e992a4SHeiner Kallweit 257925e992a4SHeiner Kallweit if (dev->flags & IFF_PROMISC) { 258081cd17a4SHeiner Kallweit rx_mode |= AcceptAllPhys; 258181cd17a4SHeiner Kallweit } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || 258281cd17a4SHeiner Kallweit dev->flags & IFF_ALLMULTI || 258381cd17a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_35) { 258481cd17a4SHeiner Kallweit /* accept all multicasts */ 258581cd17a4SHeiner Kallweit } else if (netdev_mc_empty(dev)) { 258681cd17a4SHeiner Kallweit rx_mode &= ~AcceptMulticast; 258725e992a4SHeiner Kallweit } else { 258825e992a4SHeiner Kallweit struct netdev_hw_addr *ha; 258925e992a4SHeiner Kallweit 259025e992a4SHeiner Kallweit mc_filter[1] = mc_filter[0] = 0; 259125e992a4SHeiner Kallweit netdev_for_each_mc_addr(ha, dev) { 2592bc54ac36SHeiner Kallweit u32 bit_nr = eth_hw_addr_crc(ha) >> 26; 259381cd17a4SHeiner Kallweit mc_filter[bit_nr >> 5] |= BIT(bit_nr & 31); 259481cd17a4SHeiner Kallweit } 259581cd17a4SHeiner Kallweit 259681cd17a4SHeiner Kallweit if (tp->mac_version > RTL_GIGA_MAC_VER_06) { 259781cd17a4SHeiner Kallweit tmp = mc_filter[0]; 259881cd17a4SHeiner Kallweit mc_filter[0] = swab32(mc_filter[1]); 259981cd17a4SHeiner Kallweit mc_filter[1] = swab32(tmp); 260025e992a4SHeiner Kallweit } 260125e992a4SHeiner Kallweit } 260225e992a4SHeiner Kallweit 260325e992a4SHeiner Kallweit RTL_W32(tp, MAR0 + 4, mc_filter[1]); 260425e992a4SHeiner Kallweit RTL_W32(tp, MAR0 + 0, mc_filter[0]); 260525e992a4SHeiner Kallweit 260681cd17a4SHeiner Kallweit tmp = RTL_R32(tp, RxConfig); 260710478283SHeiner Kallweit RTL_W32(tp, RxConfig, (tmp & ~RX_CONFIG_ACCEPT_OK_MASK) | rx_mode); 260825e992a4SHeiner Kallweit } 260925e992a4SHeiner Kallweit 261025e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_csiar_cond) 261125e992a4SHeiner Kallweit { 261225e992a4SHeiner Kallweit return RTL_R32(tp, CSIAR) & CSIAR_FLAG; 261325e992a4SHeiner Kallweit } 261425e992a4SHeiner Kallweit 261525e992a4SHeiner Kallweit static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value) 261625e992a4SHeiner Kallweit { 261725e992a4SHeiner Kallweit u32 func = PCI_FUNC(tp->pci_dev->devfn); 261825e992a4SHeiner Kallweit 261925e992a4SHeiner Kallweit RTL_W32(tp, CSIDR, value); 262025e992a4SHeiner Kallweit RTL_W32(tp, CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | 262125e992a4SHeiner Kallweit CSIAR_BYTE_ENABLE | func << 16); 262225e992a4SHeiner Kallweit 2623d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_csiar_cond, 10, 100); 262425e992a4SHeiner Kallweit } 262525e992a4SHeiner Kallweit 262625e992a4SHeiner Kallweit static u32 rtl_csi_read(struct rtl8169_private *tp, int addr) 262725e992a4SHeiner Kallweit { 262825e992a4SHeiner Kallweit u32 func = PCI_FUNC(tp->pci_dev->devfn); 262925e992a4SHeiner Kallweit 263025e992a4SHeiner Kallweit RTL_W32(tp, CSIAR, (addr & CSIAR_ADDR_MASK) | func << 16 | 263125e992a4SHeiner Kallweit CSIAR_BYTE_ENABLE); 263225e992a4SHeiner Kallweit 2633d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ? 263425e992a4SHeiner Kallweit RTL_R32(tp, CSIDR) : ~0; 263525e992a4SHeiner Kallweit } 263625e992a4SHeiner Kallweit 263725e992a4SHeiner Kallweit static void rtl_csi_access_enable(struct rtl8169_private *tp, u8 val) 263825e992a4SHeiner Kallweit { 263925e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 264025e992a4SHeiner Kallweit u32 csi; 264125e992a4SHeiner Kallweit 264225e992a4SHeiner Kallweit /* According to Realtek the value at config space address 0x070f 264325e992a4SHeiner Kallweit * controls the L0s/L1 entrance latency. We try standard ECAM access 264425e992a4SHeiner Kallweit * first and if it fails fall back to CSI. 264525e992a4SHeiner Kallweit */ 264625e992a4SHeiner Kallweit if (pdev->cfg_size > 0x070f && 264725e992a4SHeiner Kallweit pci_write_config_byte(pdev, 0x070f, val) == PCIBIOS_SUCCESSFUL) 264825e992a4SHeiner Kallweit return; 264925e992a4SHeiner Kallweit 265025e992a4SHeiner Kallweit netdev_notice_once(tp->dev, 265125e992a4SHeiner Kallweit "No native access to PCI extended config space, falling back to CSI\n"); 265225e992a4SHeiner Kallweit csi = rtl_csi_read(tp, 0x070c) & 0x00ffffff; 265325e992a4SHeiner Kallweit rtl_csi_write(tp, 0x070c, csi | val << 24); 265425e992a4SHeiner Kallweit } 265525e992a4SHeiner Kallweit 265625e992a4SHeiner Kallweit static void rtl_set_def_aspm_entry_latency(struct rtl8169_private *tp) 265725e992a4SHeiner Kallweit { 265825e992a4SHeiner Kallweit rtl_csi_access_enable(tp, 0x27); 265925e992a4SHeiner Kallweit } 266025e992a4SHeiner Kallweit 266125e992a4SHeiner Kallweit struct ephy_info { 266225e992a4SHeiner Kallweit unsigned int offset; 266325e992a4SHeiner Kallweit u16 mask; 266425e992a4SHeiner Kallweit u16 bits; 266525e992a4SHeiner Kallweit }; 266625e992a4SHeiner Kallweit 266725e992a4SHeiner Kallweit static void __rtl_ephy_init(struct rtl8169_private *tp, 266825e992a4SHeiner Kallweit const struct ephy_info *e, int len) 266925e992a4SHeiner Kallweit { 267025e992a4SHeiner Kallweit u16 w; 267125e992a4SHeiner Kallweit 267225e992a4SHeiner Kallweit while (len-- > 0) { 267325e992a4SHeiner Kallweit w = (rtl_ephy_read(tp, e->offset) & ~e->mask) | e->bits; 267425e992a4SHeiner Kallweit rtl_ephy_write(tp, e->offset, w); 267525e992a4SHeiner Kallweit e++; 267625e992a4SHeiner Kallweit } 267725e992a4SHeiner Kallweit } 267825e992a4SHeiner Kallweit 267925e992a4SHeiner Kallweit #define rtl_ephy_init(tp, a) __rtl_ephy_init(tp, a, ARRAY_SIZE(a)) 268025e992a4SHeiner Kallweit 268125e992a4SHeiner Kallweit static void rtl_disable_clock_request(struct rtl8169_private *tp) 268225e992a4SHeiner Kallweit { 268325e992a4SHeiner Kallweit pcie_capability_clear_word(tp->pci_dev, PCI_EXP_LNKCTL, 268425e992a4SHeiner Kallweit PCI_EXP_LNKCTL_CLKREQ_EN); 268525e992a4SHeiner Kallweit } 268625e992a4SHeiner Kallweit 268725e992a4SHeiner Kallweit static void rtl_enable_clock_request(struct rtl8169_private *tp) 268825e992a4SHeiner Kallweit { 268925e992a4SHeiner Kallweit pcie_capability_set_word(tp->pci_dev, PCI_EXP_LNKCTL, 269025e992a4SHeiner Kallweit PCI_EXP_LNKCTL_CLKREQ_EN); 269125e992a4SHeiner Kallweit } 269225e992a4SHeiner Kallweit 269325e992a4SHeiner Kallweit static void rtl_pcie_state_l2l3_disable(struct rtl8169_private *tp) 269425e992a4SHeiner Kallweit { 269525e992a4SHeiner Kallweit /* work around an issue when PCI reset occurs during L2/L3 state */ 269625e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Rdy_to_L23); 269725e992a4SHeiner Kallweit } 269825e992a4SHeiner Kallweit 269925e992a4SHeiner Kallweit static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) 270025e992a4SHeiner Kallweit { 270162b1b3b3SHeiner Kallweit /* Don't enable ASPM in the chip if OS can't control ASPM */ 270262b1b3b3SHeiner Kallweit if (enable && tp->aspm_manageable) { 270325e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) | ASPM_en); 270425e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) | ClkReqEn); 270525e992a4SHeiner Kallweit } else { 270625e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn); 270725e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en); 270825e992a4SHeiner Kallweit } 270925e992a4SHeiner Kallweit 271025e992a4SHeiner Kallweit udelay(10); 271125e992a4SHeiner Kallweit } 271225e992a4SHeiner Kallweit 271325e992a4SHeiner Kallweit static void rtl_set_fifo_size(struct rtl8169_private *tp, u16 rx_stat, 271425e992a4SHeiner Kallweit u16 tx_stat, u16 rx_dyn, u16 tx_dyn) 271525e992a4SHeiner Kallweit { 271625e992a4SHeiner Kallweit /* Usage of dynamic vs. static FIFO is controlled by bit 271725e992a4SHeiner Kallweit * TXCFG_AUTO_FIFO. Exact meaning of FIFO values isn't known. 271825e992a4SHeiner Kallweit */ 271925e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, (rx_stat << 16) | rx_dyn); 272025e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, (tx_stat << 16) | tx_dyn); 272125e992a4SHeiner Kallweit } 272225e992a4SHeiner Kallweit 272325e992a4SHeiner Kallweit static void rtl8168g_set_pause_thresholds(struct rtl8169_private *tp, 272425e992a4SHeiner Kallweit u8 low, u8 high) 272525e992a4SHeiner Kallweit { 272625e992a4SHeiner Kallweit /* FIFO thresholds for pause flow control */ 272725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, low); 272825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, high); 272925e992a4SHeiner Kallweit } 273025e992a4SHeiner Kallweit 273194b5ff74SHeiner Kallweit static void rtl_hw_start_8168b(struct rtl8169_private *tp) 273225e992a4SHeiner Kallweit { 273325e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 273425e992a4SHeiner Kallweit } 273525e992a4SHeiner Kallweit 273625e992a4SHeiner Kallweit static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) 273725e992a4SHeiner Kallweit { 273825e992a4SHeiner Kallweit RTL_W8(tp, Config1, RTL_R8(tp, Config1) | Speed_down); 273925e992a4SHeiner Kallweit 274025e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 274125e992a4SHeiner Kallweit 274225e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 274325e992a4SHeiner Kallweit } 274425e992a4SHeiner Kallweit 274525e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) 274625e992a4SHeiner Kallweit { 274725e992a4SHeiner Kallweit static const struct ephy_info e_info_8168cp[] = { 274825e992a4SHeiner Kallweit { 0x01, 0, 0x0001 }, 274925e992a4SHeiner Kallweit { 0x02, 0x0800, 0x1000 }, 275025e992a4SHeiner Kallweit { 0x03, 0, 0x0042 }, 275125e992a4SHeiner Kallweit { 0x06, 0x0080, 0x0000 }, 275225e992a4SHeiner Kallweit { 0x07, 0, 0x2000 } 275325e992a4SHeiner Kallweit }; 275425e992a4SHeiner Kallweit 275525e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 275625e992a4SHeiner Kallweit 275725e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168cp); 275825e992a4SHeiner Kallweit 275925e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 276025e992a4SHeiner Kallweit } 276125e992a4SHeiner Kallweit 276225e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) 276325e992a4SHeiner Kallweit { 276425e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 276525e992a4SHeiner Kallweit 276625e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 276725e992a4SHeiner Kallweit } 276825e992a4SHeiner Kallweit 276925e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) 277025e992a4SHeiner Kallweit { 277125e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 277225e992a4SHeiner Kallweit 277325e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 277425e992a4SHeiner Kallweit 277525e992a4SHeiner Kallweit /* Magic. */ 277625e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, 0x20); 277725e992a4SHeiner Kallweit } 277825e992a4SHeiner Kallweit 277925e992a4SHeiner Kallweit static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) 278025e992a4SHeiner Kallweit { 278125e992a4SHeiner Kallweit static const struct ephy_info e_info_8168c_1[] = { 278225e992a4SHeiner Kallweit { 0x02, 0x0800, 0x1000 }, 278325e992a4SHeiner Kallweit { 0x03, 0, 0x0002 }, 278425e992a4SHeiner Kallweit { 0x06, 0x0080, 0x0000 } 278525e992a4SHeiner Kallweit }; 278625e992a4SHeiner Kallweit 278725e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 278825e992a4SHeiner Kallweit 278925e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); 279025e992a4SHeiner Kallweit 279125e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168c_1); 279225e992a4SHeiner Kallweit 279325e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 279425e992a4SHeiner Kallweit } 279525e992a4SHeiner Kallweit 279625e992a4SHeiner Kallweit static void rtl_hw_start_8168c_2(struct rtl8169_private *tp) 279725e992a4SHeiner Kallweit { 279825e992a4SHeiner Kallweit static const struct ephy_info e_info_8168c_2[] = { 279925e992a4SHeiner Kallweit { 0x01, 0, 0x0001 }, 2800a7a92cf8SHeiner Kallweit { 0x03, 0x0400, 0x0020 } 280125e992a4SHeiner Kallweit }; 280225e992a4SHeiner Kallweit 280325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 280425e992a4SHeiner Kallweit 280525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168c_2); 280625e992a4SHeiner Kallweit 280725e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 280825e992a4SHeiner Kallweit } 280925e992a4SHeiner Kallweit 281025e992a4SHeiner Kallweit static void rtl_hw_start_8168c_3(struct rtl8169_private *tp) 281125e992a4SHeiner Kallweit { 281225e992a4SHeiner Kallweit rtl_hw_start_8168c_2(tp); 281325e992a4SHeiner Kallweit } 281425e992a4SHeiner Kallweit 281525e992a4SHeiner Kallweit static void rtl_hw_start_8168c_4(struct rtl8169_private *tp) 281625e992a4SHeiner Kallweit { 281725e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 281825e992a4SHeiner Kallweit 281925e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp); 282025e992a4SHeiner Kallweit } 282125e992a4SHeiner Kallweit 282225e992a4SHeiner Kallweit static void rtl_hw_start_8168d(struct rtl8169_private *tp) 282325e992a4SHeiner Kallweit { 282425e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 282525e992a4SHeiner Kallweit 282625e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 282725e992a4SHeiner Kallweit } 282825e992a4SHeiner Kallweit 282925e992a4SHeiner Kallweit static void rtl_hw_start_8168d_4(struct rtl8169_private *tp) 283025e992a4SHeiner Kallweit { 283125e992a4SHeiner Kallweit static const struct ephy_info e_info_8168d_4[] = { 283225e992a4SHeiner Kallweit { 0x0b, 0x0000, 0x0048 }, 283325e992a4SHeiner Kallweit { 0x19, 0x0020, 0x0050 }, 2834a7a92cf8SHeiner Kallweit { 0x0c, 0x0100, 0x0020 }, 2835a7a92cf8SHeiner Kallweit { 0x10, 0x0004, 0x0000 }, 283625e992a4SHeiner Kallweit }; 283725e992a4SHeiner Kallweit 283825e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 283925e992a4SHeiner Kallweit 284025e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168d_4); 284125e992a4SHeiner Kallweit 284225e992a4SHeiner Kallweit rtl_enable_clock_request(tp); 284325e992a4SHeiner Kallweit } 284425e992a4SHeiner Kallweit 284525e992a4SHeiner Kallweit static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) 284625e992a4SHeiner Kallweit { 284725e992a4SHeiner Kallweit static const struct ephy_info e_info_8168e_1[] = { 284825e992a4SHeiner Kallweit { 0x00, 0x0200, 0x0100 }, 284925e992a4SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 285025e992a4SHeiner Kallweit { 0x06, 0x0002, 0x0001 }, 285125e992a4SHeiner Kallweit { 0x06, 0x0000, 0x0030 }, 285225e992a4SHeiner Kallweit { 0x07, 0x0000, 0x2000 }, 285325e992a4SHeiner Kallweit { 0x00, 0x0000, 0x0020 }, 285425e992a4SHeiner Kallweit { 0x03, 0x5800, 0x2000 }, 285525e992a4SHeiner Kallweit { 0x03, 0x0000, 0x0001 }, 285625e992a4SHeiner Kallweit { 0x01, 0x0800, 0x1000 }, 285725e992a4SHeiner Kallweit { 0x07, 0x0000, 0x4000 }, 285825e992a4SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 285925e992a4SHeiner Kallweit { 0x19, 0xffff, 0xfe6c }, 286025e992a4SHeiner Kallweit { 0x0a, 0x0000, 0x0040 } 286125e992a4SHeiner Kallweit }; 286225e992a4SHeiner Kallweit 286325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 286425e992a4SHeiner Kallweit 286525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168e_1); 286625e992a4SHeiner Kallweit 286725e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 286825e992a4SHeiner Kallweit 286925e992a4SHeiner Kallweit /* Reset tx FIFO pointer */ 287025e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | TXPLA_RST); 287125e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~TXPLA_RST); 287225e992a4SHeiner Kallweit 287325e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 287425e992a4SHeiner Kallweit } 287525e992a4SHeiner Kallweit 287625e992a4SHeiner Kallweit static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) 287725e992a4SHeiner Kallweit { 287825e992a4SHeiner Kallweit static const struct ephy_info e_info_8168e_2[] = { 287925e992a4SHeiner Kallweit { 0x09, 0x0000, 0x0080 }, 2880a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2881a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2882a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 288325e992a4SHeiner Kallweit }; 288425e992a4SHeiner Kallweit 288525e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 288625e992a4SHeiner Kallweit 288725e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168e_2); 288825e992a4SHeiner Kallweit 288925e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 289025e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 289125e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); 289225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050); 289325e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x07ff0060); 289425e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, ERIAR_MASK_0001, BIT(4)); 289525e992a4SHeiner Kallweit rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00); 289625e992a4SHeiner Kallweit 289725e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 289825e992a4SHeiner Kallweit 289925e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 290025e992a4SHeiner Kallweit 290125e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 290225e992a4SHeiner Kallweit 290325e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 290425e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN); 290525e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 290625e992a4SHeiner Kallweit 290725e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 290825e992a4SHeiner Kallweit } 290925e992a4SHeiner Kallweit 291025e992a4SHeiner Kallweit static void rtl_hw_start_8168f(struct rtl8169_private *tp) 291125e992a4SHeiner Kallweit { 291225e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 291325e992a4SHeiner Kallweit 291425e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 291525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 291625e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); 291725e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 291825e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, ERIAR_MASK_0001, BIT(4)); 291925e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0x1d0, ERIAR_MASK_0001, BIT(4)); 292025e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050); 292125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060); 292225e992a4SHeiner Kallweit 292325e992a4SHeiner Kallweit rtl_disable_clock_request(tp); 292425e992a4SHeiner Kallweit 292525e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 292625e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 292725e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN); 292825e992a4SHeiner Kallweit RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en); 292925e992a4SHeiner Kallweit 293025e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 293125e992a4SHeiner Kallweit } 293225e992a4SHeiner Kallweit 293325e992a4SHeiner Kallweit static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) 293425e992a4SHeiner Kallweit { 293525e992a4SHeiner Kallweit static const struct ephy_info e_info_8168f_1[] = { 293625e992a4SHeiner Kallweit { 0x06, 0x00c0, 0x0020 }, 293725e992a4SHeiner Kallweit { 0x08, 0x0001, 0x0002 }, 293825e992a4SHeiner Kallweit { 0x09, 0x0000, 0x0080 }, 2939a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2940a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2941a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 294225e992a4SHeiner Kallweit }; 294325e992a4SHeiner Kallweit 294425e992a4SHeiner Kallweit rtl_hw_start_8168f(tp); 294525e992a4SHeiner Kallweit 294625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168f_1); 294725e992a4SHeiner Kallweit 294825e992a4SHeiner Kallweit rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00); 294925e992a4SHeiner Kallweit } 295025e992a4SHeiner Kallweit 295125e992a4SHeiner Kallweit static void rtl_hw_start_8411(struct rtl8169_private *tp) 295225e992a4SHeiner Kallweit { 295325e992a4SHeiner Kallweit static const struct ephy_info e_info_8168f_1[] = { 295425e992a4SHeiner Kallweit { 0x06, 0x00c0, 0x0020 }, 295525e992a4SHeiner Kallweit { 0x0f, 0xffff, 0x5200 }, 2956a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 }, 2957a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 }, 2958a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 }, 295925e992a4SHeiner Kallweit }; 296025e992a4SHeiner Kallweit 296125e992a4SHeiner Kallweit rtl_hw_start_8168f(tp); 296225e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 296325e992a4SHeiner Kallweit 296425e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168f_1); 296525e992a4SHeiner Kallweit 296625e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00); 296725e992a4SHeiner Kallweit } 296825e992a4SHeiner Kallweit 296925e992a4SHeiner Kallweit static void rtl_hw_start_8168g(struct rtl8169_private *tp) 297025e992a4SHeiner Kallweit { 297125e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 297225e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x38, 0x48); 297325e992a4SHeiner Kallweit 297425e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 297525e992a4SHeiner Kallweit 297625e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 297725e992a4SHeiner Kallweit rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f); 297825e992a4SHeiner Kallweit 297925e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 298025e992a4SHeiner Kallweit 298125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 298225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 298325e992a4SHeiner Kallweit 298425e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 298525e992a4SHeiner Kallweit 298625e992a4SHeiner Kallweit rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06); 298725e992a4SHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, ERIAR_MASK_0011, BIT(12)); 298825e992a4SHeiner Kallweit 298925e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 299025e992a4SHeiner Kallweit } 299125e992a4SHeiner Kallweit 299225e992a4SHeiner Kallweit static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) 299325e992a4SHeiner Kallweit { 299425e992a4SHeiner Kallweit static const struct ephy_info e_info_8168g_1[] = { 2995a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 2996a7a92cf8SHeiner Kallweit { 0x0c, 0x3ff0, 0x0820 }, 299725e992a4SHeiner Kallweit { 0x1e, 0x0000, 0x0001 }, 299825e992a4SHeiner Kallweit { 0x19, 0x8000, 0x0000 } 299925e992a4SHeiner Kallweit }; 300025e992a4SHeiner Kallweit 300125e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 300225e992a4SHeiner Kallweit 300325e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 300425e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 300525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168g_1); 300625e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 300725e992a4SHeiner Kallweit } 300825e992a4SHeiner Kallweit 300925e992a4SHeiner Kallweit static void rtl_hw_start_8168g_2(struct rtl8169_private *tp) 301025e992a4SHeiner Kallweit { 301125e992a4SHeiner Kallweit static const struct ephy_info e_info_8168g_2[] = { 3012a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 3013a7a92cf8SHeiner Kallweit { 0x0c, 0x3ff0, 0x0820 }, 3014a7a92cf8SHeiner Kallweit { 0x19, 0xffff, 0x7c00 }, 3015a7a92cf8SHeiner Kallweit { 0x1e, 0xffff, 0x20eb }, 3016a7a92cf8SHeiner Kallweit { 0x0d, 0xffff, 0x1666 }, 3017a7a92cf8SHeiner Kallweit { 0x00, 0xffff, 0x10a3 }, 3018a7a92cf8SHeiner Kallweit { 0x06, 0xffff, 0xf050 }, 3019a7a92cf8SHeiner Kallweit { 0x04, 0x0000, 0x0010 }, 3020a7a92cf8SHeiner Kallweit { 0x1d, 0x4000, 0x0000 }, 302125e992a4SHeiner Kallweit }; 302225e992a4SHeiner Kallweit 302325e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 302425e992a4SHeiner Kallweit 302525e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 3026ebdcebcbSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 302725e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168g_2); 302825e992a4SHeiner Kallweit } 302925e992a4SHeiner Kallweit 303025e992a4SHeiner Kallweit static void rtl_hw_start_8411_2(struct rtl8169_private *tp) 303125e992a4SHeiner Kallweit { 303225e992a4SHeiner Kallweit static const struct ephy_info e_info_8411_2[] = { 3033a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 }, 3034a7a92cf8SHeiner Kallweit { 0x0c, 0x37d0, 0x0820 }, 3035a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x0001 }, 3036a7a92cf8SHeiner Kallweit { 0x19, 0x8021, 0x0000 }, 3037a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 3038a7a92cf8SHeiner Kallweit { 0x0d, 0x0100, 0x0200 }, 3039a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0080 }, 3040a7a92cf8SHeiner Kallweit { 0x06, 0x0000, 0x0010 }, 3041a7a92cf8SHeiner Kallweit { 0x04, 0x0000, 0x0010 }, 3042a7a92cf8SHeiner Kallweit { 0x1d, 0x0000, 0x4000 }, 304325e992a4SHeiner Kallweit }; 304425e992a4SHeiner Kallweit 304525e992a4SHeiner Kallweit rtl_hw_start_8168g(tp); 304625e992a4SHeiner Kallweit 304725e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 304825e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 304925e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8411_2); 3050fe4e8db0SHeiner Kallweit 3051fe4e8db0SHeiner Kallweit /* The following Realtek-provided magic fixes an issue with the RX unit 3052fe4e8db0SHeiner Kallweit * getting confused after the PHY having been powered-down. 3053fe4e8db0SHeiner Kallweit */ 3054fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC28, 0x0000); 3055fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2A, 0x0000); 3056fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2C, 0x0000); 3057fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2E, 0x0000); 3058fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC30, 0x0000); 3059fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC32, 0x0000); 3060fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC34, 0x0000); 3061fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC36, 0x0000); 3062fe4e8db0SHeiner Kallweit mdelay(3); 3063fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC26, 0x0000); 3064fe4e8db0SHeiner Kallweit 3065fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF800, 0xE008); 3066fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF802, 0xE00A); 3067fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF804, 0xE00C); 3068fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF806, 0xE00E); 3069fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF808, 0xE027); 3070fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80A, 0xE04F); 3071fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80C, 0xE05E); 3072fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80E, 0xE065); 3073fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF810, 0xC602); 3074fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF812, 0xBE00); 3075fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF814, 0x0000); 3076fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF816, 0xC502); 3077fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF818, 0xBD00); 3078fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81A, 0x074C); 3079fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81C, 0xC302); 3080fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81E, 0xBB00); 3081fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF820, 0x080A); 3082fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF822, 0x6420); 3083fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF824, 0x48C2); 3084fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF826, 0x8C20); 3085fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF828, 0xC516); 3086fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82A, 0x64A4); 3087fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82C, 0x49C0); 3088fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82E, 0xF009); 3089fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF830, 0x74A2); 3090fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF832, 0x8CA5); 3091fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF834, 0x74A0); 3092fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF836, 0xC50E); 3093fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF838, 0x9CA2); 3094fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83A, 0x1C11); 3095fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83C, 0x9CA0); 3096fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83E, 0xE006); 3097fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF840, 0x74F8); 3098fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF842, 0x48C4); 3099fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF844, 0x8CF8); 3100fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF846, 0xC404); 3101fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF848, 0xBC00); 3102fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84A, 0xC403); 3103fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84C, 0xBC00); 3104fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84E, 0x0BF2); 3105fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF850, 0x0C0A); 3106fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF852, 0xE434); 3107fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF854, 0xD3C0); 3108fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF856, 0x49D9); 3109fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF858, 0xF01F); 3110fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85A, 0xC526); 3111fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85C, 0x64A5); 3112fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85E, 0x1400); 3113fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF860, 0xF007); 3114fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF862, 0x0C01); 3115fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF864, 0x8CA5); 3116fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF866, 0x1C15); 3117fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF868, 0xC51B); 3118fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86A, 0x9CA0); 3119fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86C, 0xE013); 3120fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86E, 0xC519); 3121fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF870, 0x74A0); 3122fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF872, 0x48C4); 3123fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF874, 0x8CA0); 3124fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF876, 0xC516); 3125fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF878, 0x74A4); 3126fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87A, 0x48C8); 3127fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87C, 0x48CA); 3128fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87E, 0x9CA4); 3129fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF880, 0xC512); 3130fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF882, 0x1B00); 3131fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF884, 0x9BA0); 3132fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF886, 0x1B1C); 3133fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF888, 0x483F); 3134fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88A, 0x9BA2); 3135fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88C, 0x1B04); 3136fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88E, 0xC508); 3137fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF890, 0x9BA0); 3138fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF892, 0xC505); 3139fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF894, 0xBD00); 3140fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF896, 0xC502); 3141fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF898, 0xBD00); 3142fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89A, 0x0300); 3143fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89C, 0x051E); 3144fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89E, 0xE434); 3145fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A0, 0xE018); 3146fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A2, 0xE092); 3147fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A4, 0xDE20); 3148fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A6, 0xD3C0); 3149fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A8, 0xC50F); 3150fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AA, 0x76A4); 3151fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AC, 0x49E3); 3152fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AE, 0xF007); 3153fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B0, 0x49C0); 3154fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B2, 0xF103); 3155fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B4, 0xC607); 3156fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B6, 0xBE00); 3157fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B8, 0xC606); 3158fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BA, 0xBE00); 3159fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BC, 0xC602); 3160fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BE, 0xBE00); 3161fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C0, 0x0C4C); 3162fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C2, 0x0C28); 3163fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C4, 0x0C2C); 3164fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C6, 0xDC00); 3165fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C8, 0xC707); 3166fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CA, 0x1D00); 3167fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CC, 0x8DE2); 3168fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CE, 0x48C1); 3169fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D0, 0xC502); 3170fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D2, 0xBD00); 3171fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D4, 0x00AA); 3172fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D6, 0xE0C0); 3173fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D8, 0xC502); 3174fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8DA, 0xBD00); 3175fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8DC, 0x0132); 3176fe4e8db0SHeiner Kallweit 3177fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC26, 0x8000); 3178fe4e8db0SHeiner Kallweit 3179fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2A, 0x0743); 3180fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2C, 0x0801); 3181fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2E, 0x0BE9); 3182fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC30, 0x02FD); 3183fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC32, 0x0C25); 3184fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC34, 0x00A9); 3185fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC36, 0x012D); 3186fe4e8db0SHeiner Kallweit 318725e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 318825e992a4SHeiner Kallweit } 318925e992a4SHeiner Kallweit 319025e992a4SHeiner Kallweit static void rtl_hw_start_8168h_1(struct rtl8169_private *tp) 319125e992a4SHeiner Kallweit { 319225e992a4SHeiner Kallweit static const struct ephy_info e_info_8168h_1[] = { 319325e992a4SHeiner Kallweit { 0x1e, 0x0800, 0x0001 }, 319425e992a4SHeiner Kallweit { 0x1d, 0x0000, 0x0800 }, 319525e992a4SHeiner Kallweit { 0x05, 0xffff, 0x2089 }, 319625e992a4SHeiner Kallweit { 0x06, 0xffff, 0x5881 }, 3197a7a92cf8SHeiner Kallweit { 0x04, 0xffff, 0x854a }, 319825e992a4SHeiner Kallweit { 0x01, 0xffff, 0x068b } 319925e992a4SHeiner Kallweit }; 3200ef712edeSHeiner Kallweit int rg_saw_cnt; 320125e992a4SHeiner Kallweit 320225e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 320325e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 320425e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168h_1); 320525e992a4SHeiner Kallweit 320625e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 320725e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x38, 0x48); 320825e992a4SHeiner Kallweit 320925e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 321025e992a4SHeiner Kallweit 321125e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 321225e992a4SHeiner Kallweit 321325e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0xdc, ERIAR_MASK_1111, BIT(4)); 321425e992a4SHeiner Kallweit 321525e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, ERIAR_MASK_1111, 0x1f00); 321625e992a4SHeiner Kallweit 321725e992a4SHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 321825e992a4SHeiner Kallweit 321925e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 322025e992a4SHeiner Kallweit 322125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 322225e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 322325e992a4SHeiner Kallweit 322425e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 322525e992a4SHeiner Kallweit 322625e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 322725e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 322825e992a4SHeiner Kallweit 322925e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 323025e992a4SHeiner Kallweit 323125e992a4SHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, ERIAR_MASK_0011, BIT(12)); 323225e992a4SHeiner Kallweit 323325e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 323425e992a4SHeiner Kallweit 32353ab077d2SHeiner Kallweit rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff; 323625e992a4SHeiner Kallweit if (rg_saw_cnt > 0) { 323725e992a4SHeiner Kallweit u16 sw_cnt_1ms_ini; 323825e992a4SHeiner Kallweit 323925e992a4SHeiner Kallweit sw_cnt_1ms_ini = 16000000/rg_saw_cnt; 324025e992a4SHeiner Kallweit sw_cnt_1ms_ini &= 0x0fff; 3241ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini); 324225e992a4SHeiner Kallweit } 324325e992a4SHeiner Kallweit 3244ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070); 3245ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x6000, 0x8008); 3246ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe0d6, 0x01ff, 0x017f); 3247ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f); 324825e992a4SHeiner Kallweit 324925e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0001); 325025e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0000); 325125e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xc094, 0x0000); 325225e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xc09e, 0x0000); 325325e992a4SHeiner Kallweit 325425e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 325525e992a4SHeiner Kallweit } 325625e992a4SHeiner Kallweit 325725e992a4SHeiner Kallweit static void rtl_hw_start_8168ep(struct rtl8169_private *tp) 325825e992a4SHeiner Kallweit { 325925e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp); 326025e992a4SHeiner Kallweit 326125e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 326225e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f); 326325e992a4SHeiner Kallweit 326425e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 326525e992a4SHeiner Kallweit 326625e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 326725e992a4SHeiner Kallweit 326825e992a4SHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, ERIAR_MASK_1111, 0x1f80); 326925e992a4SHeiner Kallweit 327025e992a4SHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 327125e992a4SHeiner Kallweit 327225e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 327325e992a4SHeiner Kallweit 327425e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 327525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 327625e992a4SHeiner Kallweit 327725e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp); 327825e992a4SHeiner Kallweit 327925e992a4SHeiner Kallweit rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06); 328025e992a4SHeiner Kallweit 328125e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 328225e992a4SHeiner Kallweit 328325e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 328425e992a4SHeiner Kallweit } 328525e992a4SHeiner Kallweit 328625e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_1(struct rtl8169_private *tp) 328725e992a4SHeiner Kallweit { 328825e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_1[] = { 328925e992a4SHeiner Kallweit { 0x00, 0xffff, 0x10ab }, 329025e992a4SHeiner Kallweit { 0x06, 0xffff, 0xf030 }, 329125e992a4SHeiner Kallweit { 0x08, 0xffff, 0x2006 }, 329225e992a4SHeiner Kallweit { 0x0d, 0xffff, 0x1666 }, 329325e992a4SHeiner Kallweit { 0x0c, 0x3ff0, 0x0000 } 329425e992a4SHeiner Kallweit }; 329525e992a4SHeiner Kallweit 329625e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 329725e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 329825e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_1); 329925e992a4SHeiner Kallweit 330025e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 330125e992a4SHeiner Kallweit 330225e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 330325e992a4SHeiner Kallweit } 330425e992a4SHeiner Kallweit 330525e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_2(struct rtl8169_private *tp) 330625e992a4SHeiner Kallweit { 330725e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_2[] = { 330825e992a4SHeiner Kallweit { 0x00, 0xffff, 0x10a3 }, 330925e992a4SHeiner Kallweit { 0x19, 0xffff, 0xfc00 }, 331025e992a4SHeiner Kallweit { 0x1e, 0xffff, 0x20ea } 331125e992a4SHeiner Kallweit }; 331225e992a4SHeiner Kallweit 331325e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 331425e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 331525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_2); 331625e992a4SHeiner Kallweit 331725e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 331825e992a4SHeiner Kallweit 331925e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 332025e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 332125e992a4SHeiner Kallweit 332225e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 332325e992a4SHeiner Kallweit } 332425e992a4SHeiner Kallweit 332525e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp) 332625e992a4SHeiner Kallweit { 332725e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_3[] = { 3328a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0080 }, 3329a7a92cf8SHeiner Kallweit { 0x0d, 0x0100, 0x0200 }, 3330a7a92cf8SHeiner Kallweit { 0x19, 0x8021, 0x0000 }, 3331a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x2000 }, 333225e992a4SHeiner Kallweit }; 333325e992a4SHeiner Kallweit 333425e992a4SHeiner Kallweit /* disable aspm and clock request before access ephy */ 333525e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 333625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_3); 333725e992a4SHeiner Kallweit 333825e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp); 333925e992a4SHeiner Kallweit 334025e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 334125e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 334225e992a4SHeiner Kallweit 3343ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e2, 0x0fff, 0x0271); 3344ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e4, 0x00ff, 0x0000); 3345ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe860, 0x0000, 0x0080); 334625e992a4SHeiner Kallweit 334725e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 334825e992a4SHeiner Kallweit } 334925e992a4SHeiner Kallweit 33501287723aSHeiner Kallweit static void rtl_hw_start_8117(struct rtl8169_private *tp) 33511287723aSHeiner Kallweit { 33521287723aSHeiner Kallweit static const struct ephy_info e_info_8117[] = { 33531287723aSHeiner Kallweit { 0x19, 0x0040, 0x1100 }, 33541287723aSHeiner Kallweit { 0x59, 0x0040, 0x1100 }, 33551287723aSHeiner Kallweit }; 33561287723aSHeiner Kallweit int rg_saw_cnt; 33571287723aSHeiner Kallweit 33581287723aSHeiner Kallweit rtl8168ep_stop_cmac(tp); 33591287723aSHeiner Kallweit 33601287723aSHeiner Kallweit /* disable aspm and clock request before access ephy */ 33611287723aSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 33621287723aSHeiner Kallweit rtl_ephy_init(tp, e_info_8117); 33631287723aSHeiner Kallweit 33641287723aSHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); 33651287723aSHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f); 33661287723aSHeiner Kallweit 33671287723aSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 33681287723aSHeiner Kallweit 33691287723aSHeiner Kallweit rtl_reset_packet_filter(tp); 33701287723aSHeiner Kallweit 33711287723aSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, ERIAR_MASK_1111, 0x1f90); 33721287723aSHeiner Kallweit 33731287723aSHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); 33741287723aSHeiner Kallweit 33751287723aSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 33761287723aSHeiner Kallweit 33771287723aSHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 33781287723aSHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 33791287723aSHeiner Kallweit 33801287723aSHeiner Kallweit rtl8168_config_eee_mac(tp); 33811287723aSHeiner Kallweit 33821287723aSHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 33831287723aSHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); 33841287723aSHeiner Kallweit 33851287723aSHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); 33861287723aSHeiner Kallweit 33871287723aSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, ERIAR_MASK_0011, BIT(12)); 33881287723aSHeiner Kallweit 33891287723aSHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 33901287723aSHeiner Kallweit 33911287723aSHeiner Kallweit rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff; 33921287723aSHeiner Kallweit if (rg_saw_cnt > 0) { 33931287723aSHeiner Kallweit u16 sw_cnt_1ms_ini; 33941287723aSHeiner Kallweit 33951287723aSHeiner Kallweit sw_cnt_1ms_ini = (16000000 / rg_saw_cnt) & 0x0fff; 33961287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini); 33971287723aSHeiner Kallweit } 33981287723aSHeiner Kallweit 33991287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070); 34001287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xea80, 0x0003); 34011287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x0000, 0x0009); 34021287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f); 34031287723aSHeiner Kallweit 34041287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0001); 34051287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0000); 34061287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc094, 0x0000); 34071287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc09e, 0x0000); 34081287723aSHeiner Kallweit 3409229c1e0dSHeiner Kallweit /* firmware is for MAC only */ 34101c5be5e9SHeiner Kallweit r8169_apply_firmware(tp); 3411229c1e0dSHeiner Kallweit 34121287723aSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 34131287723aSHeiner Kallweit } 34141287723aSHeiner Kallweit 341525e992a4SHeiner Kallweit static void rtl_hw_start_8102e_1(struct rtl8169_private *tp) 341625e992a4SHeiner Kallweit { 341725e992a4SHeiner Kallweit static const struct ephy_info e_info_8102e_1[] = { 341825e992a4SHeiner Kallweit { 0x01, 0, 0x6e65 }, 341925e992a4SHeiner Kallweit { 0x02, 0, 0x091f }, 342025e992a4SHeiner Kallweit { 0x03, 0, 0xc2f9 }, 342125e992a4SHeiner Kallweit { 0x06, 0, 0xafb5 }, 342225e992a4SHeiner Kallweit { 0x07, 0, 0x0e00 }, 342325e992a4SHeiner Kallweit { 0x19, 0, 0xec80 }, 342425e992a4SHeiner Kallweit { 0x01, 0, 0x2e65 }, 342525e992a4SHeiner Kallweit { 0x01, 0, 0x6e65 } 342625e992a4SHeiner Kallweit }; 342725e992a4SHeiner Kallweit u8 cfg1; 342825e992a4SHeiner Kallweit 342925e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 343025e992a4SHeiner Kallweit 343125e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, FIX_NAK_1); 343225e992a4SHeiner Kallweit 343325e992a4SHeiner Kallweit RTL_W8(tp, Config1, 343425e992a4SHeiner Kallweit LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable); 343525e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 343625e992a4SHeiner Kallweit 343725e992a4SHeiner Kallweit cfg1 = RTL_R8(tp, Config1); 343825e992a4SHeiner Kallweit if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) 343925e992a4SHeiner Kallweit RTL_W8(tp, Config1, cfg1 & ~LEDS0); 344025e992a4SHeiner Kallweit 344125e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8102e_1); 344225e992a4SHeiner Kallweit } 344325e992a4SHeiner Kallweit 344425e992a4SHeiner Kallweit static void rtl_hw_start_8102e_2(struct rtl8169_private *tp) 344525e992a4SHeiner Kallweit { 344625e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 344725e992a4SHeiner Kallweit 344825e992a4SHeiner Kallweit RTL_W8(tp, Config1, MEMMAP | IOMAP | VPD | PMEnable); 344925e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); 345025e992a4SHeiner Kallweit } 345125e992a4SHeiner Kallweit 345225e992a4SHeiner Kallweit static void rtl_hw_start_8102e_3(struct rtl8169_private *tp) 345325e992a4SHeiner Kallweit { 345425e992a4SHeiner Kallweit rtl_hw_start_8102e_2(tp); 345525e992a4SHeiner Kallweit 345625e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x03, 0xc2f9); 345725e992a4SHeiner Kallweit } 345825e992a4SHeiner Kallweit 345925e992a4SHeiner Kallweit static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) 346025e992a4SHeiner Kallweit { 346125e992a4SHeiner Kallweit static const struct ephy_info e_info_8105e_1[] = { 346225e992a4SHeiner Kallweit { 0x07, 0, 0x4000 }, 346325e992a4SHeiner Kallweit { 0x19, 0, 0x0200 }, 346425e992a4SHeiner Kallweit { 0x19, 0, 0x0020 }, 346525e992a4SHeiner Kallweit { 0x1e, 0, 0x2000 }, 346625e992a4SHeiner Kallweit { 0x03, 0, 0x0001 }, 346725e992a4SHeiner Kallweit { 0x19, 0, 0x0100 }, 346825e992a4SHeiner Kallweit { 0x19, 0, 0x0004 }, 346925e992a4SHeiner Kallweit { 0x0a, 0, 0x0020 } 347025e992a4SHeiner Kallweit }; 347125e992a4SHeiner Kallweit 347225e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 347325e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 347425e992a4SHeiner Kallweit 347525e992a4SHeiner Kallweit /* Disable Early Tally Counter */ 347625e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) & ~0x010000); 347725e992a4SHeiner Kallweit 347825e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET); 347925e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN); 348025e992a4SHeiner Kallweit 348125e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8105e_1); 348225e992a4SHeiner Kallweit 348325e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 348425e992a4SHeiner Kallweit } 348525e992a4SHeiner Kallweit 348625e992a4SHeiner Kallweit static void rtl_hw_start_8105e_2(struct rtl8169_private *tp) 348725e992a4SHeiner Kallweit { 348825e992a4SHeiner Kallweit rtl_hw_start_8105e_1(tp); 348925e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x1e, rtl_ephy_read(tp, 0x1e) | 0x8000); 349025e992a4SHeiner Kallweit } 349125e992a4SHeiner Kallweit 349225e992a4SHeiner Kallweit static void rtl_hw_start_8402(struct rtl8169_private *tp) 349325e992a4SHeiner Kallweit { 349425e992a4SHeiner Kallweit static const struct ephy_info e_info_8402[] = { 349525e992a4SHeiner Kallweit { 0x19, 0xffff, 0xff64 }, 349625e992a4SHeiner Kallweit { 0x1e, 0, 0x4000 } 349725e992a4SHeiner Kallweit }; 349825e992a4SHeiner Kallweit 349925e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 350025e992a4SHeiner Kallweit 350125e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 350225e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 350325e992a4SHeiner Kallweit 350425e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 350525e992a4SHeiner Kallweit 350625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8402); 350725e992a4SHeiner Kallweit 350825e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x00, 0x00, 0x02, 0x06); 350925e992a4SHeiner Kallweit rtl_reset_packet_filter(tp); 351025e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); 351125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); 351225e992a4SHeiner Kallweit rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00); 351325e992a4SHeiner Kallweit 35146d7a631eSHeiner Kallweit /* disable EEE */ 35156d7a631eSHeiner Kallweit rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000); 35166d7a631eSHeiner Kallweit 351725e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 351825e992a4SHeiner Kallweit } 351925e992a4SHeiner Kallweit 352025e992a4SHeiner Kallweit static void rtl_hw_start_8106(struct rtl8169_private *tp) 352125e992a4SHeiner Kallweit { 352225e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 352325e992a4SHeiner Kallweit 352425e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */ 352525e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800); 352625e992a4SHeiner Kallweit 352725e992a4SHeiner Kallweit RTL_W32(tp, MISC, (RTL_R32(tp, MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN); 352825e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET); 352925e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); 353025e992a4SHeiner Kallweit 35318d46f620SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000); 35328d46f620SHeiner Kallweit 35336d7a631eSHeiner Kallweit /* disable EEE */ 35346d7a631eSHeiner Kallweit rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000); 35356d7a631eSHeiner Kallweit 353625e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 353725e992a4SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true); 353825e992a4SHeiner Kallweit } 353925e992a4SHeiner Kallweit 3540f1bce4adSHeiner Kallweit DECLARE_RTL_COND(rtl_mac_ocp_e00e_cond) 3541f1bce4adSHeiner Kallweit { 3542f1bce4adSHeiner Kallweit return r8168_mac_ocp_read(tp, 0xe00e) & BIT(13); 3543f1bce4adSHeiner Kallweit } 3544f1bce4adSHeiner Kallweit 3545f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_common(struct rtl8169_private *tp) 3546f1bce4adSHeiner Kallweit { 3547f1bce4adSHeiner Kallweit rtl_pcie_state_l2l3_disable(tp); 3548f1bce4adSHeiner Kallweit 3549f1bce4adSHeiner Kallweit RTL_W16(tp, 0x382, 0x221b); 3550f1bce4adSHeiner Kallweit RTL_W8(tp, 0x4500, 0); 3551f1bce4adSHeiner Kallweit RTL_W16(tp, 0x4800, 0); 3552f1bce4adSHeiner Kallweit 3553f1bce4adSHeiner Kallweit /* disable UPS */ 3554f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd40a, 0x0010, 0x0000); 3555f1bce4adSHeiner Kallweit 3556f1bce4adSHeiner Kallweit RTL_W8(tp, Config1, RTL_R8(tp, Config1) & ~0x10); 3557f1bce4adSHeiner Kallweit 3558f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc140, 0xffff); 3559f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc142, 0xffff); 3560f1bce4adSHeiner Kallweit 3561f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e2, 0x0fff, 0x03a9); 3562f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e4, 0x00ff, 0x0000); 3563f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe860, 0x0000, 0x0080); 3564f1bce4adSHeiner Kallweit 3565f1bce4adSHeiner Kallweit /* disable new tx descriptor format */ 3566f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000); 3567f1bce4adSHeiner Kallweit 3568f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400); 3569f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0020); 3570f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b4, 0x0000, 0x000c); 3571f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb6a, 0x00ff, 0x0033); 3572f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb50, 0x03e0, 0x0040); 3573f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); 3574f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); 3575f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403); 3576f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0067); 3577f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0ac, 0x0080, 0x1f00); 3578f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f); 3579f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe84c, 0x0000, 0x00c0); 3580f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000); 3581f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb54, 0x0000, 0x0001); 3582f1bce4adSHeiner Kallweit udelay(1); 3583f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb54, 0x0001, 0x0000); 3584f1bce4adSHeiner Kallweit RTL_W16(tp, 0x1880, RTL_R16(tp, 0x1880) & ~0x0030); 3585f1bce4adSHeiner Kallweit 3586f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe098, 0xc302); 3587f1bce4adSHeiner Kallweit 3588d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10); 3589f1bce4adSHeiner Kallweit 3590b3a42e3aSHeiner Kallweit rtl8125_config_eee_mac(tp); 3591b3a42e3aSHeiner Kallweit 3592f1bce4adSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); 3593f1bce4adSHeiner Kallweit udelay(10); 3594f1bce4adSHeiner Kallweit } 3595f1bce4adSHeiner Kallweit 3596f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_1(struct rtl8169_private *tp) 3597f1bce4adSHeiner Kallweit { 3598f1bce4adSHeiner Kallweit static const struct ephy_info e_info_8125_1[] = { 3599f1bce4adSHeiner Kallweit { 0x01, 0xffff, 0xa812 }, 3600f1bce4adSHeiner Kallweit { 0x09, 0xffff, 0x520c }, 3601f1bce4adSHeiner Kallweit { 0x04, 0xffff, 0xd000 }, 3602f1bce4adSHeiner Kallweit { 0x0d, 0xffff, 0xf702 }, 3603f1bce4adSHeiner Kallweit { 0x0a, 0xffff, 0x8653 }, 3604f1bce4adSHeiner Kallweit { 0x06, 0xffff, 0x001e }, 3605f1bce4adSHeiner Kallweit { 0x08, 0xffff, 0x3595 }, 3606f1bce4adSHeiner Kallweit { 0x20, 0xffff, 0x9455 }, 3607f1bce4adSHeiner Kallweit { 0x21, 0xffff, 0x99ff }, 3608f1bce4adSHeiner Kallweit { 0x02, 0xffff, 0x6046 }, 3609f1bce4adSHeiner Kallweit { 0x29, 0xffff, 0xfe00 }, 3610f1bce4adSHeiner Kallweit { 0x23, 0xffff, 0xab62 }, 3611f1bce4adSHeiner Kallweit 3612f1bce4adSHeiner Kallweit { 0x41, 0xffff, 0xa80c }, 3613f1bce4adSHeiner Kallweit { 0x49, 0xffff, 0x520c }, 3614f1bce4adSHeiner Kallweit { 0x44, 0xffff, 0xd000 }, 3615f1bce4adSHeiner Kallweit { 0x4d, 0xffff, 0xf702 }, 3616f1bce4adSHeiner Kallweit { 0x4a, 0xffff, 0x8653 }, 3617f1bce4adSHeiner Kallweit { 0x46, 0xffff, 0x001e }, 3618f1bce4adSHeiner Kallweit { 0x48, 0xffff, 0x3595 }, 3619f1bce4adSHeiner Kallweit { 0x60, 0xffff, 0x9455 }, 3620f1bce4adSHeiner Kallweit { 0x61, 0xffff, 0x99ff }, 3621f1bce4adSHeiner Kallweit { 0x42, 0xffff, 0x6046 }, 3622f1bce4adSHeiner Kallweit { 0x69, 0xffff, 0xfe00 }, 3623f1bce4adSHeiner Kallweit { 0x63, 0xffff, 0xab62 }, 3624f1bce4adSHeiner Kallweit }; 3625f1bce4adSHeiner Kallweit 3626f1bce4adSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 3627f1bce4adSHeiner Kallweit 3628f1bce4adSHeiner Kallweit /* disable aspm and clock request before access ephy */ 3629f1bce4adSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 3630f1bce4adSHeiner Kallweit rtl_ephy_init(tp, e_info_8125_1); 3631f1bce4adSHeiner Kallweit 3632f1bce4adSHeiner Kallweit rtl_hw_start_8125_common(tp); 3633f1bce4adSHeiner Kallweit } 3634f1bce4adSHeiner Kallweit 3635f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_2(struct rtl8169_private *tp) 3636f1bce4adSHeiner Kallweit { 3637f1bce4adSHeiner Kallweit static const struct ephy_info e_info_8125_2[] = { 3638f1bce4adSHeiner Kallweit { 0x04, 0xffff, 0xd000 }, 3639f1bce4adSHeiner Kallweit { 0x0a, 0xffff, 0x8653 }, 3640f1bce4adSHeiner Kallweit { 0x23, 0xffff, 0xab66 }, 3641f1bce4adSHeiner Kallweit { 0x20, 0xffff, 0x9455 }, 3642f1bce4adSHeiner Kallweit { 0x21, 0xffff, 0x99ff }, 3643f1bce4adSHeiner Kallweit { 0x29, 0xffff, 0xfe04 }, 3644f1bce4adSHeiner Kallweit 3645f1bce4adSHeiner Kallweit { 0x44, 0xffff, 0xd000 }, 3646f1bce4adSHeiner Kallweit { 0x4a, 0xffff, 0x8653 }, 3647f1bce4adSHeiner Kallweit { 0x63, 0xffff, 0xab66 }, 3648f1bce4adSHeiner Kallweit { 0x60, 0xffff, 0x9455 }, 3649f1bce4adSHeiner Kallweit { 0x61, 0xffff, 0x99ff }, 3650f1bce4adSHeiner Kallweit { 0x69, 0xffff, 0xfe04 }, 3651f1bce4adSHeiner Kallweit }; 3652f1bce4adSHeiner Kallweit 3653f1bce4adSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp); 3654f1bce4adSHeiner Kallweit 3655f1bce4adSHeiner Kallweit /* disable aspm and clock request before access ephy */ 3656f1bce4adSHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false); 3657f1bce4adSHeiner Kallweit rtl_ephy_init(tp, e_info_8125_2); 3658f1bce4adSHeiner Kallweit 3659f1bce4adSHeiner Kallweit rtl_hw_start_8125_common(tp); 3660f1bce4adSHeiner Kallweit } 3661f1bce4adSHeiner Kallweit 366225e992a4SHeiner Kallweit static void rtl_hw_config(struct rtl8169_private *tp) 366325e992a4SHeiner Kallweit { 366425e992a4SHeiner Kallweit static const rtl_generic_fct hw_configs[] = { 366525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_07] = rtl_hw_start_8102e_1, 366625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_08] = rtl_hw_start_8102e_3, 366725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_09] = rtl_hw_start_8102e_2, 366825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_10] = NULL, 366994b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b, 367094b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_12] = rtl_hw_start_8168b, 367125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_13] = NULL, 367225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_14] = NULL, 367325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_15] = NULL, 367425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_16] = NULL, 367594b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b, 367625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1, 367725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_19] = rtl_hw_start_8168c_1, 367825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_20] = rtl_hw_start_8168c_2, 367925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_21] = rtl_hw_start_8168c_3, 368025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_22] = rtl_hw_start_8168c_4, 368125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_23] = rtl_hw_start_8168cp_2, 368225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_24] = rtl_hw_start_8168cp_3, 368325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_25] = rtl_hw_start_8168d, 368425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_26] = rtl_hw_start_8168d, 368525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_27] = rtl_hw_start_8168d, 368625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_28] = rtl_hw_start_8168d_4, 368725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_29] = rtl_hw_start_8105e_1, 368825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_30] = rtl_hw_start_8105e_2, 36890a413e6bSHeiner Kallweit [RTL_GIGA_MAC_VER_31] = rtl_hw_start_8168d, 369025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_32] = rtl_hw_start_8168e_1, 369125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_33] = rtl_hw_start_8168e_1, 369225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_34] = rtl_hw_start_8168e_2, 369325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_35] = rtl_hw_start_8168f_1, 369425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_36] = rtl_hw_start_8168f_1, 369525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_37] = rtl_hw_start_8402, 369625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_38] = rtl_hw_start_8411, 369725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_39] = rtl_hw_start_8106, 369825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_40] = rtl_hw_start_8168g_1, 369925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_41] = rtl_hw_start_8168g_1, 370025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_42] = rtl_hw_start_8168g_2, 370125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_43] = rtl_hw_start_8168g_2, 370225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_44] = rtl_hw_start_8411_2, 370325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_45] = rtl_hw_start_8168h_1, 370425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_46] = rtl_hw_start_8168h_1, 370525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_47] = rtl_hw_start_8168h_1, 370625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_48] = rtl_hw_start_8168h_1, 370725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_49] = rtl_hw_start_8168ep_1, 370825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_50] = rtl_hw_start_8168ep_2, 370925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3, 37101287723aSHeiner Kallweit [RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117, 3711f1bce4adSHeiner Kallweit [RTL_GIGA_MAC_VER_60] = rtl_hw_start_8125_1, 3712f1bce4adSHeiner Kallweit [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125_2, 371325e992a4SHeiner Kallweit }; 371425e992a4SHeiner Kallweit 371525e992a4SHeiner Kallweit if (hw_configs[tp->mac_version]) 371625e992a4SHeiner Kallweit hw_configs[tp->mac_version](tp); 371725e992a4SHeiner Kallweit } 371825e992a4SHeiner Kallweit 3719f1bce4adSHeiner Kallweit static void rtl_hw_start_8125(struct rtl8169_private *tp) 3720f1bce4adSHeiner Kallweit { 3721f1bce4adSHeiner Kallweit int i; 3722f1bce4adSHeiner Kallweit 3723f1bce4adSHeiner Kallweit /* disable interrupt coalescing */ 3724f1bce4adSHeiner Kallweit for (i = 0xa00; i < 0xb00; i += 4) 3725f1bce4adSHeiner Kallweit RTL_W32(tp, i, 0); 3726f1bce4adSHeiner Kallweit 3727f1bce4adSHeiner Kallweit rtl_hw_config(tp); 3728f1bce4adSHeiner Kallweit } 3729f1bce4adSHeiner Kallweit 373025e992a4SHeiner Kallweit static void rtl_hw_start_8168(struct rtl8169_private *tp) 373125e992a4SHeiner Kallweit { 3732272b2265SHeiner Kallweit if (rtl_is_8168evl_up(tp)) 3733272b2265SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, EarlySize); 3734272b2265SHeiner Kallweit else 373525e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, TxPacketMax); 373625e992a4SHeiner Kallweit 373725e992a4SHeiner Kallweit rtl_hw_config(tp); 3738bcf2b868SHeiner Kallweit 3739bcf2b868SHeiner Kallweit /* disable interrupt coalescing */ 3740bcf2b868SHeiner Kallweit RTL_W16(tp, IntrMitigate, 0x0000); 374125e992a4SHeiner Kallweit } 374225e992a4SHeiner Kallweit 37436c19156eSHeiner Kallweit static void rtl_hw_start_8169(struct rtl8169_private *tp) 37446c19156eSHeiner Kallweit { 37456c19156eSHeiner Kallweit RTL_W8(tp, EarlyTxThres, NoEarlyTx); 37466c19156eSHeiner Kallweit 37476c19156eSHeiner Kallweit tp->cp_cmd |= PCIMulRW; 37486c19156eSHeiner Kallweit 37496c19156eSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_02 || 375009e65335SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_03) 375109e65335SHeiner Kallweit tp->cp_cmd |= EnAnaPLL; 37526c19156eSHeiner Kallweit 37536c19156eSHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 37546c19156eSHeiner Kallweit 3755ef891284SHeiner Kallweit rtl8169_set_magic_reg(tp); 37566c19156eSHeiner Kallweit 3757bcf2b868SHeiner Kallweit /* disable interrupt coalescing */ 3758bcf2b868SHeiner Kallweit RTL_W16(tp, IntrMitigate, 0x0000); 37596c19156eSHeiner Kallweit } 37606c19156eSHeiner Kallweit 37616c19156eSHeiner Kallweit static void rtl_hw_start(struct rtl8169_private *tp) 37626c19156eSHeiner Kallweit { 37636c19156eSHeiner Kallweit rtl_unlock_config_regs(tp); 37646c19156eSHeiner Kallweit 37656c19156eSHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd); 37666c19156eSHeiner Kallweit 37676c19156eSHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 37686c19156eSHeiner Kallweit rtl_hw_start_8169(tp); 3769f1bce4adSHeiner Kallweit else if (rtl_is_8125(tp)) 3770f1bce4adSHeiner Kallweit rtl_hw_start_8125(tp); 37716c19156eSHeiner Kallweit else 37726c19156eSHeiner Kallweit rtl_hw_start_8168(tp); 37736c19156eSHeiner Kallweit 37746c19156eSHeiner Kallweit rtl_set_rx_max_size(tp); 37756c19156eSHeiner Kallweit rtl_set_rx_tx_desc_registers(tp); 37766c19156eSHeiner Kallweit rtl_lock_config_regs(tp); 37776c19156eSHeiner Kallweit 37789db0ac57SHeiner Kallweit rtl_jumbo_config(tp); 37794ebcb113SHeiner Kallweit 37806c19156eSHeiner Kallweit /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ 3781711463f8SHeiner Kallweit rtl_pci_commit(tp); 3782711463f8SHeiner Kallweit 37836c19156eSHeiner Kallweit RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); 37846c19156eSHeiner Kallweit rtl_init_rxcfg(tp); 37856c19156eSHeiner Kallweit rtl_set_tx_config_registers(tp); 378610478283SHeiner Kallweit rtl_set_rx_config_features(tp, tp->dev->features); 37876c19156eSHeiner Kallweit rtl_set_rx_mode(tp->dev); 37886c19156eSHeiner Kallweit rtl_irq_enable(tp); 37896c19156eSHeiner Kallweit } 37906c19156eSHeiner Kallweit 379125e992a4SHeiner Kallweit static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) 379225e992a4SHeiner Kallweit { 379325e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 379425e992a4SHeiner Kallweit 379525e992a4SHeiner Kallweit dev->mtu = new_mtu; 379625e992a4SHeiner Kallweit netdev_update_features(dev); 37979db0ac57SHeiner Kallweit rtl_jumbo_config(tp); 379825e992a4SHeiner Kallweit 379925e992a4SHeiner Kallweit return 0; 380025e992a4SHeiner Kallweit } 380125e992a4SHeiner Kallweit 380225e992a4SHeiner Kallweit static inline void rtl8169_mark_to_asic(struct RxDesc *desc) 380325e992a4SHeiner Kallweit { 380425e992a4SHeiner Kallweit u32 eor = le32_to_cpu(desc->opts1) & RingEnd; 380525e992a4SHeiner Kallweit 3806047521d7SHeiner Kallweit desc->opts2 = 0; 380725e992a4SHeiner Kallweit /* Force memory writes to complete before releasing descriptor */ 380825e992a4SHeiner Kallweit dma_wmb(); 380925e992a4SHeiner Kallweit 381025e992a4SHeiner Kallweit desc->opts1 = cpu_to_le32(DescOwn | eor | R8169_RX_BUF_SIZE); 381125e992a4SHeiner Kallweit } 381225e992a4SHeiner Kallweit 381332879f00SHeiner Kallweit static struct page *rtl8169_alloc_rx_data(struct rtl8169_private *tp, 381425e992a4SHeiner Kallweit struct RxDesc *desc) 381525e992a4SHeiner Kallweit { 381625e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 381725e992a4SHeiner Kallweit int node = dev_to_node(d); 381832879f00SHeiner Kallweit dma_addr_t mapping; 381932879f00SHeiner Kallweit struct page *data; 382025e992a4SHeiner Kallweit 382132879f00SHeiner Kallweit data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); 382225e992a4SHeiner Kallweit if (!data) 382325e992a4SHeiner Kallweit return NULL; 382425e992a4SHeiner Kallweit 382532879f00SHeiner Kallweit mapping = dma_map_page(d, data, 0, R8169_RX_BUF_SIZE, DMA_FROM_DEVICE); 382625e992a4SHeiner Kallweit if (unlikely(dma_mapping_error(d, mapping))) { 382793882c6fSHeiner Kallweit netdev_err(tp->dev, "Failed to map RX DMA!\n"); 382832879f00SHeiner Kallweit __free_pages(data, get_order(R8169_RX_BUF_SIZE)); 382932879f00SHeiner Kallweit return NULL; 383025e992a4SHeiner Kallweit } 383125e992a4SHeiner Kallweit 383225e992a4SHeiner Kallweit desc->addr = cpu_to_le64(mapping); 383325e992a4SHeiner Kallweit rtl8169_mark_to_asic(desc); 383425e992a4SHeiner Kallweit 383532879f00SHeiner Kallweit return data; 383625e992a4SHeiner Kallweit } 383725e992a4SHeiner Kallweit 383825e992a4SHeiner Kallweit static void rtl8169_rx_clear(struct rtl8169_private *tp) 383925e992a4SHeiner Kallweit { 384025e992a4SHeiner Kallweit unsigned int i; 384125e992a4SHeiner Kallweit 3842eb2e7f09SHeiner Kallweit for (i = 0; i < NUM_RX_DESC && tp->Rx_databuff[i]; i++) { 3843eb2e7f09SHeiner Kallweit dma_unmap_page(tp_to_dev(tp), 3844eb2e7f09SHeiner Kallweit le64_to_cpu(tp->RxDescArray[i].addr), 3845eb2e7f09SHeiner Kallweit R8169_RX_BUF_SIZE, DMA_FROM_DEVICE); 3846eb2e7f09SHeiner Kallweit __free_pages(tp->Rx_databuff[i], get_order(R8169_RX_BUF_SIZE)); 3847eb2e7f09SHeiner Kallweit tp->Rx_databuff[i] = NULL; 38489d3679feSHeiner Kallweit tp->RxDescArray[i].addr = 0; 38499d3679feSHeiner Kallweit tp->RxDescArray[i].opts1 = 0; 385025e992a4SHeiner Kallweit } 385125e992a4SHeiner Kallweit } 385225e992a4SHeiner Kallweit 385325e992a4SHeiner Kallweit static int rtl8169_rx_fill(struct rtl8169_private *tp) 385425e992a4SHeiner Kallweit { 385525e992a4SHeiner Kallweit unsigned int i; 385625e992a4SHeiner Kallweit 385725e992a4SHeiner Kallweit for (i = 0; i < NUM_RX_DESC; i++) { 385832879f00SHeiner Kallweit struct page *data; 385925e992a4SHeiner Kallweit 386025e992a4SHeiner Kallweit data = rtl8169_alloc_rx_data(tp, tp->RxDescArray + i); 386125e992a4SHeiner Kallweit if (!data) { 3862e4b5c7a5SHeiner Kallweit rtl8169_rx_clear(tp); 3863e4b5c7a5SHeiner Kallweit return -ENOMEM; 386425e992a4SHeiner Kallweit } 386525e992a4SHeiner Kallweit tp->Rx_databuff[i] = data; 386625e992a4SHeiner Kallweit } 386725e992a4SHeiner Kallweit 38682ac1fa43SHeiner Kallweit /* mark as last descriptor in the ring */ 38692ac1fa43SHeiner Kallweit tp->RxDescArray[NUM_RX_DESC - 1].opts1 |= cpu_to_le32(RingEnd); 387025e992a4SHeiner Kallweit 3871e4b5c7a5SHeiner Kallweit return 0; 387225e992a4SHeiner Kallweit } 387325e992a4SHeiner Kallweit 387425e992a4SHeiner Kallweit static int rtl8169_init_ring(struct rtl8169_private *tp) 387525e992a4SHeiner Kallweit { 387625e992a4SHeiner Kallweit rtl8169_init_ring_indexes(tp); 387725e992a4SHeiner Kallweit 387825e992a4SHeiner Kallweit memset(tp->tx_skb, 0, sizeof(tp->tx_skb)); 387925e992a4SHeiner Kallweit memset(tp->Rx_databuff, 0, sizeof(tp->Rx_databuff)); 388025e992a4SHeiner Kallweit 388125e992a4SHeiner Kallweit return rtl8169_rx_fill(tp); 388225e992a4SHeiner Kallweit } 388325e992a4SHeiner Kallweit 388422d352c5SHeiner Kallweit static void rtl8169_unmap_tx_skb(struct rtl8169_private *tp, unsigned int entry) 388525e992a4SHeiner Kallweit { 388622d352c5SHeiner Kallweit struct ring_info *tx_skb = tp->tx_skb + entry; 388722d352c5SHeiner Kallweit struct TxDesc *desc = tp->TxDescArray + entry; 388825e992a4SHeiner Kallweit 388922d352c5SHeiner Kallweit dma_unmap_single(tp_to_dev(tp), le64_to_cpu(desc->addr), tx_skb->len, 389022d352c5SHeiner Kallweit DMA_TO_DEVICE); 38916a41f2b2SHeiner Kallweit memset(desc, 0, sizeof(*desc)); 38926a41f2b2SHeiner Kallweit memset(tx_skb, 0, sizeof(*tx_skb)); 389325e992a4SHeiner Kallweit } 389425e992a4SHeiner Kallweit 389525e992a4SHeiner Kallweit static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, 389625e992a4SHeiner Kallweit unsigned int n) 389725e992a4SHeiner Kallweit { 389825e992a4SHeiner Kallweit unsigned int i; 389925e992a4SHeiner Kallweit 390025e992a4SHeiner Kallweit for (i = 0; i < n; i++) { 390125e992a4SHeiner Kallweit unsigned int entry = (start + i) % NUM_TX_DESC; 390225e992a4SHeiner Kallweit struct ring_info *tx_skb = tp->tx_skb + entry; 390325e992a4SHeiner Kallweit unsigned int len = tx_skb->len; 390425e992a4SHeiner Kallweit 390525e992a4SHeiner Kallweit if (len) { 390625e992a4SHeiner Kallweit struct sk_buff *skb = tx_skb->skb; 390725e992a4SHeiner Kallweit 390822d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 39096a41f2b2SHeiner Kallweit if (skb) 391025e992a4SHeiner Kallweit dev_consume_skb_any(skb); 391125e992a4SHeiner Kallweit } 391225e992a4SHeiner Kallweit } 391325e992a4SHeiner Kallweit } 391425e992a4SHeiner Kallweit 391525e992a4SHeiner Kallweit static void rtl8169_tx_clear(struct rtl8169_private *tp) 391625e992a4SHeiner Kallweit { 391725e992a4SHeiner Kallweit rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); 391825e992a4SHeiner Kallweit tp->cur_tx = tp->dirty_tx = 0; 391925e992a4SHeiner Kallweit netdev_reset_queue(tp->dev); 392025e992a4SHeiner Kallweit } 392125e992a4SHeiner Kallweit 392225e992a4SHeiner Kallweit static void rtl_reset_work(struct rtl8169_private *tp) 392325e992a4SHeiner Kallweit { 392425e992a4SHeiner Kallweit struct net_device *dev = tp->dev; 392525e992a4SHeiner Kallweit int i; 392625e992a4SHeiner Kallweit 392725e992a4SHeiner Kallweit napi_disable(&tp->napi); 392825e992a4SHeiner Kallweit netif_stop_queue(dev); 392925e992a4SHeiner Kallweit synchronize_rcu(); 393025e992a4SHeiner Kallweit 393125e992a4SHeiner Kallweit rtl8169_hw_reset(tp); 393225e992a4SHeiner Kallweit 393325e992a4SHeiner Kallweit for (i = 0; i < NUM_RX_DESC; i++) 393425e992a4SHeiner Kallweit rtl8169_mark_to_asic(tp->RxDescArray + i); 393525e992a4SHeiner Kallweit 393625e992a4SHeiner Kallweit rtl8169_tx_clear(tp); 393725e992a4SHeiner Kallweit rtl8169_init_ring_indexes(tp); 393825e992a4SHeiner Kallweit 393925e992a4SHeiner Kallweit napi_enable(&tp->napi); 394025e992a4SHeiner Kallweit rtl_hw_start(tp); 394125e992a4SHeiner Kallweit netif_wake_queue(dev); 394225e992a4SHeiner Kallweit } 394325e992a4SHeiner Kallweit 39440290bd29SMichael S. Tsirkin static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue) 394525e992a4SHeiner Kallweit { 394625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 394725e992a4SHeiner Kallweit 394825e992a4SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 394925e992a4SHeiner Kallweit } 395025e992a4SHeiner Kallweit 3951b8447abcSHeiner Kallweit static int rtl8169_tx_map(struct rtl8169_private *tp, const u32 *opts, u32 len, 3952b8447abcSHeiner Kallweit void *addr, unsigned int entry, bool desc_own) 395325e992a4SHeiner Kallweit { 3954b8447abcSHeiner Kallweit struct TxDesc *txd = tp->TxDescArray + entry; 3955b8447abcSHeiner Kallweit struct device *d = tp_to_dev(tp); 3956b8447abcSHeiner Kallweit dma_addr_t mapping; 3957b8447abcSHeiner Kallweit u32 opts1; 3958b8447abcSHeiner Kallweit int ret; 395925e992a4SHeiner Kallweit 3960b8447abcSHeiner Kallweit mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE); 3961b8447abcSHeiner Kallweit ret = dma_mapping_error(d, mapping); 3962b8447abcSHeiner Kallweit if (unlikely(ret)) { 3963b8447abcSHeiner Kallweit if (net_ratelimit()) 396493882c6fSHeiner Kallweit netdev_err(tp->dev, "Failed to map TX data!\n"); 3965b8447abcSHeiner Kallweit return ret; 3966b8447abcSHeiner Kallweit } 3967b8447abcSHeiner Kallweit 3968b8447abcSHeiner Kallweit txd->addr = cpu_to_le64(mapping); 3969b8447abcSHeiner Kallweit txd->opts2 = cpu_to_le32(opts[1]); 3970b8447abcSHeiner Kallweit 3971b8447abcSHeiner Kallweit opts1 = opts[0] | len; 397225e992a4SHeiner Kallweit if (entry == NUM_TX_DESC - 1) 3973b8447abcSHeiner Kallweit opts1 |= RingEnd; 3974b8447abcSHeiner Kallweit if (desc_own) 3975b8447abcSHeiner Kallweit opts1 |= DescOwn; 3976b8447abcSHeiner Kallweit txd->opts1 = cpu_to_le32(opts1); 397725e992a4SHeiner Kallweit 3978b8447abcSHeiner Kallweit tp->tx_skb[entry].len = len; 3979b8447abcSHeiner Kallweit 3980b8447abcSHeiner Kallweit return 0; 398125e992a4SHeiner Kallweit } 398225e992a4SHeiner Kallweit 398325e992a4SHeiner Kallweit static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, 3984b8447abcSHeiner Kallweit const u32 *opts, unsigned int entry) 398525e992a4SHeiner Kallweit { 398625e992a4SHeiner Kallweit struct skb_shared_info *info = skb_shinfo(skb); 3987b8447abcSHeiner Kallweit unsigned int cur_frag; 398825e992a4SHeiner Kallweit 398925e992a4SHeiner Kallweit for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { 399025e992a4SHeiner Kallweit const skb_frag_t *frag = info->frags + cur_frag; 3991b8447abcSHeiner Kallweit void *addr = skb_frag_address(frag); 3992b8447abcSHeiner Kallweit u32 len = skb_frag_size(frag); 399325e992a4SHeiner Kallweit 399425e992a4SHeiner Kallweit entry = (entry + 1) % NUM_TX_DESC; 399525e992a4SHeiner Kallweit 3996b8447abcSHeiner Kallweit if (unlikely(rtl8169_tx_map(tp, opts, len, addr, entry, true))) 399725e992a4SHeiner Kallweit goto err_out; 399825e992a4SHeiner Kallweit } 399925e992a4SHeiner Kallweit 40009020845fSHeiner Kallweit return 0; 400125e992a4SHeiner Kallweit 400225e992a4SHeiner Kallweit err_out: 400325e992a4SHeiner Kallweit rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag); 400425e992a4SHeiner Kallweit return -EIO; 400525e992a4SHeiner Kallweit } 400625e992a4SHeiner Kallweit 400725e992a4SHeiner Kallweit static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) 400825e992a4SHeiner Kallweit { 400925e992a4SHeiner Kallweit return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; 401025e992a4SHeiner Kallweit } 401125e992a4SHeiner Kallweit 401225e992a4SHeiner Kallweit static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts) 401325e992a4SHeiner Kallweit { 401425e992a4SHeiner Kallweit u32 mss = skb_shinfo(skb)->gso_size; 401525e992a4SHeiner Kallweit 401625e992a4SHeiner Kallweit if (mss) { 401725e992a4SHeiner Kallweit opts[0] |= TD_LSO; 40184abc3c04SHeiner Kallweit opts[0] |= mss << TD0_MSS_SHIFT; 401925e992a4SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 402025e992a4SHeiner Kallweit const struct iphdr *ip = ip_hdr(skb); 402125e992a4SHeiner Kallweit 402225e992a4SHeiner Kallweit if (ip->protocol == IPPROTO_TCP) 402325e992a4SHeiner Kallweit opts[0] |= TD0_IP_CS | TD0_TCP_CS; 402425e992a4SHeiner Kallweit else if (ip->protocol == IPPROTO_UDP) 402525e992a4SHeiner Kallweit opts[0] |= TD0_IP_CS | TD0_UDP_CS; 402625e992a4SHeiner Kallweit else 402725e992a4SHeiner Kallweit WARN_ON_ONCE(1); 402825e992a4SHeiner Kallweit } 402925e992a4SHeiner Kallweit } 403025e992a4SHeiner Kallweit 403125e992a4SHeiner Kallweit static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, 403225e992a4SHeiner Kallweit struct sk_buff *skb, u32 *opts) 403325e992a4SHeiner Kallweit { 403425e992a4SHeiner Kallweit u32 transport_offset = (u32)skb_transport_offset(skb); 40350623b98bSHeiner Kallweit struct skb_shared_info *shinfo = skb_shinfo(skb); 40360623b98bSHeiner Kallweit u32 mss = shinfo->gso_size; 403725e992a4SHeiner Kallweit 403825e992a4SHeiner Kallweit if (mss) { 40390623b98bSHeiner Kallweit if (shinfo->gso_type & SKB_GSO_TCPV4) { 404025e992a4SHeiner Kallweit opts[0] |= TD1_GTSENV4; 40410623b98bSHeiner Kallweit } else if (shinfo->gso_type & SKB_GSO_TCPV6) { 40428b19c68cSHeiner Kallweit if (skb_cow_head(skb, 0)) 404325e992a4SHeiner Kallweit return false; 404425e992a4SHeiner Kallweit 40458b19c68cSHeiner Kallweit tcp_v6_gso_csum_prep(skb); 404625e992a4SHeiner Kallweit opts[0] |= TD1_GTSENV6; 40470623b98bSHeiner Kallweit } else { 404825e992a4SHeiner Kallweit WARN_ON_ONCE(1); 404925e992a4SHeiner Kallweit } 405025e992a4SHeiner Kallweit 405125e992a4SHeiner Kallweit opts[0] |= transport_offset << GTTCPHO_SHIFT; 40524abc3c04SHeiner Kallweit opts[1] |= mss << TD1_MSS_SHIFT; 405325e992a4SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 405425e992a4SHeiner Kallweit u8 ip_protocol; 405525e992a4SHeiner Kallweit 405625e992a4SHeiner Kallweit switch (vlan_get_protocol(skb)) { 405725e992a4SHeiner Kallweit case htons(ETH_P_IP): 405825e992a4SHeiner Kallweit opts[1] |= TD1_IPv4_CS; 405925e992a4SHeiner Kallweit ip_protocol = ip_hdr(skb)->protocol; 406025e992a4SHeiner Kallweit break; 406125e992a4SHeiner Kallweit 406225e992a4SHeiner Kallweit case htons(ETH_P_IPV6): 406325e992a4SHeiner Kallweit opts[1] |= TD1_IPv6_CS; 406425e992a4SHeiner Kallweit ip_protocol = ipv6_hdr(skb)->nexthdr; 406525e992a4SHeiner Kallweit break; 406625e992a4SHeiner Kallweit 406725e992a4SHeiner Kallweit default: 406825e992a4SHeiner Kallweit ip_protocol = IPPROTO_RAW; 406925e992a4SHeiner Kallweit break; 407025e992a4SHeiner Kallweit } 407125e992a4SHeiner Kallweit 407225e992a4SHeiner Kallweit if (ip_protocol == IPPROTO_TCP) 407325e992a4SHeiner Kallweit opts[1] |= TD1_TCP_CS; 407425e992a4SHeiner Kallweit else if (ip_protocol == IPPROTO_UDP) 407525e992a4SHeiner Kallweit opts[1] |= TD1_UDP_CS; 407625e992a4SHeiner Kallweit else 407725e992a4SHeiner Kallweit WARN_ON_ONCE(1); 407825e992a4SHeiner Kallweit 407925e992a4SHeiner Kallweit opts[1] |= transport_offset << TCPHO_SHIFT; 408025e992a4SHeiner Kallweit } else { 408125e992a4SHeiner Kallweit if (unlikely(rtl_test_hw_pad_bug(tp, skb))) 408225e992a4SHeiner Kallweit return !eth_skb_pad(skb); 408325e992a4SHeiner Kallweit } 408425e992a4SHeiner Kallweit 408525e992a4SHeiner Kallweit return true; 408625e992a4SHeiner Kallweit } 408725e992a4SHeiner Kallweit 408825e992a4SHeiner Kallweit static bool rtl_tx_slots_avail(struct rtl8169_private *tp, 408925e992a4SHeiner Kallweit unsigned int nr_frags) 409025e992a4SHeiner Kallweit { 409125e992a4SHeiner Kallweit unsigned int slots_avail = tp->dirty_tx + NUM_TX_DESC - tp->cur_tx; 409225e992a4SHeiner Kallweit 409325e992a4SHeiner Kallweit /* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ 409425e992a4SHeiner Kallweit return slots_avail > nr_frags; 409525e992a4SHeiner Kallweit } 409625e992a4SHeiner Kallweit 409725e992a4SHeiner Kallweit /* Versions RTL8102e and from RTL8168c onwards support csum_v2 */ 409825e992a4SHeiner Kallweit static bool rtl_chip_supports_csum_v2(struct rtl8169_private *tp) 409925e992a4SHeiner Kallweit { 410025e992a4SHeiner Kallweit switch (tp->mac_version) { 410125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 410225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17: 410325e992a4SHeiner Kallweit return false; 410425e992a4SHeiner Kallweit default: 410525e992a4SHeiner Kallweit return true; 410625e992a4SHeiner Kallweit } 410725e992a4SHeiner Kallweit } 410825e992a4SHeiner Kallweit 4109f1bce4adSHeiner Kallweit static void rtl8169_doorbell(struct rtl8169_private *tp) 4110f1bce4adSHeiner Kallweit { 4111f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) 4112f1bce4adSHeiner Kallweit RTL_W16(tp, TxPoll_8125, BIT(0)); 4113f1bce4adSHeiner Kallweit else 4114f1bce4adSHeiner Kallweit RTL_W8(tp, TxPoll, NPQ); 4115f1bce4adSHeiner Kallweit } 4116f1bce4adSHeiner Kallweit 411725e992a4SHeiner Kallweit static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, 411825e992a4SHeiner Kallweit struct net_device *dev) 411925e992a4SHeiner Kallweit { 41209020845fSHeiner Kallweit unsigned int frags = skb_shinfo(skb)->nr_frags; 412125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 412225e992a4SHeiner Kallweit unsigned int entry = tp->cur_tx % NUM_TX_DESC; 4123b8447abcSHeiner Kallweit struct TxDesc *txd_first, *txd_last; 4124b8447abcSHeiner Kallweit bool stop_queue, door_bell; 4125b8447abcSHeiner Kallweit u32 opts[2]; 4126b8447abcSHeiner Kallweit 4127b8447abcSHeiner Kallweit txd_first = tp->TxDescArray + entry; 412825e992a4SHeiner Kallweit 41299020845fSHeiner Kallweit if (unlikely(!rtl_tx_slots_avail(tp, frags))) { 413093882c6fSHeiner Kallweit if (net_ratelimit()) 413193882c6fSHeiner Kallweit netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); 413225e992a4SHeiner Kallweit goto err_stop_0; 413325e992a4SHeiner Kallweit } 413425e992a4SHeiner Kallweit 4135b8447abcSHeiner Kallweit if (unlikely(le32_to_cpu(txd_first->opts1) & DescOwn)) 413625e992a4SHeiner Kallweit goto err_stop_0; 413725e992a4SHeiner Kallweit 4138355f948aSHeiner Kallweit opts[1] = rtl8169_tx_vlan_tag(skb); 4139b8447abcSHeiner Kallweit opts[0] = 0; 414025e992a4SHeiner Kallweit 4141b8447abcSHeiner Kallweit if (!rtl_chip_supports_csum_v2(tp)) 414225e992a4SHeiner Kallweit rtl8169_tso_csum_v1(skb, opts); 4143b8447abcSHeiner Kallweit else if (!rtl8169_tso_csum_v2(tp, skb, opts)) 414425e992a4SHeiner Kallweit goto err_dma_0; 414525e992a4SHeiner Kallweit 4146b8447abcSHeiner Kallweit if (unlikely(rtl8169_tx_map(tp, opts, skb_headlen(skb), skb->data, 4147b8447abcSHeiner Kallweit entry, false))) 4148b8447abcSHeiner Kallweit goto err_dma_0; 414925e992a4SHeiner Kallweit 4150b8447abcSHeiner Kallweit if (frags) { 4151b8447abcSHeiner Kallweit if (rtl8169_xmit_frags(tp, skb, opts, entry)) 41529020845fSHeiner Kallweit goto err_dma_1; 4153b8447abcSHeiner Kallweit entry = (entry + frags) % NUM_TX_DESC; 415425e992a4SHeiner Kallweit } 415525e992a4SHeiner Kallweit 4156b8447abcSHeiner Kallweit txd_last = tp->TxDescArray + entry; 4157b8447abcSHeiner Kallweit txd_last->opts1 |= cpu_to_le32(LastFrag); 4158b8447abcSHeiner Kallweit tp->tx_skb[entry].skb = skb; 415925e992a4SHeiner Kallweit 416025e992a4SHeiner Kallweit skb_tx_timestamp(skb); 416125e992a4SHeiner Kallweit 416225e992a4SHeiner Kallweit /* Force memory writes to complete before releasing descriptor */ 416325e992a4SHeiner Kallweit dma_wmb(); 416425e992a4SHeiner Kallweit 4165ef143585SHeiner Kallweit door_bell = __netdev_sent_queue(dev, skb->len, netdev_xmit_more()); 4166ef143585SHeiner Kallweit 4167b8447abcSHeiner Kallweit txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag); 416825e992a4SHeiner Kallweit 4169794867eeSHeiner Kallweit /* rtl_tx needs to see descriptor changes before updated tp->cur_tx */ 4170794867eeSHeiner Kallweit smp_wmb(); 417125e992a4SHeiner Kallweit 417225e992a4SHeiner Kallweit tp->cur_tx += frags + 1; 417325e992a4SHeiner Kallweit 4174ef143585SHeiner Kallweit stop_queue = !rtl_tx_slots_avail(tp, MAX_SKB_FRAGS); 4175ef143585SHeiner Kallweit if (unlikely(stop_queue)) { 417625e992a4SHeiner Kallweit /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must 417725e992a4SHeiner Kallweit * not miss a ring update when it notices a stopped queue. 417825e992a4SHeiner Kallweit */ 417925e992a4SHeiner Kallweit smp_wmb(); 418025e992a4SHeiner Kallweit netif_stop_queue(dev); 41814773f9bdSHeiner Kallweit door_bell = true; 4182ef143585SHeiner Kallweit } 4183ef143585SHeiner Kallweit 4184ef143585SHeiner Kallweit if (door_bell) 4185f1bce4adSHeiner Kallweit rtl8169_doorbell(tp); 4186ef143585SHeiner Kallweit 4187ef143585SHeiner Kallweit if (unlikely(stop_queue)) { 418825e992a4SHeiner Kallweit /* Sync with rtl_tx: 418925e992a4SHeiner Kallweit * - publish queue status and cur_tx ring index (write barrier) 419025e992a4SHeiner Kallweit * - refresh dirty_tx ring index (read barrier). 419125e992a4SHeiner Kallweit * May the current thread have a pessimistic view of the ring 419225e992a4SHeiner Kallweit * status and forget to wake up queue, a racing rtl_tx thread 419325e992a4SHeiner Kallweit * can't. 419425e992a4SHeiner Kallweit */ 419525e992a4SHeiner Kallweit smp_mb(); 419625e992a4SHeiner Kallweit if (rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) 419725e992a4SHeiner Kallweit netif_start_queue(dev); 419825e992a4SHeiner Kallweit } 419925e992a4SHeiner Kallweit 420025e992a4SHeiner Kallweit return NETDEV_TX_OK; 420125e992a4SHeiner Kallweit 420225e992a4SHeiner Kallweit err_dma_1: 420322d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 420425e992a4SHeiner Kallweit err_dma_0: 420525e992a4SHeiner Kallweit dev_kfree_skb_any(skb); 420625e992a4SHeiner Kallweit dev->stats.tx_dropped++; 420725e992a4SHeiner Kallweit return NETDEV_TX_OK; 420825e992a4SHeiner Kallweit 420925e992a4SHeiner Kallweit err_stop_0: 421025e992a4SHeiner Kallweit netif_stop_queue(dev); 421125e992a4SHeiner Kallweit dev->stats.tx_dropped++; 421225e992a4SHeiner Kallweit return NETDEV_TX_BUSY; 421325e992a4SHeiner Kallweit } 421425e992a4SHeiner Kallweit 4215773235f4SHeiner Kallweit static unsigned int rtl_last_frag_len(struct sk_buff *skb) 4216773235f4SHeiner Kallweit { 4217773235f4SHeiner Kallweit struct skb_shared_info *info = skb_shinfo(skb); 4218773235f4SHeiner Kallweit unsigned int nr_frags = info->nr_frags; 4219773235f4SHeiner Kallweit 4220773235f4SHeiner Kallweit if (!nr_frags) 4221773235f4SHeiner Kallweit return UINT_MAX; 4222773235f4SHeiner Kallweit 4223773235f4SHeiner Kallweit return skb_frag_size(info->frags + nr_frags - 1); 4224773235f4SHeiner Kallweit } 4225773235f4SHeiner Kallweit 4226773235f4SHeiner Kallweit /* Workaround for hw issues with TSO on RTL8168evl */ 4227773235f4SHeiner Kallweit static netdev_features_t rtl8168evl_fix_tso(struct sk_buff *skb, 4228773235f4SHeiner Kallweit netdev_features_t features) 4229773235f4SHeiner Kallweit { 4230773235f4SHeiner Kallweit /* IPv4 header has options field */ 4231773235f4SHeiner Kallweit if (vlan_get_protocol(skb) == htons(ETH_P_IP) && 4232773235f4SHeiner Kallweit ip_hdrlen(skb) > sizeof(struct iphdr)) 4233773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4234773235f4SHeiner Kallweit 4235773235f4SHeiner Kallweit /* IPv4 TCP header has options field */ 4236773235f4SHeiner Kallweit else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 && 4237773235f4SHeiner Kallweit tcp_hdrlen(skb) > sizeof(struct tcphdr)) 4238773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4239773235f4SHeiner Kallweit 4240773235f4SHeiner Kallweit else if (rtl_last_frag_len(skb) <= 6) 4241773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4242773235f4SHeiner Kallweit 4243773235f4SHeiner Kallweit return features; 4244773235f4SHeiner Kallweit } 4245773235f4SHeiner Kallweit 4246e64e0c89SHeiner Kallweit static netdev_features_t rtl8169_features_check(struct sk_buff *skb, 4247e64e0c89SHeiner Kallweit struct net_device *dev, 4248e64e0c89SHeiner Kallweit netdev_features_t features) 4249e64e0c89SHeiner Kallweit { 4250e64e0c89SHeiner Kallweit int transport_offset = skb_transport_offset(skb); 4251e64e0c89SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 4252e64e0c89SHeiner Kallweit 4253e64e0c89SHeiner Kallweit if (skb_is_gso(skb)) { 4254773235f4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34) 4255773235f4SHeiner Kallweit features = rtl8168evl_fix_tso(skb, features); 4256773235f4SHeiner Kallweit 4257e64e0c89SHeiner Kallweit if (transport_offset > GTTCPHO_MAX && 4258e64e0c89SHeiner Kallweit rtl_chip_supports_csum_v2(tp)) 4259e64e0c89SHeiner Kallweit features &= ~NETIF_F_ALL_TSO; 4260e64e0c89SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 4261e64e0c89SHeiner Kallweit if (skb->len < ETH_ZLEN) { 4262e64e0c89SHeiner Kallweit switch (tp->mac_version) { 4263e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_11: 4264e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 4265e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 4266e64e0c89SHeiner Kallweit case RTL_GIGA_MAC_VER_34: 4267e64e0c89SHeiner Kallweit features &= ~NETIF_F_CSUM_MASK; 4268e64e0c89SHeiner Kallweit break; 4269e64e0c89SHeiner Kallweit default: 4270e64e0c89SHeiner Kallweit break; 4271e64e0c89SHeiner Kallweit } 4272e64e0c89SHeiner Kallweit } 4273e64e0c89SHeiner Kallweit 4274e64e0c89SHeiner Kallweit if (transport_offset > TCPHO_MAX && 4275e64e0c89SHeiner Kallweit rtl_chip_supports_csum_v2(tp)) 4276e64e0c89SHeiner Kallweit features &= ~NETIF_F_CSUM_MASK; 4277e64e0c89SHeiner Kallweit } 4278e64e0c89SHeiner Kallweit 4279e64e0c89SHeiner Kallweit return vlan_features_check(skb, features); 4280e64e0c89SHeiner Kallweit } 4281e64e0c89SHeiner Kallweit 428225e992a4SHeiner Kallweit static void rtl8169_pcierr_interrupt(struct net_device *dev) 428325e992a4SHeiner Kallweit { 428425e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 428525e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 42862864a883SHeiner Kallweit int pci_status_errs; 42872864a883SHeiner Kallweit u16 pci_cmd; 428825e992a4SHeiner Kallweit 428925e992a4SHeiner Kallweit pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); 429025e992a4SHeiner Kallweit 42912864a883SHeiner Kallweit pci_status_errs = pci_status_get_and_clear_errors(pdev); 42922864a883SHeiner Kallweit 429393882c6fSHeiner Kallweit if (net_ratelimit()) 429493882c6fSHeiner Kallweit netdev_err(dev, "PCI error (cmd = 0x%04x, status_errs = 0x%04x)\n", 42952864a883SHeiner Kallweit pci_cmd, pci_status_errs); 429625e992a4SHeiner Kallweit /* 429725e992a4SHeiner Kallweit * The recovery sequence below admits a very elaborated explanation: 429825e992a4SHeiner Kallweit * - it seems to work; 429925e992a4SHeiner Kallweit * - I did not see what else could be done; 430025e992a4SHeiner Kallweit * - it makes iop3xx happy. 430125e992a4SHeiner Kallweit * 430225e992a4SHeiner Kallweit * Feel free to adjust to your needs. 430325e992a4SHeiner Kallweit */ 430425e992a4SHeiner Kallweit if (pdev->broken_parity_status) 430525e992a4SHeiner Kallweit pci_cmd &= ~PCI_COMMAND_PARITY; 430625e992a4SHeiner Kallweit else 430725e992a4SHeiner Kallweit pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY; 430825e992a4SHeiner Kallweit 430925e992a4SHeiner Kallweit pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); 431025e992a4SHeiner Kallweit 431125e992a4SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 431225e992a4SHeiner Kallweit } 431325e992a4SHeiner Kallweit 431425e992a4SHeiner Kallweit static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, 431525e992a4SHeiner Kallweit int budget) 431625e992a4SHeiner Kallweit { 431725e992a4SHeiner Kallweit unsigned int dirty_tx, tx_left, bytes_compl = 0, pkts_compl = 0; 431825e992a4SHeiner Kallweit 431925e992a4SHeiner Kallweit dirty_tx = tp->dirty_tx; 432025e992a4SHeiner Kallweit smp_rmb(); 432125e992a4SHeiner Kallweit 4322a0e6650bSHeiner Kallweit for (tx_left = tp->cur_tx - dirty_tx; tx_left > 0; tx_left--) { 432325e992a4SHeiner Kallweit unsigned int entry = dirty_tx % NUM_TX_DESC; 432422d352c5SHeiner Kallweit struct sk_buff *skb = tp->tx_skb[entry].skb; 432525e992a4SHeiner Kallweit u32 status; 432625e992a4SHeiner Kallweit 432725e992a4SHeiner Kallweit status = le32_to_cpu(tp->TxDescArray[entry].opts1); 432825e992a4SHeiner Kallweit if (status & DescOwn) 432925e992a4SHeiner Kallweit break; 433025e992a4SHeiner Kallweit 433122d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry); 433222d352c5SHeiner Kallweit 43336a41f2b2SHeiner Kallweit if (skb) { 433425e992a4SHeiner Kallweit pkts_compl++; 43356a41f2b2SHeiner Kallweit bytes_compl += skb->len; 43366a41f2b2SHeiner Kallweit napi_consume_skb(skb, budget); 433725e992a4SHeiner Kallweit } 433825e992a4SHeiner Kallweit dirty_tx++; 433925e992a4SHeiner Kallweit } 434025e992a4SHeiner Kallweit 434125e992a4SHeiner Kallweit if (tp->dirty_tx != dirty_tx) { 434225e992a4SHeiner Kallweit netdev_completed_queue(dev, pkts_compl, bytes_compl); 434325e992a4SHeiner Kallweit 434425e992a4SHeiner Kallweit u64_stats_update_begin(&tp->tx_stats.syncp); 434525e992a4SHeiner Kallweit tp->tx_stats.packets += pkts_compl; 434625e992a4SHeiner Kallweit tp->tx_stats.bytes += bytes_compl; 434725e992a4SHeiner Kallweit u64_stats_update_end(&tp->tx_stats.syncp); 434825e992a4SHeiner Kallweit 434925e992a4SHeiner Kallweit tp->dirty_tx = dirty_tx; 435025e992a4SHeiner Kallweit /* Sync with rtl8169_start_xmit: 435125e992a4SHeiner Kallweit * - publish dirty_tx ring index (write barrier) 435225e992a4SHeiner Kallweit * - refresh cur_tx ring index and queue status (read barrier) 435325e992a4SHeiner Kallweit * May the current thread miss the stopped queue condition, 435425e992a4SHeiner Kallweit * a racing xmit thread can only have a right view of the 435525e992a4SHeiner Kallweit * ring status. 435625e992a4SHeiner Kallweit */ 435725e992a4SHeiner Kallweit smp_mb(); 435825e992a4SHeiner Kallweit if (netif_queue_stopped(dev) && 435925e992a4SHeiner Kallweit rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) { 436025e992a4SHeiner Kallweit netif_wake_queue(dev); 436125e992a4SHeiner Kallweit } 436225e992a4SHeiner Kallweit /* 436325e992a4SHeiner Kallweit * 8168 hack: TxPoll requests are lost when the Tx packets are 436425e992a4SHeiner Kallweit * too close. Let's kick an extra TxPoll request when a burst 436525e992a4SHeiner Kallweit * of start_xmit activity is detected (if it is not detected, 436625e992a4SHeiner Kallweit * it is slow enough). -- FR 436725e992a4SHeiner Kallweit */ 436825e992a4SHeiner Kallweit if (tp->cur_tx != dirty_tx) 4369f1bce4adSHeiner Kallweit rtl8169_doorbell(tp); 437025e992a4SHeiner Kallweit } 437125e992a4SHeiner Kallweit } 437225e992a4SHeiner Kallweit 437325e992a4SHeiner Kallweit static inline int rtl8169_fragmented_frame(u32 status) 437425e992a4SHeiner Kallweit { 437525e992a4SHeiner Kallweit return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); 437625e992a4SHeiner Kallweit } 437725e992a4SHeiner Kallweit 437825e992a4SHeiner Kallweit static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) 437925e992a4SHeiner Kallweit { 438025e992a4SHeiner Kallweit u32 status = opts1 & RxProtoMask; 438125e992a4SHeiner Kallweit 438225e992a4SHeiner Kallweit if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || 438325e992a4SHeiner Kallweit ((status == RxProtoUDP) && !(opts1 & UDPFail))) 438425e992a4SHeiner Kallweit skb->ip_summed = CHECKSUM_UNNECESSARY; 438525e992a4SHeiner Kallweit else 438625e992a4SHeiner Kallweit skb_checksum_none_assert(skb); 438725e992a4SHeiner Kallweit } 438825e992a4SHeiner Kallweit 438925e992a4SHeiner Kallweit static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget) 439025e992a4SHeiner Kallweit { 439125e992a4SHeiner Kallweit unsigned int cur_rx, rx_left; 439225e992a4SHeiner Kallweit unsigned int count; 439325e992a4SHeiner Kallweit 439425e992a4SHeiner Kallweit cur_rx = tp->cur_rx; 439525e992a4SHeiner Kallweit 439625e992a4SHeiner Kallweit for (rx_left = min(budget, NUM_RX_DESC); rx_left > 0; rx_left--, cur_rx++) { 439725e992a4SHeiner Kallweit unsigned int entry = cur_rx % NUM_RX_DESC; 439832879f00SHeiner Kallweit const void *rx_buf = page_address(tp->Rx_databuff[entry]); 439925e992a4SHeiner Kallweit struct RxDesc *desc = tp->RxDescArray + entry; 440025e992a4SHeiner Kallweit u32 status; 440125e992a4SHeiner Kallweit 440225e992a4SHeiner Kallweit status = le32_to_cpu(desc->opts1); 440325e992a4SHeiner Kallweit if (status & DescOwn) 440425e992a4SHeiner Kallweit break; 440525e992a4SHeiner Kallweit 440625e992a4SHeiner Kallweit /* This barrier is needed to keep us from reading 440725e992a4SHeiner Kallweit * any other fields out of the Rx descriptor until 440825e992a4SHeiner Kallweit * we know the status of DescOwn 440925e992a4SHeiner Kallweit */ 441025e992a4SHeiner Kallweit dma_rmb(); 441125e992a4SHeiner Kallweit 441225e992a4SHeiner Kallweit if (unlikely(status & RxRES)) { 441393882c6fSHeiner Kallweit if (net_ratelimit()) 441493882c6fSHeiner Kallweit netdev_warn(dev, "Rx ERROR. status = %08x\n", 441525e992a4SHeiner Kallweit status); 441625e992a4SHeiner Kallweit dev->stats.rx_errors++; 441725e992a4SHeiner Kallweit if (status & (RxRWT | RxRUNT)) 441825e992a4SHeiner Kallweit dev->stats.rx_length_errors++; 441925e992a4SHeiner Kallweit if (status & RxCRC) 442025e992a4SHeiner Kallweit dev->stats.rx_crc_errors++; 442125e992a4SHeiner Kallweit if (status & (RxRUNT | RxCRC) && !(status & RxRWT) && 442225e992a4SHeiner Kallweit dev->features & NETIF_F_RXALL) { 442325e992a4SHeiner Kallweit goto process_pkt; 442425e992a4SHeiner Kallweit } 442525e992a4SHeiner Kallweit } else { 4426fcd4e608SHeiner Kallweit unsigned int pkt_size; 442725e992a4SHeiner Kallweit struct sk_buff *skb; 442825e992a4SHeiner Kallweit 442925e992a4SHeiner Kallweit process_pkt: 4430fcd4e608SHeiner Kallweit pkt_size = status & GENMASK(13, 0); 443125e992a4SHeiner Kallweit if (likely(!(dev->features & NETIF_F_RXFCS))) 4432fcd4e608SHeiner Kallweit pkt_size -= ETH_FCS_LEN; 443325e992a4SHeiner Kallweit /* 443425e992a4SHeiner Kallweit * The driver does not support incoming fragmented 443525e992a4SHeiner Kallweit * frames. They are seen as a symptom of over-mtu 443625e992a4SHeiner Kallweit * sized frames. 443725e992a4SHeiner Kallweit */ 443825e992a4SHeiner Kallweit if (unlikely(rtl8169_fragmented_frame(status))) { 443925e992a4SHeiner Kallweit dev->stats.rx_dropped++; 444025e992a4SHeiner Kallweit dev->stats.rx_length_errors++; 444125e992a4SHeiner Kallweit goto release_descriptor; 444225e992a4SHeiner Kallweit } 444325e992a4SHeiner Kallweit 4444fcd4e608SHeiner Kallweit skb = napi_alloc_skb(&tp->napi, pkt_size); 4445fcd4e608SHeiner Kallweit if (unlikely(!skb)) { 444625e992a4SHeiner Kallweit dev->stats.rx_dropped++; 444725e992a4SHeiner Kallweit goto release_descriptor; 444825e992a4SHeiner Kallweit } 444925e992a4SHeiner Kallweit 44503c95e501SHeiner Kallweit dma_sync_single_for_cpu(tp_to_dev(tp), 44513c95e501SHeiner Kallweit le64_to_cpu(desc->addr), 44523c95e501SHeiner Kallweit pkt_size, DMA_FROM_DEVICE); 445332879f00SHeiner Kallweit prefetch(rx_buf); 445432879f00SHeiner Kallweit skb_copy_to_linear_data(skb, rx_buf, pkt_size); 4455fcd4e608SHeiner Kallweit skb->tail += pkt_size; 4456fcd4e608SHeiner Kallweit skb->len = pkt_size; 4457fcd4e608SHeiner Kallweit 4458d4ed7463SHeiner Kallweit dma_sync_single_for_device(tp_to_dev(tp), 4459d4ed7463SHeiner Kallweit le64_to_cpu(desc->addr), 4460d4ed7463SHeiner Kallweit pkt_size, DMA_FROM_DEVICE); 4461d4ed7463SHeiner Kallweit 446225e992a4SHeiner Kallweit rtl8169_rx_csum(skb, status); 446325e992a4SHeiner Kallweit skb->protocol = eth_type_trans(skb, dev); 446425e992a4SHeiner Kallweit 446525e992a4SHeiner Kallweit rtl8169_rx_vlan_tag(desc, skb); 446625e992a4SHeiner Kallweit 446725e992a4SHeiner Kallweit if (skb->pkt_type == PACKET_MULTICAST) 446825e992a4SHeiner Kallweit dev->stats.multicast++; 446925e992a4SHeiner Kallweit 447025e992a4SHeiner Kallweit napi_gro_receive(&tp->napi, skb); 447125e992a4SHeiner Kallweit 447225e992a4SHeiner Kallweit u64_stats_update_begin(&tp->rx_stats.syncp); 447325e992a4SHeiner Kallweit tp->rx_stats.packets++; 447425e992a4SHeiner Kallweit tp->rx_stats.bytes += pkt_size; 447525e992a4SHeiner Kallweit u64_stats_update_end(&tp->rx_stats.syncp); 447625e992a4SHeiner Kallweit } 447725e992a4SHeiner Kallweit release_descriptor: 447825e992a4SHeiner Kallweit rtl8169_mark_to_asic(desc); 447925e992a4SHeiner Kallweit } 448025e992a4SHeiner Kallweit 448125e992a4SHeiner Kallweit count = cur_rx - tp->cur_rx; 448225e992a4SHeiner Kallweit tp->cur_rx = cur_rx; 448325e992a4SHeiner Kallweit 448425e992a4SHeiner Kallweit return count; 448525e992a4SHeiner Kallweit } 448625e992a4SHeiner Kallweit 448725e992a4SHeiner Kallweit static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) 448825e992a4SHeiner Kallweit { 448925e992a4SHeiner Kallweit struct rtl8169_private *tp = dev_instance; 4490c1d532d2SHeiner Kallweit u32 status = rtl_get_events(tp); 449125e992a4SHeiner Kallweit 4492c1d532d2SHeiner Kallweit if (!tp->irq_enabled || (status & 0xffff) == 0xffff || 4493c1d532d2SHeiner Kallweit !(status & tp->irq_mask)) 449425e992a4SHeiner Kallweit return IRQ_NONE; 449525e992a4SHeiner Kallweit 449625e992a4SHeiner Kallweit if (unlikely(status & SYSErr)) { 449725e992a4SHeiner Kallweit rtl8169_pcierr_interrupt(tp->dev); 449825e992a4SHeiner Kallweit goto out; 449925e992a4SHeiner Kallweit } 450025e992a4SHeiner Kallweit 450125e992a4SHeiner Kallweit if (status & LinkChg) 450225e992a4SHeiner Kallweit phy_mac_interrupt(tp->phydev); 450325e992a4SHeiner Kallweit 450425e992a4SHeiner Kallweit if (unlikely(status & RxFIFOOver && 450525e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_11)) { 450625e992a4SHeiner Kallweit netif_stop_queue(tp->dev); 45076b02e407SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 450825e992a4SHeiner Kallweit } 450925e992a4SHeiner Kallweit 451025e992a4SHeiner Kallweit rtl_irq_disable(tp); 451125e992a4SHeiner Kallweit napi_schedule_irqoff(&tp->napi); 451225e992a4SHeiner Kallweit out: 451325e992a4SHeiner Kallweit rtl_ack_events(tp, status); 451425e992a4SHeiner Kallweit 451525e992a4SHeiner Kallweit return IRQ_HANDLED; 451625e992a4SHeiner Kallweit } 451725e992a4SHeiner Kallweit 451825e992a4SHeiner Kallweit static void rtl_task(struct work_struct *work) 451925e992a4SHeiner Kallweit { 452025e992a4SHeiner Kallweit struct rtl8169_private *tp = 452125e992a4SHeiner Kallweit container_of(work, struct rtl8169_private, wk.work); 452225e992a4SHeiner Kallweit 452325e992a4SHeiner Kallweit rtl_lock_work(tp); 452425e992a4SHeiner Kallweit 4525e18958c6SHeiner Kallweit if (!netif_running(tp->dev) || 452625e992a4SHeiner Kallweit !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) 452725e992a4SHeiner Kallweit goto out_unlock; 452825e992a4SHeiner Kallweit 4529e18958c6SHeiner Kallweit if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) 4530e18958c6SHeiner Kallweit rtl_reset_work(tp); 453125e992a4SHeiner Kallweit out_unlock: 453225e992a4SHeiner Kallweit rtl_unlock_work(tp); 453325e992a4SHeiner Kallweit } 453425e992a4SHeiner Kallweit 453525e992a4SHeiner Kallweit static int rtl8169_poll(struct napi_struct *napi, int budget) 453625e992a4SHeiner Kallweit { 453725e992a4SHeiner Kallweit struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); 453825e992a4SHeiner Kallweit struct net_device *dev = tp->dev; 453925e992a4SHeiner Kallweit int work_done; 454025e992a4SHeiner Kallweit 454125e992a4SHeiner Kallweit work_done = rtl_rx(dev, tp, (u32) budget); 454225e992a4SHeiner Kallweit 454325e992a4SHeiner Kallweit rtl_tx(dev, tp, budget); 454425e992a4SHeiner Kallweit 454525e992a4SHeiner Kallweit if (work_done < budget) { 454625e992a4SHeiner Kallweit napi_complete_done(napi, work_done); 454725e992a4SHeiner Kallweit rtl_irq_enable(tp); 454825e992a4SHeiner Kallweit } 454925e992a4SHeiner Kallweit 455025e992a4SHeiner Kallweit return work_done; 455125e992a4SHeiner Kallweit } 455225e992a4SHeiner Kallweit 455325e992a4SHeiner Kallweit static void r8169_phylink_handler(struct net_device *ndev) 455425e992a4SHeiner Kallweit { 455525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(ndev); 455625e992a4SHeiner Kallweit 455725e992a4SHeiner Kallweit if (netif_carrier_ok(ndev)) { 455825e992a4SHeiner Kallweit rtl_link_chg_patch(tp); 455925e992a4SHeiner Kallweit pm_request_resume(&tp->pci_dev->dev); 456025e992a4SHeiner Kallweit } else { 456125e992a4SHeiner Kallweit pm_runtime_idle(&tp->pci_dev->dev); 456225e992a4SHeiner Kallweit } 456325e992a4SHeiner Kallweit 456425e992a4SHeiner Kallweit if (net_ratelimit()) 456525e992a4SHeiner Kallweit phy_print_status(tp->phydev); 456625e992a4SHeiner Kallweit } 456725e992a4SHeiner Kallweit 456825e992a4SHeiner Kallweit static int r8169_phy_connect(struct rtl8169_private *tp) 456925e992a4SHeiner Kallweit { 457025e992a4SHeiner Kallweit struct phy_device *phydev = tp->phydev; 457125e992a4SHeiner Kallweit phy_interface_t phy_mode; 457225e992a4SHeiner Kallweit int ret; 457325e992a4SHeiner Kallweit 457425e992a4SHeiner Kallweit phy_mode = tp->supports_gmii ? PHY_INTERFACE_MODE_GMII : 457525e992a4SHeiner Kallweit PHY_INTERFACE_MODE_MII; 457625e992a4SHeiner Kallweit 457725e992a4SHeiner Kallweit ret = phy_connect_direct(tp->dev, phydev, r8169_phylink_handler, 457825e992a4SHeiner Kallweit phy_mode); 457925e992a4SHeiner Kallweit if (ret) 458025e992a4SHeiner Kallweit return ret; 458125e992a4SHeiner Kallweit 458266058b1cSHeiner Kallweit if (!tp->supports_gmii) 458325e992a4SHeiner Kallweit phy_set_max_speed(phydev, SPEED_100); 458425e992a4SHeiner Kallweit 458525e992a4SHeiner Kallweit phy_support_asym_pause(phydev); 458625e992a4SHeiner Kallweit 458725e992a4SHeiner Kallweit phy_attached_info(phydev); 458825e992a4SHeiner Kallweit 458925e992a4SHeiner Kallweit return 0; 459025e992a4SHeiner Kallweit } 459125e992a4SHeiner Kallweit 459225e992a4SHeiner Kallweit static void rtl8169_down(struct net_device *dev) 459325e992a4SHeiner Kallweit { 459425e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 459525e992a4SHeiner Kallweit 459625e992a4SHeiner Kallweit phy_stop(tp->phydev); 459725e992a4SHeiner Kallweit 459825e992a4SHeiner Kallweit napi_disable(&tp->napi); 459925e992a4SHeiner Kallweit netif_stop_queue(dev); 460025e992a4SHeiner Kallweit 460125e992a4SHeiner Kallweit rtl8169_hw_reset(tp); 460225e992a4SHeiner Kallweit 460325e992a4SHeiner Kallweit /* Give a racing hard_start_xmit a few cycles to complete. */ 460425e992a4SHeiner Kallweit synchronize_rcu(); 460525e992a4SHeiner Kallweit 460625e992a4SHeiner Kallweit rtl8169_tx_clear(tp); 460725e992a4SHeiner Kallweit 460825e992a4SHeiner Kallweit rtl8169_rx_clear(tp); 460925e992a4SHeiner Kallweit 461025e992a4SHeiner Kallweit rtl_pll_power_down(tp); 461125e992a4SHeiner Kallweit } 461225e992a4SHeiner Kallweit 461325e992a4SHeiner Kallweit static int rtl8169_close(struct net_device *dev) 461425e992a4SHeiner Kallweit { 461525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 461625e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 461725e992a4SHeiner Kallweit 461825e992a4SHeiner Kallweit pm_runtime_get_sync(&pdev->dev); 461925e992a4SHeiner Kallweit 462025e992a4SHeiner Kallweit /* Update counters before going down */ 462125e992a4SHeiner Kallweit rtl8169_update_counters(tp); 462225e992a4SHeiner Kallweit 462325e992a4SHeiner Kallweit rtl_lock_work(tp); 462425e992a4SHeiner Kallweit /* Clear all task flags */ 462525e992a4SHeiner Kallweit bitmap_zero(tp->wk.flags, RTL_FLAG_MAX); 462625e992a4SHeiner Kallweit 462725e992a4SHeiner Kallweit rtl8169_down(dev); 462825e992a4SHeiner Kallweit rtl_unlock_work(tp); 462925e992a4SHeiner Kallweit 463025e992a4SHeiner Kallweit cancel_work_sync(&tp->wk.work); 463125e992a4SHeiner Kallweit 463225e992a4SHeiner Kallweit phy_disconnect(tp->phydev); 463325e992a4SHeiner Kallweit 463425e992a4SHeiner Kallweit pci_free_irq(pdev, 0, tp); 463525e992a4SHeiner Kallweit 463625e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, 463725e992a4SHeiner Kallweit tp->RxPhyAddr); 463825e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, 463925e992a4SHeiner Kallweit tp->TxPhyAddr); 464025e992a4SHeiner Kallweit tp->TxDescArray = NULL; 464125e992a4SHeiner Kallweit tp->RxDescArray = NULL; 464225e992a4SHeiner Kallweit 464325e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev); 464425e992a4SHeiner Kallweit 464525e992a4SHeiner Kallweit return 0; 464625e992a4SHeiner Kallweit } 464725e992a4SHeiner Kallweit 464825e992a4SHeiner Kallweit #ifdef CONFIG_NET_POLL_CONTROLLER 464925e992a4SHeiner Kallweit static void rtl8169_netpoll(struct net_device *dev) 465025e992a4SHeiner Kallweit { 465125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 465225e992a4SHeiner Kallweit 465325e992a4SHeiner Kallweit rtl8169_interrupt(pci_irq_vector(tp->pci_dev, 0), tp); 465425e992a4SHeiner Kallweit } 465525e992a4SHeiner Kallweit #endif 465625e992a4SHeiner Kallweit 465725e992a4SHeiner Kallweit static int rtl_open(struct net_device *dev) 465825e992a4SHeiner Kallweit { 465925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 466025e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 466125e992a4SHeiner Kallweit int retval = -ENOMEM; 466225e992a4SHeiner Kallweit 466325e992a4SHeiner Kallweit pm_runtime_get_sync(&pdev->dev); 466425e992a4SHeiner Kallweit 466525e992a4SHeiner Kallweit /* 466625e992a4SHeiner Kallweit * Rx and Tx descriptors needs 256 bytes alignment. 466725e992a4SHeiner Kallweit * dma_alloc_coherent provides more. 466825e992a4SHeiner Kallweit */ 466925e992a4SHeiner Kallweit tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES, 467025e992a4SHeiner Kallweit &tp->TxPhyAddr, GFP_KERNEL); 467125e992a4SHeiner Kallweit if (!tp->TxDescArray) 467225e992a4SHeiner Kallweit goto err_pm_runtime_put; 467325e992a4SHeiner Kallweit 467425e992a4SHeiner Kallweit tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES, 467525e992a4SHeiner Kallweit &tp->RxPhyAddr, GFP_KERNEL); 467625e992a4SHeiner Kallweit if (!tp->RxDescArray) 467725e992a4SHeiner Kallweit goto err_free_tx_0; 467825e992a4SHeiner Kallweit 467925e992a4SHeiner Kallweit retval = rtl8169_init_ring(tp); 468025e992a4SHeiner Kallweit if (retval < 0) 468125e992a4SHeiner Kallweit goto err_free_rx_1; 468225e992a4SHeiner Kallweit 468325e992a4SHeiner Kallweit rtl_request_firmware(tp); 468425e992a4SHeiner Kallweit 468525e992a4SHeiner Kallweit retval = pci_request_irq(pdev, 0, rtl8169_interrupt, NULL, tp, 468625e992a4SHeiner Kallweit dev->name); 468725e992a4SHeiner Kallweit if (retval < 0) 468825e992a4SHeiner Kallweit goto err_release_fw_2; 468925e992a4SHeiner Kallweit 469025e992a4SHeiner Kallweit retval = r8169_phy_connect(tp); 469125e992a4SHeiner Kallweit if (retval) 469225e992a4SHeiner Kallweit goto err_free_irq; 469325e992a4SHeiner Kallweit 469425e992a4SHeiner Kallweit rtl_lock_work(tp); 469525e992a4SHeiner Kallweit 469625e992a4SHeiner Kallweit set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); 469725e992a4SHeiner Kallweit 469825e992a4SHeiner Kallweit napi_enable(&tp->napi); 469925e992a4SHeiner Kallweit 4700b5aed0b3SHeiner Kallweit rtl8169_init_phy(tp); 470125e992a4SHeiner Kallweit 470225e992a4SHeiner Kallweit rtl_pll_power_up(tp); 470325e992a4SHeiner Kallweit 470425e992a4SHeiner Kallweit rtl_hw_start(tp); 470525e992a4SHeiner Kallweit 4706d56f58ceSHeiner Kallweit rtl8169_init_counter_offsets(tp); 470725e992a4SHeiner Kallweit 470825e992a4SHeiner Kallweit phy_start(tp->phydev); 470925e992a4SHeiner Kallweit netif_start_queue(dev); 471025e992a4SHeiner Kallweit 471125e992a4SHeiner Kallweit rtl_unlock_work(tp); 471225e992a4SHeiner Kallweit 471325e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev); 471425e992a4SHeiner Kallweit out: 471525e992a4SHeiner Kallweit return retval; 471625e992a4SHeiner Kallweit 471725e992a4SHeiner Kallweit err_free_irq: 471825e992a4SHeiner Kallweit pci_free_irq(pdev, 0, tp); 471925e992a4SHeiner Kallweit err_release_fw_2: 472025e992a4SHeiner Kallweit rtl_release_firmware(tp); 472125e992a4SHeiner Kallweit rtl8169_rx_clear(tp); 472225e992a4SHeiner Kallweit err_free_rx_1: 472325e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, 472425e992a4SHeiner Kallweit tp->RxPhyAddr); 472525e992a4SHeiner Kallweit tp->RxDescArray = NULL; 472625e992a4SHeiner Kallweit err_free_tx_0: 472725e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, 472825e992a4SHeiner Kallweit tp->TxPhyAddr); 472925e992a4SHeiner Kallweit tp->TxDescArray = NULL; 473025e992a4SHeiner Kallweit err_pm_runtime_put: 473125e992a4SHeiner Kallweit pm_runtime_put_noidle(&pdev->dev); 473225e992a4SHeiner Kallweit goto out; 473325e992a4SHeiner Kallweit } 473425e992a4SHeiner Kallweit 473525e992a4SHeiner Kallweit static void 473625e992a4SHeiner Kallweit rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 473725e992a4SHeiner Kallweit { 473825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 473925e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 474025e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters; 474125e992a4SHeiner Kallweit unsigned int start; 474225e992a4SHeiner Kallweit 474325e992a4SHeiner Kallweit pm_runtime_get_noresume(&pdev->dev); 474425e992a4SHeiner Kallweit 4745314a9cbbSHeiner Kallweit netdev_stats_to_stats64(stats, &dev->stats); 4746314a9cbbSHeiner Kallweit 474725e992a4SHeiner Kallweit do { 474825e992a4SHeiner Kallweit start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp); 474925e992a4SHeiner Kallweit stats->rx_packets = tp->rx_stats.packets; 475025e992a4SHeiner Kallweit stats->rx_bytes = tp->rx_stats.bytes; 475125e992a4SHeiner Kallweit } while (u64_stats_fetch_retry_irq(&tp->rx_stats.syncp, start)); 475225e992a4SHeiner Kallweit 475325e992a4SHeiner Kallweit do { 475425e992a4SHeiner Kallweit start = u64_stats_fetch_begin_irq(&tp->tx_stats.syncp); 475525e992a4SHeiner Kallweit stats->tx_packets = tp->tx_stats.packets; 475625e992a4SHeiner Kallweit stats->tx_bytes = tp->tx_stats.bytes; 475725e992a4SHeiner Kallweit } while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start)); 475825e992a4SHeiner Kallweit 475925e992a4SHeiner Kallweit /* 4760ed72a9bbSCorentin Musard * Fetch additional counter values missing in stats collected by driver 476125e992a4SHeiner Kallweit * from tally counters. 476225e992a4SHeiner Kallweit */ 476325e992a4SHeiner Kallweit if (pm_runtime_active(&pdev->dev)) 476425e992a4SHeiner Kallweit rtl8169_update_counters(tp); 476525e992a4SHeiner Kallweit 476625e992a4SHeiner Kallweit /* 476725e992a4SHeiner Kallweit * Subtract values fetched during initalization. 476825e992a4SHeiner Kallweit * See rtl8169_init_counter_offsets for a description why we do that. 476925e992a4SHeiner Kallweit */ 477025e992a4SHeiner Kallweit stats->tx_errors = le64_to_cpu(counters->tx_errors) - 477125e992a4SHeiner Kallweit le64_to_cpu(tp->tc_offset.tx_errors); 477225e992a4SHeiner Kallweit stats->collisions = le32_to_cpu(counters->tx_multi_collision) - 477325e992a4SHeiner Kallweit le32_to_cpu(tp->tc_offset.tx_multi_collision); 477425e992a4SHeiner Kallweit stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) - 477525e992a4SHeiner Kallweit le16_to_cpu(tp->tc_offset.tx_aborted); 47760da3359aSHeiner Kallweit stats->rx_missed_errors = le16_to_cpu(counters->rx_missed) - 47770da3359aSHeiner Kallweit le16_to_cpu(tp->tc_offset.rx_missed); 477825e992a4SHeiner Kallweit 477925e992a4SHeiner Kallweit pm_runtime_put_noidle(&pdev->dev); 478025e992a4SHeiner Kallweit } 478125e992a4SHeiner Kallweit 478225e992a4SHeiner Kallweit static void rtl8169_net_suspend(struct net_device *dev) 478325e992a4SHeiner Kallweit { 478425e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 478525e992a4SHeiner Kallweit 478625e992a4SHeiner Kallweit if (!netif_running(dev)) 478725e992a4SHeiner Kallweit return; 478825e992a4SHeiner Kallweit 478925e992a4SHeiner Kallweit phy_stop(tp->phydev); 479025e992a4SHeiner Kallweit netif_device_detach(dev); 479125e992a4SHeiner Kallweit 479225e992a4SHeiner Kallweit rtl_lock_work(tp); 479325e992a4SHeiner Kallweit napi_disable(&tp->napi); 479425e992a4SHeiner Kallweit /* Clear all task flags */ 479525e992a4SHeiner Kallweit bitmap_zero(tp->wk.flags, RTL_FLAG_MAX); 479625e992a4SHeiner Kallweit 479725e992a4SHeiner Kallweit rtl_unlock_work(tp); 479825e992a4SHeiner Kallweit 479925e992a4SHeiner Kallweit rtl_pll_power_down(tp); 480025e992a4SHeiner Kallweit } 480125e992a4SHeiner Kallweit 480225e992a4SHeiner Kallweit #ifdef CONFIG_PM 480325e992a4SHeiner Kallweit 480425e992a4SHeiner Kallweit static int rtl8169_suspend(struct device *device) 480525e992a4SHeiner Kallweit { 480625e992a4SHeiner Kallweit struct net_device *dev = dev_get_drvdata(device); 480725e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 480825e992a4SHeiner Kallweit 480925e992a4SHeiner Kallweit rtl8169_net_suspend(dev); 481025e992a4SHeiner Kallweit clk_disable_unprepare(tp->clk); 481125e992a4SHeiner Kallweit 481225e992a4SHeiner Kallweit return 0; 481325e992a4SHeiner Kallweit } 481425e992a4SHeiner Kallweit 481525e992a4SHeiner Kallweit static void __rtl8169_resume(struct net_device *dev) 481625e992a4SHeiner Kallweit { 481725e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 481825e992a4SHeiner Kallweit 481925e992a4SHeiner Kallweit netif_device_attach(dev); 482025e992a4SHeiner Kallweit 482125e992a4SHeiner Kallweit rtl_pll_power_up(tp); 4822b5aed0b3SHeiner Kallweit rtl8169_init_phy(tp); 482325e992a4SHeiner Kallweit 482425e992a4SHeiner Kallweit phy_start(tp->phydev); 482525e992a4SHeiner Kallweit 482625e992a4SHeiner Kallweit rtl_lock_work(tp); 482725e992a4SHeiner Kallweit napi_enable(&tp->napi); 482825e992a4SHeiner Kallweit set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); 482925e992a4SHeiner Kallweit rtl_reset_work(tp); 483025e992a4SHeiner Kallweit rtl_unlock_work(tp); 483125e992a4SHeiner Kallweit } 483225e992a4SHeiner Kallweit 483325e992a4SHeiner Kallweit static int rtl8169_resume(struct device *device) 483425e992a4SHeiner Kallweit { 483525e992a4SHeiner Kallweit struct net_device *dev = dev_get_drvdata(device); 483625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 483725e992a4SHeiner Kallweit 483825e992a4SHeiner Kallweit rtl_rar_set(tp, dev->dev_addr); 483925e992a4SHeiner Kallweit 484025e992a4SHeiner Kallweit clk_prepare_enable(tp->clk); 484125e992a4SHeiner Kallweit 484225e992a4SHeiner Kallweit if (netif_running(dev)) 484325e992a4SHeiner Kallweit __rtl8169_resume(dev); 484425e992a4SHeiner Kallweit 484525e992a4SHeiner Kallweit return 0; 484625e992a4SHeiner Kallweit } 484725e992a4SHeiner Kallweit 484825e992a4SHeiner Kallweit static int rtl8169_runtime_suspend(struct device *device) 484925e992a4SHeiner Kallweit { 485025e992a4SHeiner Kallweit struct net_device *dev = dev_get_drvdata(device); 485125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 485225e992a4SHeiner Kallweit 485325e992a4SHeiner Kallweit if (!tp->TxDescArray) 485425e992a4SHeiner Kallweit return 0; 485525e992a4SHeiner Kallweit 485625e992a4SHeiner Kallweit rtl_lock_work(tp); 485725e992a4SHeiner Kallweit __rtl8169_set_wol(tp, WAKE_ANY); 485825e992a4SHeiner Kallweit rtl_unlock_work(tp); 485925e992a4SHeiner Kallweit 486025e992a4SHeiner Kallweit rtl8169_net_suspend(dev); 486125e992a4SHeiner Kallweit 486225e992a4SHeiner Kallweit /* Update counters before going runtime suspend */ 486325e992a4SHeiner Kallweit rtl8169_update_counters(tp); 486425e992a4SHeiner Kallweit 486525e992a4SHeiner Kallweit return 0; 486625e992a4SHeiner Kallweit } 486725e992a4SHeiner Kallweit 486825e992a4SHeiner Kallweit static int rtl8169_runtime_resume(struct device *device) 486925e992a4SHeiner Kallweit { 487025e992a4SHeiner Kallweit struct net_device *dev = dev_get_drvdata(device); 487125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 487225e992a4SHeiner Kallweit 487325e992a4SHeiner Kallweit rtl_rar_set(tp, dev->dev_addr); 487425e992a4SHeiner Kallweit 487525e992a4SHeiner Kallweit if (!tp->TxDescArray) 487625e992a4SHeiner Kallweit return 0; 487725e992a4SHeiner Kallweit 487825e992a4SHeiner Kallweit rtl_lock_work(tp); 487925e992a4SHeiner Kallweit __rtl8169_set_wol(tp, tp->saved_wolopts); 488025e992a4SHeiner Kallweit rtl_unlock_work(tp); 488125e992a4SHeiner Kallweit 488225e992a4SHeiner Kallweit __rtl8169_resume(dev); 488325e992a4SHeiner Kallweit 488425e992a4SHeiner Kallweit return 0; 488525e992a4SHeiner Kallweit } 488625e992a4SHeiner Kallweit 488725e992a4SHeiner Kallweit static int rtl8169_runtime_idle(struct device *device) 488825e992a4SHeiner Kallweit { 488925e992a4SHeiner Kallweit struct net_device *dev = dev_get_drvdata(device); 489025e992a4SHeiner Kallweit 489125e992a4SHeiner Kallweit if (!netif_running(dev) || !netif_carrier_ok(dev)) 489225e992a4SHeiner Kallweit pm_schedule_suspend(device, 10000); 489325e992a4SHeiner Kallweit 489425e992a4SHeiner Kallweit return -EBUSY; 489525e992a4SHeiner Kallweit } 489625e992a4SHeiner Kallweit 489725e992a4SHeiner Kallweit static const struct dev_pm_ops rtl8169_pm_ops = { 489825e992a4SHeiner Kallweit .suspend = rtl8169_suspend, 489925e992a4SHeiner Kallweit .resume = rtl8169_resume, 490025e992a4SHeiner Kallweit .freeze = rtl8169_suspend, 490125e992a4SHeiner Kallweit .thaw = rtl8169_resume, 490225e992a4SHeiner Kallweit .poweroff = rtl8169_suspend, 490325e992a4SHeiner Kallweit .restore = rtl8169_resume, 490425e992a4SHeiner Kallweit .runtime_suspend = rtl8169_runtime_suspend, 490525e992a4SHeiner Kallweit .runtime_resume = rtl8169_runtime_resume, 490625e992a4SHeiner Kallweit .runtime_idle = rtl8169_runtime_idle, 490725e992a4SHeiner Kallweit }; 490825e992a4SHeiner Kallweit 490925e992a4SHeiner Kallweit #define RTL8169_PM_OPS (&rtl8169_pm_ops) 491025e992a4SHeiner Kallweit 491125e992a4SHeiner Kallweit #else /* !CONFIG_PM */ 491225e992a4SHeiner Kallweit 491325e992a4SHeiner Kallweit #define RTL8169_PM_OPS NULL 491425e992a4SHeiner Kallweit 491525e992a4SHeiner Kallweit #endif /* !CONFIG_PM */ 491625e992a4SHeiner Kallweit 491725e992a4SHeiner Kallweit static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp) 491825e992a4SHeiner Kallweit { 491925e992a4SHeiner Kallweit /* WoL fails with 8168b when the receiver is disabled. */ 492025e992a4SHeiner Kallweit switch (tp->mac_version) { 492125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_11: 492225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 492325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 492425e992a4SHeiner Kallweit pci_clear_master(tp->pci_dev); 492525e992a4SHeiner Kallweit 492625e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, CmdRxEnb); 4927711463f8SHeiner Kallweit rtl_pci_commit(tp); 492825e992a4SHeiner Kallweit break; 492925e992a4SHeiner Kallweit default: 493025e992a4SHeiner Kallweit break; 493125e992a4SHeiner Kallweit } 493225e992a4SHeiner Kallweit } 493325e992a4SHeiner Kallweit 493425e992a4SHeiner Kallweit static void rtl_shutdown(struct pci_dev *pdev) 493525e992a4SHeiner Kallweit { 493625e992a4SHeiner Kallweit struct net_device *dev = pci_get_drvdata(pdev); 493725e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 493825e992a4SHeiner Kallweit 493925e992a4SHeiner Kallweit rtl8169_net_suspend(dev); 494025e992a4SHeiner Kallweit 494125e992a4SHeiner Kallweit /* Restore original MAC address */ 494225e992a4SHeiner Kallweit rtl_rar_set(tp, dev->perm_addr); 494325e992a4SHeiner Kallweit 494425e992a4SHeiner Kallweit rtl8169_hw_reset(tp); 494525e992a4SHeiner Kallweit 494625e992a4SHeiner Kallweit if (system_state == SYSTEM_POWER_OFF) { 494725e992a4SHeiner Kallweit if (tp->saved_wolopts) { 494825e992a4SHeiner Kallweit rtl_wol_suspend_quirk(tp); 494925e992a4SHeiner Kallweit rtl_wol_shutdown_quirk(tp); 495025e992a4SHeiner Kallweit } 495125e992a4SHeiner Kallweit 495225e992a4SHeiner Kallweit pci_wake_from_d3(pdev, true); 495325e992a4SHeiner Kallweit pci_set_power_state(pdev, PCI_D3hot); 495425e992a4SHeiner Kallweit } 495525e992a4SHeiner Kallweit } 495625e992a4SHeiner Kallweit 495725e992a4SHeiner Kallweit static void rtl_remove_one(struct pci_dev *pdev) 495825e992a4SHeiner Kallweit { 495925e992a4SHeiner Kallweit struct net_device *dev = pci_get_drvdata(pdev); 496025e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev); 496125e992a4SHeiner Kallweit 496225e992a4SHeiner Kallweit if (r8168_check_dash(tp)) 496325e992a4SHeiner Kallweit rtl8168_driver_stop(tp); 496425e992a4SHeiner Kallweit 496525e992a4SHeiner Kallweit netif_napi_del(&tp->napi); 496625e992a4SHeiner Kallweit 496725e992a4SHeiner Kallweit unregister_netdev(dev); 496825e992a4SHeiner Kallweit mdiobus_unregister(tp->phydev->mdio.bus); 496925e992a4SHeiner Kallweit 497025e992a4SHeiner Kallweit rtl_release_firmware(tp); 497125e992a4SHeiner Kallweit 497225e992a4SHeiner Kallweit if (pci_dev_run_wake(pdev)) 497325e992a4SHeiner Kallweit pm_runtime_get_noresume(&pdev->dev); 497425e992a4SHeiner Kallweit 497525e992a4SHeiner Kallweit /* restore original MAC address */ 497625e992a4SHeiner Kallweit rtl_rar_set(tp, dev->perm_addr); 497725e992a4SHeiner Kallweit } 497825e992a4SHeiner Kallweit 497925e992a4SHeiner Kallweit static const struct net_device_ops rtl_netdev_ops = { 498025e992a4SHeiner Kallweit .ndo_open = rtl_open, 498125e992a4SHeiner Kallweit .ndo_stop = rtl8169_close, 498225e992a4SHeiner Kallweit .ndo_get_stats64 = rtl8169_get_stats64, 498325e992a4SHeiner Kallweit .ndo_start_xmit = rtl8169_start_xmit, 4984e64e0c89SHeiner Kallweit .ndo_features_check = rtl8169_features_check, 498525e992a4SHeiner Kallweit .ndo_tx_timeout = rtl8169_tx_timeout, 498625e992a4SHeiner Kallweit .ndo_validate_addr = eth_validate_addr, 498725e992a4SHeiner Kallweit .ndo_change_mtu = rtl8169_change_mtu, 498825e992a4SHeiner Kallweit .ndo_fix_features = rtl8169_fix_features, 498925e992a4SHeiner Kallweit .ndo_set_features = rtl8169_set_features, 499025e992a4SHeiner Kallweit .ndo_set_mac_address = rtl_set_mac_address, 49913231e5d2SHeiner Kallweit .ndo_do_ioctl = phy_do_ioctl_running, 499225e992a4SHeiner Kallweit .ndo_set_rx_mode = rtl_set_rx_mode, 499325e992a4SHeiner Kallweit #ifdef CONFIG_NET_POLL_CONTROLLER 499425e992a4SHeiner Kallweit .ndo_poll_controller = rtl8169_netpoll, 499525e992a4SHeiner Kallweit #endif 499625e992a4SHeiner Kallweit 499725e992a4SHeiner Kallweit }; 499825e992a4SHeiner Kallweit 4999ec9a4088SHeiner Kallweit static void rtl_set_irq_mask(struct rtl8169_private *tp) 5000ec9a4088SHeiner Kallweit { 50012045e158SHeiner Kallweit tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg; 5002ec9a4088SHeiner Kallweit 5003ec9a4088SHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 5004ec9a4088SHeiner Kallweit tp->irq_mask |= SYSErr | RxOverflow | RxFIFOOver; 5005ec9a4088SHeiner Kallweit else if (tp->mac_version == RTL_GIGA_MAC_VER_11) 5006ec9a4088SHeiner Kallweit /* special workaround needed */ 5007ec9a4088SHeiner Kallweit tp->irq_mask |= RxFIFOOver; 5008ec9a4088SHeiner Kallweit else 5009ec9a4088SHeiner Kallweit tp->irq_mask |= RxOverflow; 5010ec9a4088SHeiner Kallweit } 5011ec9a4088SHeiner Kallweit 501225e992a4SHeiner Kallweit static int rtl_alloc_irq(struct rtl8169_private *tp) 501325e992a4SHeiner Kallweit { 501425e992a4SHeiner Kallweit unsigned int flags; 501525e992a4SHeiner Kallweit 5016003bd5b4SHeiner Kallweit switch (tp->mac_version) { 5017003bd5b4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 501825e992a4SHeiner Kallweit rtl_unlock_config_regs(tp); 501925e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable); 502025e992a4SHeiner Kallweit rtl_lock_config_regs(tp); 5021003bd5b4SHeiner Kallweit /* fall through */ 5022f13bc681SHeiner Kallweit case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_17: 502325e992a4SHeiner Kallweit flags = PCI_IRQ_LEGACY; 5024003bd5b4SHeiner Kallweit break; 5025003bd5b4SHeiner Kallweit default: 502625e992a4SHeiner Kallweit flags = PCI_IRQ_ALL_TYPES; 5027003bd5b4SHeiner Kallweit break; 502825e992a4SHeiner Kallweit } 502925e992a4SHeiner Kallweit 503025e992a4SHeiner Kallweit return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags); 503125e992a4SHeiner Kallweit } 503225e992a4SHeiner Kallweit 503325e992a4SHeiner Kallweit static void rtl_read_mac_address(struct rtl8169_private *tp, 503425e992a4SHeiner Kallweit u8 mac_addr[ETH_ALEN]) 503525e992a4SHeiner Kallweit { 503625e992a4SHeiner Kallweit /* Get MAC address */ 50379e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp) && tp->mac_version != RTL_GIGA_MAC_VER_34) { 50389e9f33baSHeiner Kallweit u32 value = rtl_eri_read(tp, 0xe0); 50399e9f33baSHeiner Kallweit 504025e992a4SHeiner Kallweit mac_addr[0] = (value >> 0) & 0xff; 504125e992a4SHeiner Kallweit mac_addr[1] = (value >> 8) & 0xff; 504225e992a4SHeiner Kallweit mac_addr[2] = (value >> 16) & 0xff; 504325e992a4SHeiner Kallweit mac_addr[3] = (value >> 24) & 0xff; 504425e992a4SHeiner Kallweit 504525e992a4SHeiner Kallweit value = rtl_eri_read(tp, 0xe4); 504625e992a4SHeiner Kallweit mac_addr[4] = (value >> 0) & 0xff; 504725e992a4SHeiner Kallweit mac_addr[5] = (value >> 8) & 0xff; 5048f1bce4adSHeiner Kallweit } else if (rtl_is_8125(tp)) { 5049f1bce4adSHeiner Kallweit rtl_read_mac_from_reg(tp, mac_addr, MAC0_BKP); 505025e992a4SHeiner Kallweit } 505125e992a4SHeiner Kallweit } 505225e992a4SHeiner Kallweit 505325e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_link_list_ready_cond) 505425e992a4SHeiner Kallweit { 505525e992a4SHeiner Kallweit return RTL_R8(tp, MCU) & LINK_LIST_RDY; 505625e992a4SHeiner Kallweit } 505725e992a4SHeiner Kallweit 5058e031ce80SHeiner Kallweit static void r8168g_wait_ll_share_fifo_ready(struct rtl8169_private *tp) 5059e031ce80SHeiner Kallweit { 5060e031ce80SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42); 5061e031ce80SHeiner Kallweit } 5062e031ce80SHeiner Kallweit 506325e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_rxtx_empty_cond) 506425e992a4SHeiner Kallweit { 506525e992a4SHeiner Kallweit return (RTL_R8(tp, MCU) & RXTX_EMPTY) == RXTX_EMPTY; 506625e992a4SHeiner Kallweit } 506725e992a4SHeiner Kallweit 506825e992a4SHeiner Kallweit static int r8169_mdio_read_reg(struct mii_bus *mii_bus, int phyaddr, int phyreg) 506925e992a4SHeiner Kallweit { 507025e992a4SHeiner Kallweit struct rtl8169_private *tp = mii_bus->priv; 507125e992a4SHeiner Kallweit 507225e992a4SHeiner Kallweit if (phyaddr > 0) 507325e992a4SHeiner Kallweit return -ENODEV; 507425e992a4SHeiner Kallweit 507525e992a4SHeiner Kallweit return rtl_readphy(tp, phyreg); 507625e992a4SHeiner Kallweit } 507725e992a4SHeiner Kallweit 507825e992a4SHeiner Kallweit static int r8169_mdio_write_reg(struct mii_bus *mii_bus, int phyaddr, 507925e992a4SHeiner Kallweit int phyreg, u16 val) 508025e992a4SHeiner Kallweit { 508125e992a4SHeiner Kallweit struct rtl8169_private *tp = mii_bus->priv; 508225e992a4SHeiner Kallweit 508325e992a4SHeiner Kallweit if (phyaddr > 0) 508425e992a4SHeiner Kallweit return -ENODEV; 508525e992a4SHeiner Kallweit 508625e992a4SHeiner Kallweit rtl_writephy(tp, phyreg, val); 508725e992a4SHeiner Kallweit 508825e992a4SHeiner Kallweit return 0; 508925e992a4SHeiner Kallweit } 509025e992a4SHeiner Kallweit 509125e992a4SHeiner Kallweit static int r8169_mdio_register(struct rtl8169_private *tp) 509225e992a4SHeiner Kallweit { 509325e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev; 509425e992a4SHeiner Kallweit struct mii_bus *new_bus; 509525e992a4SHeiner Kallweit int ret; 509625e992a4SHeiner Kallweit 509725e992a4SHeiner Kallweit new_bus = devm_mdiobus_alloc(&pdev->dev); 509825e992a4SHeiner Kallweit if (!new_bus) 509925e992a4SHeiner Kallweit return -ENOMEM; 510025e992a4SHeiner Kallweit 510125e992a4SHeiner Kallweit new_bus->name = "r8169"; 510225e992a4SHeiner Kallweit new_bus->priv = tp; 510325e992a4SHeiner Kallweit new_bus->parent = &pdev->dev; 510425e992a4SHeiner Kallweit new_bus->irq[0] = PHY_IGNORE_INTERRUPT; 510525e992a4SHeiner Kallweit snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x", pci_dev_id(pdev)); 510625e992a4SHeiner Kallweit 510725e992a4SHeiner Kallweit new_bus->read = r8169_mdio_read_reg; 510825e992a4SHeiner Kallweit new_bus->write = r8169_mdio_write_reg; 510925e992a4SHeiner Kallweit 51100785dad4SHeiner Kallweit ret = devm_mdiobus_register(new_bus); 511125e992a4SHeiner Kallweit if (ret) 511225e992a4SHeiner Kallweit return ret; 511325e992a4SHeiner Kallweit 511425e992a4SHeiner Kallweit tp->phydev = mdiobus_get_phy(new_bus, 0); 511525e992a4SHeiner Kallweit if (!tp->phydev) { 511625e992a4SHeiner Kallweit return -ENODEV; 51172e8c339bSHeiner Kallweit } else if (!tp->phydev->drv) { 51182e8c339bSHeiner Kallweit /* Most chip versions fail with the genphy driver. 51192e8c339bSHeiner Kallweit * Therefore ensure that the dedicated PHY driver is loaded. 51202e8c339bSHeiner Kallweit */ 51210c2006b2SHeiner 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", 51220c2006b2SHeiner Kallweit tp->phydev->phy_id); 51232e8c339bSHeiner Kallweit return -EUNATCH; 512425e992a4SHeiner Kallweit } 512525e992a4SHeiner Kallweit 512625e992a4SHeiner Kallweit /* PHY will be woken up in rtl_open() */ 512725e992a4SHeiner Kallweit phy_suspend(tp->phydev); 512825e992a4SHeiner Kallweit 512925e992a4SHeiner Kallweit return 0; 513025e992a4SHeiner Kallweit } 513125e992a4SHeiner Kallweit 513225e992a4SHeiner Kallweit static void rtl_hw_init_8168g(struct rtl8169_private *tp) 513325e992a4SHeiner Kallweit { 513425e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN); 513525e992a4SHeiner Kallweit 5136d6836ef0SHeiner Kallweit if (!rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42)) 513725e992a4SHeiner Kallweit return; 513825e992a4SHeiner Kallweit 5139d6836ef0SHeiner Kallweit if (!rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42)) 514025e992a4SHeiner Kallweit return; 514125e992a4SHeiner Kallweit 514225e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); 514325e992a4SHeiner Kallweit msleep(1); 514425e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 514525e992a4SHeiner Kallweit 5146ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, BIT(14), 0); 5147e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp); 514825e992a4SHeiner Kallweit 5149ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, 0, BIT(15)); 5150e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp); 515125e992a4SHeiner Kallweit } 515225e992a4SHeiner Kallweit 5153f1bce4adSHeiner Kallweit static void rtl_hw_init_8125(struct rtl8169_private *tp) 5154f1bce4adSHeiner Kallweit { 5155f1bce4adSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN); 5156f1bce4adSHeiner Kallweit 5157d6836ef0SHeiner Kallweit if (!rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42)) 5158f1bce4adSHeiner Kallweit return; 5159f1bce4adSHeiner Kallweit 5160f1bce4adSHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); 5161f1bce4adSHeiner Kallweit msleep(1); 5162f1bce4adSHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB); 5163f1bce4adSHeiner Kallweit 5164f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, BIT(14), 0); 5165e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp); 5166f1bce4adSHeiner Kallweit 5167f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc0aa, 0x07d0); 5168f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc0a6, 0x0150); 5169f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc01e, 0x5555); 5170e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp); 5171f1bce4adSHeiner Kallweit } 5172f1bce4adSHeiner Kallweit 517325e992a4SHeiner Kallweit static void rtl_hw_initialize(struct rtl8169_private *tp) 517425e992a4SHeiner Kallweit { 517525e992a4SHeiner Kallweit switch (tp->mac_version) { 51761287723aSHeiner Kallweit case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: 517725e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp); 517825e992a4SHeiner Kallweit /* fall through */ 517925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: 518025e992a4SHeiner Kallweit rtl_hw_init_8168g(tp); 518125e992a4SHeiner Kallweit break; 5182f1bce4adSHeiner Kallweit case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: 5183f1bce4adSHeiner Kallweit rtl_hw_init_8125(tp); 5184f1bce4adSHeiner Kallweit break; 518525e992a4SHeiner Kallweit default: 518625e992a4SHeiner Kallweit break; 518725e992a4SHeiner Kallweit } 518825e992a4SHeiner Kallweit } 518925e992a4SHeiner Kallweit 519025e992a4SHeiner Kallweit static int rtl_jumbo_max(struct rtl8169_private *tp) 519125e992a4SHeiner Kallweit { 519225e992a4SHeiner Kallweit /* Non-GBit versions don't support jumbo frames */ 519325e992a4SHeiner Kallweit if (!tp->supports_gmii) 5194a8ec173aSHeiner Kallweit return 0; 519525e992a4SHeiner Kallweit 519625e992a4SHeiner Kallweit switch (tp->mac_version) { 519725e992a4SHeiner Kallweit /* RTL8169 */ 519825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: 519925e992a4SHeiner Kallweit return JUMBO_7K; 520025e992a4SHeiner Kallweit /* RTL8168b */ 520125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_11: 520225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_12: 520325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17: 520425e992a4SHeiner Kallweit return JUMBO_4K; 520525e992a4SHeiner Kallweit /* RTL8168c */ 520625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: 520725e992a4SHeiner Kallweit return JUMBO_6K; 520825e992a4SHeiner Kallweit default: 520925e992a4SHeiner Kallweit return JUMBO_9K; 521025e992a4SHeiner Kallweit } 521125e992a4SHeiner Kallweit } 521225e992a4SHeiner Kallweit 521325e992a4SHeiner Kallweit static void rtl_disable_clk(void *data) 521425e992a4SHeiner Kallweit { 521525e992a4SHeiner Kallweit clk_disable_unprepare(data); 521625e992a4SHeiner Kallweit } 521725e992a4SHeiner Kallweit 521825e992a4SHeiner Kallweit static int rtl_get_ether_clk(struct rtl8169_private *tp) 521925e992a4SHeiner Kallweit { 522025e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp); 522125e992a4SHeiner Kallweit struct clk *clk; 522225e992a4SHeiner Kallweit int rc; 522325e992a4SHeiner Kallweit 522425e992a4SHeiner Kallweit clk = devm_clk_get(d, "ether_clk"); 522525e992a4SHeiner Kallweit if (IS_ERR(clk)) { 522625e992a4SHeiner Kallweit rc = PTR_ERR(clk); 522725e992a4SHeiner Kallweit if (rc == -ENOENT) 522825e992a4SHeiner Kallweit /* clk-core allows NULL (for suspend / resume) */ 522925e992a4SHeiner Kallweit rc = 0; 523025e992a4SHeiner Kallweit else if (rc != -EPROBE_DEFER) 523125e992a4SHeiner Kallweit dev_err(d, "failed to get clk: %d\n", rc); 523225e992a4SHeiner Kallweit } else { 523325e992a4SHeiner Kallweit tp->clk = clk; 523425e992a4SHeiner Kallweit rc = clk_prepare_enable(clk); 523525e992a4SHeiner Kallweit if (rc) 523625e992a4SHeiner Kallweit dev_err(d, "failed to enable clk: %d\n", rc); 523725e992a4SHeiner Kallweit else 523825e992a4SHeiner Kallweit rc = devm_add_action_or_reset(d, rtl_disable_clk, clk); 523925e992a4SHeiner Kallweit } 524025e992a4SHeiner Kallweit 524125e992a4SHeiner Kallweit return rc; 524225e992a4SHeiner Kallweit } 524325e992a4SHeiner Kallweit 5244c782e204SHeiner Kallweit static void rtl_init_mac_address(struct rtl8169_private *tp) 5245c782e204SHeiner Kallweit { 5246c782e204SHeiner Kallweit struct net_device *dev = tp->dev; 5247c782e204SHeiner Kallweit u8 *mac_addr = dev->dev_addr; 5248ce37115eSHeiner Kallweit int rc; 5249c782e204SHeiner Kallweit 5250c782e204SHeiner Kallweit rc = eth_platform_get_mac_address(tp_to_dev(tp), mac_addr); 5251c782e204SHeiner Kallweit if (!rc) 5252c782e204SHeiner Kallweit goto done; 5253c782e204SHeiner Kallweit 5254c782e204SHeiner Kallweit rtl_read_mac_address(tp, mac_addr); 5255c782e204SHeiner Kallweit if (is_valid_ether_addr(mac_addr)) 5256c782e204SHeiner Kallweit goto done; 5257c782e204SHeiner Kallweit 5258ce37115eSHeiner Kallweit rtl_read_mac_from_reg(tp, mac_addr, MAC0); 5259c782e204SHeiner Kallweit if (is_valid_ether_addr(mac_addr)) 5260c782e204SHeiner Kallweit goto done; 5261c782e204SHeiner Kallweit 5262c782e204SHeiner Kallweit eth_hw_addr_random(dev); 5263c782e204SHeiner Kallweit dev_warn(tp_to_dev(tp), "can't read MAC address, setting random one\n"); 5264c782e204SHeiner Kallweit done: 5265c782e204SHeiner Kallweit rtl_rar_set(tp, mac_addr); 5266c782e204SHeiner Kallweit } 5267c782e204SHeiner Kallweit 526825e992a4SHeiner Kallweit static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 526925e992a4SHeiner Kallweit { 527025e992a4SHeiner Kallweit struct rtl8169_private *tp; 5271f1f9ca28SHeiner Kallweit int jumbo_max, region, rc; 5272f1f9ca28SHeiner Kallweit enum mac_version chipset; 527325e992a4SHeiner Kallweit struct net_device *dev; 5274f1f9ca28SHeiner Kallweit u16 xid; 527525e992a4SHeiner Kallweit 527625e992a4SHeiner Kallweit dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp)); 527725e992a4SHeiner Kallweit if (!dev) 527825e992a4SHeiner Kallweit return -ENOMEM; 527925e992a4SHeiner Kallweit 528025e992a4SHeiner Kallweit SET_NETDEV_DEV(dev, &pdev->dev); 528125e992a4SHeiner Kallweit dev->netdev_ops = &rtl_netdev_ops; 528225e992a4SHeiner Kallweit tp = netdev_priv(dev); 528325e992a4SHeiner Kallweit tp->dev = dev; 528425e992a4SHeiner Kallweit tp->pci_dev = pdev; 5285145a40e8SHeiner Kallweit tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; 52867ec3f872SHeiner Kallweit tp->eee_adv = -1; 52870360c046SHeiner Kallweit tp->ocp_base = OCP_STD_PHY_BASE; 528825e992a4SHeiner Kallweit 528925e992a4SHeiner Kallweit /* Get the *optional* external "ether_clk" used on some boards */ 529025e992a4SHeiner Kallweit rc = rtl_get_ether_clk(tp); 529125e992a4SHeiner Kallweit if (rc) 529225e992a4SHeiner Kallweit return rc; 529325e992a4SHeiner Kallweit 529425e992a4SHeiner Kallweit /* Disable ASPM completely as that cause random device stop working 529525e992a4SHeiner Kallweit * problems as well as full system hangs for some PCIe devices users. 529625e992a4SHeiner Kallweit */ 529762b1b3b3SHeiner Kallweit rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | 529862b1b3b3SHeiner Kallweit PCIE_LINK_STATE_L1); 529962b1b3b3SHeiner Kallweit tp->aspm_manageable = !rc; 530025e992a4SHeiner Kallweit 530125e992a4SHeiner Kallweit /* enable device (incl. PCI PM wakeup and hotplug setup) */ 530225e992a4SHeiner Kallweit rc = pcim_enable_device(pdev); 530325e992a4SHeiner Kallweit if (rc < 0) { 530425e992a4SHeiner Kallweit dev_err(&pdev->dev, "enable failure\n"); 530525e992a4SHeiner Kallweit return rc; 530625e992a4SHeiner Kallweit } 530725e992a4SHeiner Kallweit 530825e992a4SHeiner Kallweit if (pcim_set_mwi(pdev) < 0) 530925e992a4SHeiner Kallweit dev_info(&pdev->dev, "Mem-Wr-Inval unavailable\n"); 531025e992a4SHeiner Kallweit 531125e992a4SHeiner Kallweit /* use first MMIO region */ 531225e992a4SHeiner Kallweit region = ffs(pci_select_bars(pdev, IORESOURCE_MEM)) - 1; 531325e992a4SHeiner Kallweit if (region < 0) { 531425e992a4SHeiner Kallweit dev_err(&pdev->dev, "no MMIO resource found\n"); 531525e992a4SHeiner Kallweit return -ENODEV; 531625e992a4SHeiner Kallweit } 531725e992a4SHeiner Kallweit 531825e992a4SHeiner Kallweit /* check for weird/broken PCI region reporting */ 531925e992a4SHeiner Kallweit if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) { 532025e992a4SHeiner Kallweit dev_err(&pdev->dev, "Invalid PCI region size(s), aborting\n"); 532125e992a4SHeiner Kallweit return -ENODEV; 532225e992a4SHeiner Kallweit } 532325e992a4SHeiner Kallweit 532425e992a4SHeiner Kallweit rc = pcim_iomap_regions(pdev, BIT(region), MODULENAME); 532525e992a4SHeiner Kallweit if (rc < 0) { 532625e992a4SHeiner Kallweit dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); 532725e992a4SHeiner Kallweit return rc; 532825e992a4SHeiner Kallweit } 532925e992a4SHeiner Kallweit 533025e992a4SHeiner Kallweit tp->mmio_addr = pcim_iomap_table(pdev)[region]; 533125e992a4SHeiner Kallweit 5332f1f9ca28SHeiner Kallweit xid = (RTL_R32(tp, TxConfig) >> 20) & 0xfcf; 5333f1f9ca28SHeiner Kallweit 533425e992a4SHeiner Kallweit /* Identify chip attached to board */ 5335f1f9ca28SHeiner Kallweit chipset = rtl8169_get_mac_version(xid, tp->supports_gmii); 5336f1f9ca28SHeiner Kallweit if (chipset == RTL_GIGA_MAC_NONE) { 5337f1f9ca28SHeiner Kallweit dev_err(&pdev->dev, "unknown chip XID %03x\n", xid); 533825e992a4SHeiner Kallweit return -ENODEV; 5339f1f9ca28SHeiner Kallweit } 5340f1f9ca28SHeiner Kallweit 5341f1f9ca28SHeiner Kallweit tp->mac_version = chipset; 534225e992a4SHeiner Kallweit 5343975e8505SHeiner Kallweit tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; 534425e992a4SHeiner Kallweit 534525e992a4SHeiner Kallweit if (sizeof(dma_addr_t) > 4 && tp->mac_version >= RTL_GIGA_MAC_VER_18 && 53463c18cbe3SHeiner Kallweit !dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) 534725e992a4SHeiner Kallweit dev->features |= NETIF_F_HIGHDMA; 534825e992a4SHeiner Kallweit 534925e992a4SHeiner Kallweit rtl_init_rxcfg(tp); 535025e992a4SHeiner Kallweit 535125e992a4SHeiner Kallweit rtl8169_irq_mask_and_ack(tp); 535225e992a4SHeiner Kallweit 535325e992a4SHeiner Kallweit rtl_hw_initialize(tp); 535425e992a4SHeiner Kallweit 535525e992a4SHeiner Kallweit rtl_hw_reset(tp); 535625e992a4SHeiner Kallweit 535725e992a4SHeiner Kallweit pci_set_master(pdev); 535825e992a4SHeiner Kallweit 535925e992a4SHeiner Kallweit rc = rtl_alloc_irq(tp); 536025e992a4SHeiner Kallweit if (rc < 0) { 536125e992a4SHeiner Kallweit dev_err(&pdev->dev, "Can't allocate interrupt\n"); 536225e992a4SHeiner Kallweit return rc; 536325e992a4SHeiner Kallweit } 536425e992a4SHeiner Kallweit 536525e992a4SHeiner Kallweit mutex_init(&tp->wk.mutex); 536625e992a4SHeiner Kallweit INIT_WORK(&tp->wk.work, rtl_task); 536725e992a4SHeiner Kallweit u64_stats_init(&tp->rx_stats.syncp); 536825e992a4SHeiner Kallweit u64_stats_init(&tp->tx_stats.syncp); 536925e992a4SHeiner Kallweit 5370c782e204SHeiner Kallweit rtl_init_mac_address(tp); 537125e992a4SHeiner Kallweit 537225e992a4SHeiner Kallweit dev->ethtool_ops = &rtl8169_ethtool_ops; 537325e992a4SHeiner Kallweit 537425e992a4SHeiner Kallweit netif_napi_add(dev, &tp->napi, rtl8169_poll, NAPI_POLL_WEIGHT); 537525e992a4SHeiner Kallweit 537695099c56SHeiner Kallweit dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | 537795099c56SHeiner Kallweit NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; 5378a9b3d568SHeiner Kallweit dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; 537925e992a4SHeiner Kallweit dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; 538025e992a4SHeiner Kallweit 538125e992a4SHeiner Kallweit /* 538225e992a4SHeiner Kallweit * Pretend we are using VLANs; This bypasses a nasty bug where 538325e992a4SHeiner Kallweit * Interrupts stop flowing on high load on 8110SCd controllers. 538425e992a4SHeiner Kallweit */ 538525e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05) 538625e992a4SHeiner Kallweit /* Disallow toggling */ 538725e992a4SHeiner Kallweit dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX; 538825e992a4SHeiner Kallweit 538995099c56SHeiner Kallweit if (rtl_chip_supports_csum_v2(tp)) 539095099c56SHeiner Kallweit dev->hw_features |= NETIF_F_IPV6_CSUM; 539195099c56SHeiner Kallweit 539295099c56SHeiner Kallweit dev->features |= dev->hw_features; 539395099c56SHeiner Kallweit 539495099c56SHeiner Kallweit /* There has been a number of reports that using SG/TSO results in 539595099c56SHeiner Kallweit * tx timeouts. However for a lot of people SG/TSO works fine. 539695099c56SHeiner Kallweit * Therefore disable both features by default, but allow users to 539795099c56SHeiner Kallweit * enable them. Use at own risk! 539895099c56SHeiner Kallweit */ 53990170d594SHeiner Kallweit if (rtl_chip_supports_csum_v2(tp)) { 540095099c56SHeiner Kallweit dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; 54010170d594SHeiner Kallweit dev->gso_max_size = RTL_GSO_MAX_SIZE_V2; 54020170d594SHeiner Kallweit dev->gso_max_segs = RTL_GSO_MAX_SEGS_V2; 54030170d594SHeiner Kallweit } else { 540495099c56SHeiner Kallweit dev->hw_features |= NETIF_F_SG | NETIF_F_TSO; 54050170d594SHeiner Kallweit dev->gso_max_size = RTL_GSO_MAX_SIZE_V1; 54060170d594SHeiner Kallweit dev->gso_max_segs = RTL_GSO_MAX_SEGS_V1; 54070170d594SHeiner Kallweit } 540825e992a4SHeiner Kallweit 540925e992a4SHeiner Kallweit dev->hw_features |= NETIF_F_RXALL; 541025e992a4SHeiner Kallweit dev->hw_features |= NETIF_F_RXFCS; 541125e992a4SHeiner Kallweit 5412145192f8SHeiner Kallweit /* configure chip for default features */ 5413145192f8SHeiner Kallweit rtl8169_set_features(dev, dev->features); 5414145192f8SHeiner Kallweit 541525e992a4SHeiner Kallweit jumbo_max = rtl_jumbo_max(tp); 5416a8ec173aSHeiner Kallweit if (jumbo_max) 541725e992a4SHeiner Kallweit dev->max_mtu = jumbo_max; 541825e992a4SHeiner Kallweit 5419ec9a4088SHeiner Kallweit rtl_set_irq_mask(tp); 54209fa0a8e1SHeiner Kallweit 542125e992a4SHeiner Kallweit tp->fw_name = rtl_chip_infos[chipset].fw_name; 542225e992a4SHeiner Kallweit 542325e992a4SHeiner Kallweit tp->counters = dmam_alloc_coherent (&pdev->dev, sizeof(*tp->counters), 542425e992a4SHeiner Kallweit &tp->counters_phys_addr, 542525e992a4SHeiner Kallweit GFP_KERNEL); 542625e992a4SHeiner Kallweit if (!tp->counters) 542725e992a4SHeiner Kallweit return -ENOMEM; 542825e992a4SHeiner Kallweit 542925e992a4SHeiner Kallweit pci_set_drvdata(pdev, dev); 543025e992a4SHeiner Kallweit 543125e992a4SHeiner Kallweit rc = r8169_mdio_register(tp); 543225e992a4SHeiner Kallweit if (rc) 543325e992a4SHeiner Kallweit return rc; 543425e992a4SHeiner Kallweit 543525e992a4SHeiner Kallweit /* chip gets powered up in rtl_open() */ 543625e992a4SHeiner Kallweit rtl_pll_power_down(tp); 543725e992a4SHeiner Kallweit 543825e992a4SHeiner Kallweit rc = register_netdev(dev); 543925e992a4SHeiner Kallweit if (rc) 54400785dad4SHeiner Kallweit return rc; 544125e992a4SHeiner Kallweit 544293882c6fSHeiner Kallweit netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n", 5443f1f9ca28SHeiner Kallweit rtl_chip_infos[chipset].name, dev->dev_addr, xid, 544425e992a4SHeiner Kallweit pci_irq_vector(pdev, 0)); 544525e992a4SHeiner Kallweit 5446a8ec173aSHeiner Kallweit if (jumbo_max) 544793882c6fSHeiner Kallweit netdev_info(dev, "jumbo features [frames: %d bytes, tx checksumming: %s]\n", 544825e992a4SHeiner Kallweit jumbo_max, tp->mac_version <= RTL_GIGA_MAC_VER_06 ? 544925e992a4SHeiner Kallweit "ok" : "ko"); 545025e992a4SHeiner Kallweit 545125e992a4SHeiner Kallweit if (r8168_check_dash(tp)) 545225e992a4SHeiner Kallweit rtl8168_driver_start(tp); 545325e992a4SHeiner Kallweit 545425e992a4SHeiner Kallweit if (pci_dev_run_wake(pdev)) 545525e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev); 545625e992a4SHeiner Kallweit 545725e992a4SHeiner Kallweit return 0; 545825e992a4SHeiner Kallweit } 545925e992a4SHeiner Kallweit 546025e992a4SHeiner Kallweit static struct pci_driver rtl8169_pci_driver = { 546125e992a4SHeiner Kallweit .name = MODULENAME, 546225e992a4SHeiner Kallweit .id_table = rtl8169_pci_tbl, 546325e992a4SHeiner Kallweit .probe = rtl_init_one, 546425e992a4SHeiner Kallweit .remove = rtl_remove_one, 546525e992a4SHeiner Kallweit .shutdown = rtl_shutdown, 546625e992a4SHeiner Kallweit .driver.pm = RTL8169_PM_OPS, 546725e992a4SHeiner Kallweit }; 546825e992a4SHeiner Kallweit 546925e992a4SHeiner Kallweit module_pci_driver(rtl8169_pci_driver); 5470