125e992a4SHeiner Kallweit // SPDX-License-Identifier: GPL-2.0-only
225e992a4SHeiner Kallweit /*
325e992a4SHeiner Kallweit * r8169.c: RealTek 8169/8168/8101 ethernet driver.
425e992a4SHeiner Kallweit *
525e992a4SHeiner Kallweit * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
625e992a4SHeiner Kallweit * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
725e992a4SHeiner Kallweit * Copyright (c) a lot of people too. Please respect their work.
825e992a4SHeiner Kallweit *
925e992a4SHeiner Kallweit * See MAINTAINERS file for support contact information.
1025e992a4SHeiner Kallweit */
1125e992a4SHeiner Kallweit
1225e992a4SHeiner Kallweit #include <linux/module.h>
1325e992a4SHeiner Kallweit #include <linux/pci.h>
1425e992a4SHeiner Kallweit #include <linux/netdevice.h>
1525e992a4SHeiner Kallweit #include <linux/etherdevice.h>
1625e992a4SHeiner Kallweit #include <linux/clk.h>
1725e992a4SHeiner Kallweit #include <linux/delay.h>
1825e992a4SHeiner Kallweit #include <linux/ethtool.h>
1925e992a4SHeiner Kallweit #include <linux/phy.h>
2025e992a4SHeiner Kallweit #include <linux/if_vlan.h>
2125e992a4SHeiner Kallweit #include <linux/in.h>
2225e992a4SHeiner Kallweit #include <linux/io.h>
2325e992a4SHeiner Kallweit #include <linux/ip.h>
2425e992a4SHeiner Kallweit #include <linux/tcp.h>
2525e992a4SHeiner Kallweit #include <linux/interrupt.h>
2625e992a4SHeiner Kallweit #include <linux/dma-mapping.h>
2725e992a4SHeiner Kallweit #include <linux/pm_runtime.h>
286cf96dd4SHeiner Kallweit #include <linux/bitfield.h>
2925e992a4SHeiner Kallweit #include <linux/prefetch.h>
3025e992a4SHeiner Kallweit #include <linux/ipv6.h>
31ae1e82c6SHeiner Kallweit #include <asm/unaligned.h>
3225e992a4SHeiner Kallweit #include <net/ip6_checksum.h>
338624e9bbSHeiner Kallweit #include <net/netdev_queues.h>
3425e992a4SHeiner Kallweit
352992bdfaSHeiner Kallweit #include "r8169.h"
368197f9d2SHeiner Kallweit #include "r8169_firmware.h"
378197f9d2SHeiner Kallweit
3825e992a4SHeiner Kallweit #define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw"
3925e992a4SHeiner Kallweit #define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw"
4025e992a4SHeiner Kallweit #define FIRMWARE_8168E_1 "rtl_nic/rtl8168e-1.fw"
4125e992a4SHeiner Kallweit #define FIRMWARE_8168E_2 "rtl_nic/rtl8168e-2.fw"
4225e992a4SHeiner Kallweit #define FIRMWARE_8168E_3 "rtl_nic/rtl8168e-3.fw"
4325e992a4SHeiner Kallweit #define FIRMWARE_8168F_1 "rtl_nic/rtl8168f-1.fw"
4425e992a4SHeiner Kallweit #define FIRMWARE_8168F_2 "rtl_nic/rtl8168f-2.fw"
4525e992a4SHeiner Kallweit #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw"
4625e992a4SHeiner Kallweit #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw"
4725e992a4SHeiner Kallweit #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw"
4825e992a4SHeiner Kallweit #define FIRMWARE_8411_2 "rtl_nic/rtl8411-2.fw"
4925e992a4SHeiner Kallweit #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw"
5025e992a4SHeiner Kallweit #define FIRMWARE_8106E_2 "rtl_nic/rtl8106e-2.fw"
5125e992a4SHeiner Kallweit #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw"
5225e992a4SHeiner Kallweit #define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw"
5325e992a4SHeiner Kallweit #define FIRMWARE_8168H_2 "rtl_nic/rtl8168h-2.fw"
54229c1e0dSHeiner Kallweit #define FIRMWARE_8168FP_3 "rtl_nic/rtl8168fp-3.fw"
5525e992a4SHeiner Kallweit #define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
5602bf642bSHeiner Kallweit #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
570439297bSHeiner Kallweit #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
5825e992a4SHeiner Kallweit
5925e992a4SHeiner Kallweit /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
6025e992a4SHeiner Kallweit The RTL chips use a 64 element hash table based on the Ethernet CRC. */
6181cd17a4SHeiner Kallweit #define MC_FILTER_LIMIT 32
6225e992a4SHeiner Kallweit
6325e992a4SHeiner Kallweit #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */
6425e992a4SHeiner Kallweit #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
6525e992a4SHeiner Kallweit
6625e992a4SHeiner Kallweit #define R8169_REGS_SIZE 256
6725e992a4SHeiner Kallweit #define R8169_RX_BUF_SIZE (SZ_16K - 1)
68f06059c2SHeiner Kallweit #define NUM_TX_DESC 256 /* Number of Tx descriptor registers */
69ed22a8ffSHeiner Kallweit #define NUM_RX_DESC 256 /* Number of Rx descriptor registers */
7025e992a4SHeiner Kallweit #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
7125e992a4SHeiner Kallweit #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
728624e9bbSHeiner Kallweit #define R8169_TX_STOP_THRS (MAX_SKB_FRAGS + 1)
738624e9bbSHeiner Kallweit #define R8169_TX_START_THRS (2 * R8169_TX_STOP_THRS)
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" },
106e66d6586SHeiner Kallweit [RTL_GIGA_MAC_VER_10] = {"RTL8101e/RTL8100e" },
10725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_11] = {"RTL8168b/8111b" },
108cdafdc29SHeiner Kallweit [RTL_GIGA_MAC_VER_14] = {"RTL8401" },
10925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b" },
11025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp" },
11125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_19] = {"RTL8168c/8111c" },
11225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_20] = {"RTL8168c/8111c" },
11325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_21] = {"RTL8168c/8111c" },
11425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_22] = {"RTL8168c/8111c" },
11525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_23] = {"RTL8168cp/8111cp" },
11625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_24] = {"RTL8168cp/8111cp" },
11725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_25] = {"RTL8168d/8111d", FIRMWARE_8168D_1},
11825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_26] = {"RTL8168d/8111d", FIRMWARE_8168D_2},
11925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_28] = {"RTL8168dp/8111dp" },
12025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_29] = {"RTL8105e", FIRMWARE_8105E_1},
12125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_30] = {"RTL8105e", FIRMWARE_8105E_1},
12225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_31] = {"RTL8168dp/8111dp" },
12325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_32] = {"RTL8168e/8111e", FIRMWARE_8168E_1},
12425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_33] = {"RTL8168e/8111e", FIRMWARE_8168E_2},
12525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_34] = {"RTL8168evl/8111evl", FIRMWARE_8168E_3},
12625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_35] = {"RTL8168f/8111f", FIRMWARE_8168F_1},
12725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_36] = {"RTL8168f/8111f", FIRMWARE_8168F_2},
12825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_37] = {"RTL8402", FIRMWARE_8402_1 },
12925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_38] = {"RTL8411", FIRMWARE_8411_1 },
13025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_39] = {"RTL8106e", FIRMWARE_8106E_1},
13125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_40] = {"RTL8168g/8111g", FIRMWARE_8168G_2},
1329e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_42] = {"RTL8168gu/8111gu", FIRMWARE_8168G_3},
1339e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_43] = {"RTL8106eus", FIRMWARE_8106E_2},
1349e0773c3SHeiner Kallweit [RTL_GIGA_MAC_VER_44] = {"RTL8411b", FIRMWARE_8411_2 },
13525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_46] = {"RTL8168h/8111h", FIRMWARE_8168H_2},
13625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_48] = {"RTL8107e", FIRMWARE_8107E_2},
13725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep" },
138229c1e0dSHeiner Kallweit [RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117", FIRMWARE_8168FP_3},
139e6d6ca6eSKai-Heng Feng [RTL_GIGA_MAC_VER_53] = {"RTL8168fp/RTL8117", },
1404640338cSHeiner Kallweit [RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
1410439297bSHeiner Kallweit /* reserve 62 for CFG_METHOD_4 in the vendor driver */
1420439297bSHeiner Kallweit [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
14325e992a4SHeiner Kallweit };
14425e992a4SHeiner Kallweit
14525e992a4SHeiner Kallweit static const struct pci_device_id rtl8169_pci_tbl[] = {
146145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x2502) },
147145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x2600) },
148145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8129) },
149145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_NO_GBIT },
150145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8161) },
15172f898caSJanghyub Seo { PCI_VDEVICE(REALTEK, 0x8162) },
152145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8167) },
153145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8168) },
154145a40e8SHeiner Kallweit { PCI_VDEVICE(NCUBE, 0x8168) },
155145a40e8SHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8169) },
15625e992a4SHeiner Kallweit { PCI_VENDOR_ID_DLINK, 0x4300,
157145a40e8SHeiner Kallweit PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0 },
1589d9f3fbaSHeiner Kallweit { PCI_VDEVICE(DLINK, 0x4300) },
1599d9f3fbaSHeiner Kallweit { PCI_VDEVICE(DLINK, 0x4302) },
1609d9f3fbaSHeiner Kallweit { PCI_VDEVICE(AT, 0xc107) },
1619d9f3fbaSHeiner Kallweit { PCI_VDEVICE(USR, 0x0116) },
1629d9f3fbaSHeiner Kallweit { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
1639d9f3fbaSHeiner Kallweit { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
164f1bce4adSHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x8125) },
165f1bce4adSHeiner Kallweit { PCI_VDEVICE(REALTEK, 0x3000) },
16625e992a4SHeiner Kallweit {}
16725e992a4SHeiner Kallweit };
16825e992a4SHeiner Kallweit
16925e992a4SHeiner Kallweit MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
17025e992a4SHeiner Kallweit
17125e992a4SHeiner Kallweit enum rtl_registers {
17225e992a4SHeiner Kallweit MAC0 = 0, /* Ethernet hardware address. */
17325e992a4SHeiner Kallweit MAC4 = 4,
17425e992a4SHeiner Kallweit MAR0 = 8, /* Multicast filter. */
17525e992a4SHeiner Kallweit CounterAddrLow = 0x10,
17625e992a4SHeiner Kallweit CounterAddrHigh = 0x14,
17725e992a4SHeiner Kallweit TxDescStartAddrLow = 0x20,
17825e992a4SHeiner Kallweit TxDescStartAddrHigh = 0x24,
17925e992a4SHeiner Kallweit TxHDescStartAddrLow = 0x28,
18025e992a4SHeiner Kallweit TxHDescStartAddrHigh = 0x2c,
18125e992a4SHeiner Kallweit FLASH = 0x30,
18225e992a4SHeiner Kallweit ERSR = 0x36,
18325e992a4SHeiner Kallweit ChipCmd = 0x37,
18425e992a4SHeiner Kallweit TxPoll = 0x38,
18525e992a4SHeiner Kallweit IntrMask = 0x3c,
18625e992a4SHeiner Kallweit IntrStatus = 0x3e,
18725e992a4SHeiner Kallweit
18825e992a4SHeiner Kallweit TxConfig = 0x40,
18925e992a4SHeiner Kallweit #define TXCFG_AUTO_FIFO (1 << 7) /* 8111e-vl */
19025e992a4SHeiner Kallweit #define TXCFG_EMPTY (1 << 11) /* 8111e-vl */
19125e992a4SHeiner Kallweit
19225e992a4SHeiner Kallweit RxConfig = 0x44,
19325e992a4SHeiner Kallweit #define RX128_INT_EN (1 << 15) /* 8111c and later */
19425e992a4SHeiner Kallweit #define RX_MULTI_EN (1 << 14) /* 8111c only */
19525e992a4SHeiner Kallweit #define RXCFG_FIFO_SHIFT 13
19625e992a4SHeiner Kallweit /* No threshold before first PCI xfer */
19725e992a4SHeiner Kallweit #define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT)
19825e992a4SHeiner Kallweit #define RX_EARLY_OFF (1 << 11)
1992e04cfddSChunHao Lin #define RX_PAUSE_SLOT_ON (1 << 11) /* 8125b and later */
20025e992a4SHeiner Kallweit #define RXCFG_DMA_SHIFT 8
20125e992a4SHeiner Kallweit /* Unlimited maximum PCI burst. */
20225e992a4SHeiner Kallweit #define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT)
20325e992a4SHeiner Kallweit
20425e992a4SHeiner Kallweit Cfg9346 = 0x50,
20525e992a4SHeiner Kallweit Config0 = 0x51,
20625e992a4SHeiner Kallweit Config1 = 0x52,
20725e992a4SHeiner Kallweit Config2 = 0x53,
20825e992a4SHeiner Kallweit #define PME_SIGNAL (1 << 5) /* 8168c and later */
20925e992a4SHeiner Kallweit
21025e992a4SHeiner Kallweit Config3 = 0x54,
21125e992a4SHeiner Kallweit Config4 = 0x55,
21225e992a4SHeiner Kallweit Config5 = 0x56,
21325e992a4SHeiner Kallweit PHYAR = 0x60,
21425e992a4SHeiner Kallweit PHYstatus = 0x6c,
21525e992a4SHeiner Kallweit RxMaxSize = 0xda,
21625e992a4SHeiner Kallweit CPlusCmd = 0xe0,
21725e992a4SHeiner Kallweit IntrMitigate = 0xe2,
21825e992a4SHeiner Kallweit
2196cf96dd4SHeiner Kallweit #define RTL_COALESCE_TX_USECS GENMASK(15, 12)
2206cf96dd4SHeiner Kallweit #define RTL_COALESCE_TX_FRAMES GENMASK(11, 8)
2216cf96dd4SHeiner Kallweit #define RTL_COALESCE_RX_USECS GENMASK(7, 4)
2226cf96dd4SHeiner Kallweit #define RTL_COALESCE_RX_FRAMES GENMASK(3, 0)
2236cf96dd4SHeiner Kallweit
2242b3e48b6SHeiner Kallweit #define RTL_COALESCE_T_MAX 0x0fU
2252b3e48b6SHeiner Kallweit #define RTL_COALESCE_FRAME_MAX (RTL_COALESCE_T_MAX * 4)
22625e992a4SHeiner Kallweit
22725e992a4SHeiner Kallweit RxDescAddrLow = 0xe4,
22825e992a4SHeiner Kallweit RxDescAddrHigh = 0xe8,
22925e992a4SHeiner Kallweit EarlyTxThres = 0xec, /* 8169. Unit of 32 bytes. */
23025e992a4SHeiner Kallweit
23125e992a4SHeiner Kallweit #define NoEarlyTx 0x3f /* Max value : no early transmit. */
23225e992a4SHeiner Kallweit
23325e992a4SHeiner Kallweit MaxTxPacketSize = 0xec, /* 8101/8168. Unit of 128 bytes. */
23425e992a4SHeiner Kallweit
23525e992a4SHeiner Kallweit #define TxPacketMax (8064 >> 7)
23625e992a4SHeiner Kallweit #define EarlySize 0x27
23725e992a4SHeiner Kallweit
23825e992a4SHeiner Kallweit FuncEvent = 0xf0,
23925e992a4SHeiner Kallweit FuncEventMask = 0xf4,
24025e992a4SHeiner Kallweit FuncPresetState = 0xf8,
24125e992a4SHeiner Kallweit IBCR0 = 0xf8,
24225e992a4SHeiner Kallweit IBCR2 = 0xf9,
24325e992a4SHeiner Kallweit IBIMR0 = 0xfa,
24425e992a4SHeiner Kallweit IBISR0 = 0xfb,
24525e992a4SHeiner Kallweit FuncForceEvent = 0xfc,
24625e992a4SHeiner Kallweit };
24725e992a4SHeiner Kallweit
24825e992a4SHeiner Kallweit enum rtl8168_8101_registers {
24925e992a4SHeiner Kallweit CSIDR = 0x64,
25025e992a4SHeiner Kallweit CSIAR = 0x68,
25125e992a4SHeiner Kallweit #define CSIAR_FLAG 0x80000000
25225e992a4SHeiner Kallweit #define CSIAR_WRITE_CMD 0x80000000
25325e992a4SHeiner Kallweit #define CSIAR_BYTE_ENABLE 0x0000f000
25425e992a4SHeiner Kallweit #define CSIAR_ADDR_MASK 0x00000fff
25525e992a4SHeiner Kallweit PMCH = 0x6f,
256128735a1SHeiner Kallweit #define D3COLD_NO_PLL_DOWN BIT(7)
257128735a1SHeiner Kallweit #define D3HOT_NO_PLL_DOWN BIT(6)
258128735a1SHeiner Kallweit #define D3_NO_PLL_DOWN (BIT(7) | BIT(6))
25925e992a4SHeiner Kallweit EPHYAR = 0x80,
26025e992a4SHeiner Kallweit #define EPHYAR_FLAG 0x80000000
26125e992a4SHeiner Kallweit #define EPHYAR_WRITE_CMD 0x80000000
26225e992a4SHeiner Kallweit #define EPHYAR_REG_MASK 0x1f
26325e992a4SHeiner Kallweit #define EPHYAR_REG_SHIFT 16
26425e992a4SHeiner Kallweit #define EPHYAR_DATA_MASK 0xffff
26525e992a4SHeiner Kallweit DLLPR = 0xd0,
26625e992a4SHeiner Kallweit #define PFM_EN (1 << 6)
26725e992a4SHeiner Kallweit #define TX_10M_PS_EN (1 << 7)
26825e992a4SHeiner Kallweit DBG_REG = 0xd1,
26925e992a4SHeiner Kallweit #define FIX_NAK_1 (1 << 4)
27025e992a4SHeiner Kallweit #define FIX_NAK_2 (1 << 3)
27125e992a4SHeiner Kallweit TWSI = 0xd2,
27225e992a4SHeiner Kallweit MCU = 0xd3,
27325e992a4SHeiner Kallweit #define NOW_IS_OOB (1 << 7)
27425e992a4SHeiner Kallweit #define TX_EMPTY (1 << 5)
27525e992a4SHeiner Kallweit #define RX_EMPTY (1 << 4)
27625e992a4SHeiner Kallweit #define RXTX_EMPTY (TX_EMPTY | RX_EMPTY)
27725e992a4SHeiner Kallweit #define EN_NDP (1 << 3)
27825e992a4SHeiner Kallweit #define EN_OOB_RESET (1 << 2)
27925e992a4SHeiner Kallweit #define LINK_LIST_RDY (1 << 1)
28025e992a4SHeiner Kallweit EFUSEAR = 0xdc,
28125e992a4SHeiner Kallweit #define EFUSEAR_FLAG 0x80000000
28225e992a4SHeiner Kallweit #define EFUSEAR_WRITE_CMD 0x80000000
28325e992a4SHeiner Kallweit #define EFUSEAR_READ_CMD 0x00000000
28425e992a4SHeiner Kallweit #define EFUSEAR_REG_MASK 0x03ff
28525e992a4SHeiner Kallweit #define EFUSEAR_REG_SHIFT 8
28625e992a4SHeiner Kallweit #define EFUSEAR_DATA_MASK 0xff
28725e992a4SHeiner Kallweit MISC_1 = 0xf2,
28825e992a4SHeiner Kallweit #define PFM_D3COLD_EN (1 << 6)
28925e992a4SHeiner Kallweit };
29025e992a4SHeiner Kallweit
29125e992a4SHeiner Kallweit enum rtl8168_registers {
29225e992a4SHeiner Kallweit LED_FREQ = 0x1a,
29325e992a4SHeiner Kallweit EEE_LED = 0x1b,
29425e992a4SHeiner Kallweit ERIDR = 0x70,
29525e992a4SHeiner Kallweit ERIAR = 0x74,
29625e992a4SHeiner Kallweit #define ERIAR_FLAG 0x80000000
29725e992a4SHeiner Kallweit #define ERIAR_WRITE_CMD 0x80000000
29825e992a4SHeiner Kallweit #define ERIAR_READ_CMD 0x00000000
29925e992a4SHeiner Kallweit #define ERIAR_ADDR_BYTE_ALIGN 4
30025e992a4SHeiner Kallweit #define ERIAR_TYPE_SHIFT 16
30125e992a4SHeiner Kallweit #define ERIAR_EXGMAC (0x00 << ERIAR_TYPE_SHIFT)
30225e992a4SHeiner Kallweit #define ERIAR_MSIX (0x01 << ERIAR_TYPE_SHIFT)
30325e992a4SHeiner Kallweit #define ERIAR_ASF (0x02 << ERIAR_TYPE_SHIFT)
30425e992a4SHeiner Kallweit #define ERIAR_OOB (0x02 << ERIAR_TYPE_SHIFT)
30525e992a4SHeiner Kallweit #define ERIAR_MASK_SHIFT 12
30625e992a4SHeiner Kallweit #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT)
30725e992a4SHeiner Kallweit #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT)
30825e992a4SHeiner Kallweit #define ERIAR_MASK_0100 (0x4 << ERIAR_MASK_SHIFT)
30925e992a4SHeiner Kallweit #define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT)
31025e992a4SHeiner Kallweit #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT)
31125e992a4SHeiner Kallweit EPHY_RXER_NUM = 0x7c,
31225e992a4SHeiner Kallweit OCPDR = 0xb0, /* OCP GPHY access */
31325e992a4SHeiner Kallweit #define OCPDR_WRITE_CMD 0x80000000
31425e992a4SHeiner Kallweit #define OCPDR_READ_CMD 0x00000000
31525e992a4SHeiner Kallweit #define OCPDR_REG_MASK 0x7f
31625e992a4SHeiner Kallweit #define OCPDR_GPHY_REG_SHIFT 16
31725e992a4SHeiner Kallweit #define OCPDR_DATA_MASK 0xffff
31825e992a4SHeiner Kallweit OCPAR = 0xb4,
31925e992a4SHeiner Kallweit #define OCPAR_FLAG 0x80000000
32025e992a4SHeiner Kallweit #define OCPAR_GPHY_WRITE_CMD 0x8000f060
32125e992a4SHeiner Kallweit #define OCPAR_GPHY_READ_CMD 0x0000f060
32225e992a4SHeiner Kallweit GPHY_OCP = 0xb8,
32325e992a4SHeiner Kallweit RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */
32425e992a4SHeiner Kallweit MISC = 0xf0, /* 8168e only. */
32525e992a4SHeiner Kallweit #define TXPLA_RST (1 << 29)
32625e992a4SHeiner Kallweit #define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */
32725e992a4SHeiner Kallweit #define PWM_EN (1 << 22)
32825e992a4SHeiner Kallweit #define RXDV_GATED_EN (1 << 19)
32925e992a4SHeiner Kallweit #define EARLY_TALLY_EN (1 << 16)
33025e992a4SHeiner Kallweit };
33125e992a4SHeiner Kallweit
332f1bce4adSHeiner Kallweit enum rtl8125_registers {
333f1bce4adSHeiner Kallweit IntrMask_8125 = 0x38,
334f1bce4adSHeiner Kallweit IntrStatus_8125 = 0x3c,
335f1bce4adSHeiner Kallweit TxPoll_8125 = 0x90,
336f1bce4adSHeiner Kallweit MAC0_BKP = 0x19e0,
3370439297bSHeiner Kallweit EEE_TXIDLE_TIMER_8125 = 0x6048,
338f1bce4adSHeiner Kallweit };
339f1bce4adSHeiner Kallweit
340f1bce4adSHeiner Kallweit #define RX_VLAN_INNER_8125 BIT(22)
341f1bce4adSHeiner Kallweit #define RX_VLAN_OUTER_8125 BIT(23)
342f1bce4adSHeiner Kallweit #define RX_VLAN_8125 (RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125)
343f1bce4adSHeiner Kallweit
344f1bce4adSHeiner Kallweit #define RX_FETCH_DFLT_8125 (8 << 27)
345f1bce4adSHeiner Kallweit
34625e992a4SHeiner Kallweit enum rtl_register_content {
34725e992a4SHeiner Kallweit /* InterruptStatusBits */
34825e992a4SHeiner Kallweit SYSErr = 0x8000,
34925e992a4SHeiner Kallweit PCSTimeout = 0x4000,
35025e992a4SHeiner Kallweit SWInt = 0x0100,
35125e992a4SHeiner Kallweit TxDescUnavail = 0x0080,
35225e992a4SHeiner Kallweit RxFIFOOver = 0x0040,
35325e992a4SHeiner Kallweit LinkChg = 0x0020,
35425e992a4SHeiner Kallweit RxOverflow = 0x0010,
35525e992a4SHeiner Kallweit TxErr = 0x0008,
35625e992a4SHeiner Kallweit TxOK = 0x0004,
35725e992a4SHeiner Kallweit RxErr = 0x0002,
35825e992a4SHeiner Kallweit RxOK = 0x0001,
35925e992a4SHeiner Kallweit
36025e992a4SHeiner Kallweit /* RxStatusDesc */
36125e992a4SHeiner Kallweit RxRWT = (1 << 22),
36225e992a4SHeiner Kallweit RxRES = (1 << 21),
36325e992a4SHeiner Kallweit RxRUNT = (1 << 20),
36425e992a4SHeiner Kallweit RxCRC = (1 << 19),
36525e992a4SHeiner Kallweit
36625e992a4SHeiner Kallweit /* ChipCmdBits */
36725e992a4SHeiner Kallweit StopReq = 0x80,
36825e992a4SHeiner Kallweit CmdReset = 0x10,
36925e992a4SHeiner Kallweit CmdRxEnb = 0x08,
37025e992a4SHeiner Kallweit CmdTxEnb = 0x04,
37125e992a4SHeiner Kallweit RxBufEmpty = 0x01,
37225e992a4SHeiner Kallweit
37325e992a4SHeiner Kallweit /* TXPoll register p.5 */
37425e992a4SHeiner Kallweit HPQ = 0x80, /* Poll cmd on the high prio queue */
37525e992a4SHeiner Kallweit NPQ = 0x40, /* Poll cmd on the low prio queue */
37625e992a4SHeiner Kallweit FSWInt = 0x01, /* Forced software interrupt */
37725e992a4SHeiner Kallweit
37825e992a4SHeiner Kallweit /* Cfg9346Bits */
37925e992a4SHeiner Kallweit Cfg9346_Lock = 0x00,
38025e992a4SHeiner Kallweit Cfg9346_Unlock = 0xc0,
38125e992a4SHeiner Kallweit
38225e992a4SHeiner Kallweit /* rx_mode_bits */
38325e992a4SHeiner Kallweit AcceptErr = 0x20,
38425e992a4SHeiner Kallweit AcceptRunt = 0x10,
38510478283SHeiner Kallweit #define RX_CONFIG_ACCEPT_ERR_MASK 0x30
38625e992a4SHeiner Kallweit AcceptBroadcast = 0x08,
38725e992a4SHeiner Kallweit AcceptMulticast = 0x04,
38825e992a4SHeiner Kallweit AcceptMyPhys = 0x02,
38925e992a4SHeiner Kallweit AcceptAllPhys = 0x01,
39010478283SHeiner Kallweit #define RX_CONFIG_ACCEPT_OK_MASK 0x0f
39125e992a4SHeiner Kallweit #define RX_CONFIG_ACCEPT_MASK 0x3f
39225e992a4SHeiner Kallweit
39325e992a4SHeiner Kallweit /* TxConfigBits */
39425e992a4SHeiner Kallweit TxInterFrameGapShift = 24,
39525e992a4SHeiner Kallweit TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
39625e992a4SHeiner Kallweit
39725e992a4SHeiner Kallweit /* Config1 register p.24 */
39825e992a4SHeiner Kallweit LEDS1 = (1 << 7),
39925e992a4SHeiner Kallweit LEDS0 = (1 << 6),
40025e992a4SHeiner Kallweit Speed_down = (1 << 4),
40125e992a4SHeiner Kallweit MEMMAP = (1 << 3),
40225e992a4SHeiner Kallweit IOMAP = (1 << 2),
40325e992a4SHeiner Kallweit VPD = (1 << 1),
40425e992a4SHeiner Kallweit PMEnable = (1 << 0), /* Power Management Enable */
40525e992a4SHeiner Kallweit
40625e992a4SHeiner Kallweit /* Config2 register p. 25 */
40725e992a4SHeiner Kallweit ClkReqEn = (1 << 7), /* Clock Request Enable */
40825e992a4SHeiner Kallweit MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */
40925e992a4SHeiner Kallweit PCI_Clock_66MHz = 0x01,
41025e992a4SHeiner Kallweit PCI_Clock_33MHz = 0x00,
41125e992a4SHeiner Kallweit
41225e992a4SHeiner Kallweit /* Config3 register p.25 */
41325e992a4SHeiner Kallweit MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
41425e992a4SHeiner Kallweit LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
41525e992a4SHeiner Kallweit Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */
41625e992a4SHeiner Kallweit Rdy_to_L23 = (1 << 1), /* L23 Enable */
41725e992a4SHeiner Kallweit Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */
41825e992a4SHeiner Kallweit
41925e992a4SHeiner Kallweit /* Config4 register */
42025e992a4SHeiner Kallweit Jumbo_En1 = (1 << 1), /* 8168 only. Reserved in the 8168b */
42125e992a4SHeiner Kallweit
42225e992a4SHeiner Kallweit /* Config5 register p.27 */
42325e992a4SHeiner Kallweit BWF = (1 << 6), /* Accept Broadcast wakeup frame */
42425e992a4SHeiner Kallweit MWF = (1 << 5), /* Accept Multicast wakeup frame */
42525e992a4SHeiner Kallweit UWF = (1 << 4), /* Accept Unicast wakeup frame */
42625e992a4SHeiner Kallweit Spi_en = (1 << 3),
42725e992a4SHeiner Kallweit LanWake = (1 << 1), /* LanWake enable/disable */
42825e992a4SHeiner Kallweit PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */
42925e992a4SHeiner Kallweit ASPM_en = (1 << 0), /* ASPM enable */
43025e992a4SHeiner Kallweit
43125e992a4SHeiner Kallweit /* CPlusCmd p.31 */
43225e992a4SHeiner Kallweit EnableBist = (1 << 15), // 8168 8101
43325e992a4SHeiner Kallweit Mac_dbgo_oe = (1 << 14), // 8168 8101
43409e65335SHeiner Kallweit EnAnaPLL = (1 << 14), // 8169
43525e992a4SHeiner Kallweit Normal_mode = (1 << 13), // unused
43625e992a4SHeiner Kallweit Force_half_dup = (1 << 12), // 8168 8101
43725e992a4SHeiner Kallweit Force_rxflow_en = (1 << 11), // 8168 8101
43825e992a4SHeiner Kallweit Force_txflow_en = (1 << 10), // 8168 8101
43925e992a4SHeiner Kallweit Cxpl_dbg_sel = (1 << 9), // 8168 8101
44025e992a4SHeiner Kallweit ASF = (1 << 8), // 8168 8101
44125e992a4SHeiner Kallweit PktCntrDisable = (1 << 7), // 8168 8101
44225e992a4SHeiner Kallweit Mac_dbgo_sel = 0x001c, // 8168
44325e992a4SHeiner Kallweit RxVlan = (1 << 6),
44425e992a4SHeiner Kallweit RxChkSum = (1 << 5),
44525e992a4SHeiner Kallweit PCIDAC = (1 << 4),
44625e992a4SHeiner Kallweit PCIMulRW = (1 << 3),
44725e992a4SHeiner Kallweit #define INTT_MASK GENMASK(1, 0)
448bc73241eSHeiner Kallweit #define CPCMD_MASK (Normal_mode | RxVlan | RxChkSum | INTT_MASK)
44925e992a4SHeiner Kallweit
45025e992a4SHeiner Kallweit /* rtl8169_PHYstatus */
45125e992a4SHeiner Kallweit TBI_Enable = 0x80,
45225e992a4SHeiner Kallweit TxFlowCtrl = 0x40,
45325e992a4SHeiner Kallweit RxFlowCtrl = 0x20,
45425e992a4SHeiner Kallweit _1000bpsF = 0x10,
45525e992a4SHeiner Kallweit _100bps = 0x08,
45625e992a4SHeiner Kallweit _10bps = 0x04,
45725e992a4SHeiner Kallweit LinkStatus = 0x02,
45825e992a4SHeiner Kallweit FullDup = 0x01,
45925e992a4SHeiner Kallweit
46025e992a4SHeiner Kallweit /* ResetCounterCommand */
46125e992a4SHeiner Kallweit CounterReset = 0x1,
46225e992a4SHeiner Kallweit
46325e992a4SHeiner Kallweit /* DumpCounterCommand */
46425e992a4SHeiner Kallweit CounterDump = 0x8,
46525e992a4SHeiner Kallweit
46625e992a4SHeiner Kallweit /* magic enable v2 */
46725e992a4SHeiner Kallweit MagicPacket_v2 = (1 << 16), /* Wake up when receives a Magic Packet */
46825e992a4SHeiner Kallweit };
46925e992a4SHeiner Kallweit
47025e992a4SHeiner Kallweit enum rtl_desc_bit {
47125e992a4SHeiner Kallweit /* First doubleword. */
47225e992a4SHeiner Kallweit DescOwn = (1 << 31), /* Descriptor is owned by NIC */
47325e992a4SHeiner Kallweit RingEnd = (1 << 30), /* End of descriptor ring */
47425e992a4SHeiner Kallweit FirstFrag = (1 << 29), /* First segment of a packet */
47525e992a4SHeiner Kallweit LastFrag = (1 << 28), /* Final segment of a packet */
47625e992a4SHeiner Kallweit };
47725e992a4SHeiner Kallweit
47825e992a4SHeiner Kallweit /* Generic case. */
47925e992a4SHeiner Kallweit enum rtl_tx_desc_bit {
48025e992a4SHeiner Kallweit /* First doubleword. */
48125e992a4SHeiner Kallweit TD_LSO = (1 << 27), /* Large Send Offload */
48225e992a4SHeiner Kallweit #define TD_MSS_MAX 0x07ffu /* MSS value */
48325e992a4SHeiner Kallweit
48425e992a4SHeiner Kallweit /* Second doubleword. */
48525e992a4SHeiner Kallweit TxVlanTag = (1 << 17), /* Add VLAN tag */
48625e992a4SHeiner Kallweit };
48725e992a4SHeiner Kallweit
48825e992a4SHeiner Kallweit /* 8169, 8168b and 810x except 8102e. */
48925e992a4SHeiner Kallweit enum rtl_tx_desc_bit_0 {
49025e992a4SHeiner Kallweit /* First doubleword. */
49125e992a4SHeiner Kallweit #define TD0_MSS_SHIFT 16 /* MSS position (11 bits) */
49225e992a4SHeiner Kallweit TD0_TCP_CS = (1 << 16), /* Calculate TCP/IP checksum */
49325e992a4SHeiner Kallweit TD0_UDP_CS = (1 << 17), /* Calculate UDP/IP checksum */
49425e992a4SHeiner Kallweit TD0_IP_CS = (1 << 18), /* Calculate IP checksum */
49525e992a4SHeiner Kallweit };
49625e992a4SHeiner Kallweit
49725e992a4SHeiner Kallweit /* 8102e, 8168c and beyond. */
49825e992a4SHeiner Kallweit enum rtl_tx_desc_bit_1 {
49925e992a4SHeiner Kallweit /* First doubleword. */
50025e992a4SHeiner Kallweit TD1_GTSENV4 = (1 << 26), /* Giant Send for IPv4 */
50125e992a4SHeiner Kallweit TD1_GTSENV6 = (1 << 25), /* Giant Send for IPv6 */
50225e992a4SHeiner Kallweit #define GTTCPHO_SHIFT 18
503e64e0c89SHeiner Kallweit #define GTTCPHO_MAX 0x7f
50425e992a4SHeiner Kallweit
50525e992a4SHeiner Kallweit /* Second doubleword. */
50625e992a4SHeiner Kallweit #define TCPHO_SHIFT 18
507e64e0c89SHeiner Kallweit #define TCPHO_MAX 0x3ff
50825e992a4SHeiner Kallweit #define TD1_MSS_SHIFT 18 /* MSS position (11 bits) */
50925e992a4SHeiner Kallweit TD1_IPv6_CS = (1 << 28), /* Calculate IPv6 checksum */
51025e992a4SHeiner Kallweit TD1_IPv4_CS = (1 << 29), /* Calculate IPv4 checksum */
51125e992a4SHeiner Kallweit TD1_TCP_CS = (1 << 30), /* Calculate TCP/IP checksum */
51225e992a4SHeiner Kallweit TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */
51325e992a4SHeiner Kallweit };
51425e992a4SHeiner Kallweit
51525e992a4SHeiner Kallweit enum rtl_rx_desc_bit {
51625e992a4SHeiner Kallweit /* Rx private */
51725e992a4SHeiner Kallweit PID1 = (1 << 18), /* Protocol ID bit 1/2 */
51825e992a4SHeiner Kallweit PID0 = (1 << 17), /* Protocol ID bit 0/2 */
51925e992a4SHeiner Kallweit
52025e992a4SHeiner Kallweit #define RxProtoUDP (PID1)
52125e992a4SHeiner Kallweit #define RxProtoTCP (PID0)
52225e992a4SHeiner Kallweit #define RxProtoIP (PID1 | PID0)
52325e992a4SHeiner Kallweit #define RxProtoMask RxProtoIP
52425e992a4SHeiner Kallweit
52525e992a4SHeiner Kallweit IPFail = (1 << 16), /* IP checksum failed */
52625e992a4SHeiner Kallweit UDPFail = (1 << 15), /* UDP/IP checksum failed */
52725e992a4SHeiner Kallweit TCPFail = (1 << 14), /* TCP/IP checksum failed */
528206a75e0SHeiner Kallweit
529206a75e0SHeiner Kallweit #define RxCSFailMask (IPFail | UDPFail | TCPFail)
530206a75e0SHeiner Kallweit
53125e992a4SHeiner Kallweit RxVlanTag = (1 << 16), /* VLAN tag available */
53225e992a4SHeiner Kallweit };
53325e992a4SHeiner Kallweit
5340170d594SHeiner Kallweit #define RTL_GSO_MAX_SIZE_V1 32000
5350170d594SHeiner Kallweit #define RTL_GSO_MAX_SEGS_V1 24
5360170d594SHeiner Kallweit #define RTL_GSO_MAX_SIZE_V2 64000
5370170d594SHeiner Kallweit #define RTL_GSO_MAX_SEGS_V2 64
5380170d594SHeiner Kallweit
53925e992a4SHeiner Kallweit struct TxDesc {
54025e992a4SHeiner Kallweit __le32 opts1;
54125e992a4SHeiner Kallweit __le32 opts2;
54225e992a4SHeiner Kallweit __le64 addr;
54325e992a4SHeiner Kallweit };
54425e992a4SHeiner Kallweit
54525e992a4SHeiner Kallweit struct RxDesc {
54625e992a4SHeiner Kallweit __le32 opts1;
54725e992a4SHeiner Kallweit __le32 opts2;
54825e992a4SHeiner Kallweit __le64 addr;
54925e992a4SHeiner Kallweit };
55025e992a4SHeiner Kallweit
55125e992a4SHeiner Kallweit struct ring_info {
55225e992a4SHeiner Kallweit struct sk_buff *skb;
55325e992a4SHeiner Kallweit u32 len;
55425e992a4SHeiner Kallweit };
55525e992a4SHeiner Kallweit
55625e992a4SHeiner Kallweit struct rtl8169_counters {
55725e992a4SHeiner Kallweit __le64 tx_packets;
55825e992a4SHeiner Kallweit __le64 rx_packets;
55925e992a4SHeiner Kallweit __le64 tx_errors;
56025e992a4SHeiner Kallweit __le32 rx_errors;
56125e992a4SHeiner Kallweit __le16 rx_missed;
56225e992a4SHeiner Kallweit __le16 align_errors;
56325e992a4SHeiner Kallweit __le32 tx_one_collision;
56425e992a4SHeiner Kallweit __le32 tx_multi_collision;
56525e992a4SHeiner Kallweit __le64 rx_unicast;
56625e992a4SHeiner Kallweit __le64 rx_broadcast;
56725e992a4SHeiner Kallweit __le32 rx_multicast;
56825e992a4SHeiner Kallweit __le16 tx_aborted;
56925e992a4SHeiner Kallweit __le16 tx_underun;
57025e992a4SHeiner Kallweit };
57125e992a4SHeiner Kallweit
57225e992a4SHeiner Kallweit struct rtl8169_tc_offsets {
57325e992a4SHeiner Kallweit bool inited;
57425e992a4SHeiner Kallweit __le64 tx_errors;
57525e992a4SHeiner Kallweit __le32 tx_multi_collision;
57625e992a4SHeiner Kallweit __le16 tx_aborted;
5770da3359aSHeiner Kallweit __le16 rx_missed;
57825e992a4SHeiner Kallweit };
57925e992a4SHeiner Kallweit
58025e992a4SHeiner Kallweit enum rtl_flag {
58125e992a4SHeiner Kallweit RTL_FLAG_TASK_ENABLED = 0,
58225e992a4SHeiner Kallweit RTL_FLAG_TASK_RESET_PENDING,
583fbe43b7fSHeiner Kallweit RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE,
58480c0576eSHeiner Kallweit RTL_FLAG_TASK_TX_TIMEOUT,
58525e992a4SHeiner Kallweit RTL_FLAG_MAX
58625e992a4SHeiner Kallweit };
58725e992a4SHeiner Kallweit
588e0d38b58SHeiner Kallweit enum rtl_dash_type {
589e0d38b58SHeiner Kallweit RTL_DASH_NONE,
590e0d38b58SHeiner Kallweit RTL_DASH_DP,
591e0d38b58SHeiner Kallweit RTL_DASH_EP,
592e0d38b58SHeiner Kallweit };
593e0d38b58SHeiner Kallweit
59425e992a4SHeiner Kallweit struct rtl8169_private {
59525e992a4SHeiner Kallweit void __iomem *mmio_addr; /* memory map physical address */
59625e992a4SHeiner Kallweit struct pci_dev *pci_dev;
59725e992a4SHeiner Kallweit struct net_device *dev;
59825e992a4SHeiner Kallweit struct phy_device *phydev;
59925e992a4SHeiner Kallweit struct napi_struct napi;
60025e992a4SHeiner Kallweit enum mac_version mac_version;
601e0d38b58SHeiner Kallweit enum rtl_dash_type dash_type;
60225e992a4SHeiner Kallweit u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
60325e992a4SHeiner Kallweit u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
60425e992a4SHeiner Kallweit u32 dirty_tx;
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;
6131bd32771SThomas Gleixner int irq;
61425e992a4SHeiner Kallweit struct clk *clk;
61525e992a4SHeiner Kallweit
61625e992a4SHeiner Kallweit struct {
61725e992a4SHeiner Kallweit DECLARE_BITMAP(flags, RTL_FLAG_MAX);
61825e992a4SHeiner Kallweit struct work_struct work;
61925e992a4SHeiner Kallweit } wk;
62025e992a4SHeiner Kallweit
621d6c36cbcSSebastian Andrzej Siewior raw_spinlock_t config25_lock;
622d6c36cbcSSebastian Andrzej Siewior raw_spinlock_t mac_ocp_lock;
62391c86435SHeiner Kallweit
624d6c36cbcSSebastian Andrzej Siewior raw_spinlock_t cfg9346_usage_lock;
62559ee97c0SHeiner Kallweit int cfg9346_usage_count;
62659ee97c0SHeiner Kallweit
62725e992a4SHeiner Kallweit unsigned supports_gmii:1;
628cf2ffdeaSHeiner Kallweit unsigned aspm_manageable:1;
629c61d525fSChunHao Lin unsigned dash_enabled:1;
63025e992a4SHeiner Kallweit dma_addr_t counters_phys_addr;
63125e992a4SHeiner Kallweit struct rtl8169_counters *counters;
63225e992a4SHeiner Kallweit struct rtl8169_tc_offsets tc_offset;
63325e992a4SHeiner Kallweit u32 saved_wolopts;
6347ec3f872SHeiner Kallweit int eee_adv;
63525e992a4SHeiner Kallweit
63625e992a4SHeiner Kallweit const char *fw_name;
6378197f9d2SHeiner Kallweit struct rtl_fw *rtl_fw;
63825e992a4SHeiner Kallweit
63925e992a4SHeiner Kallweit u32 ocp_base;
64025e992a4SHeiner Kallweit };
64125e992a4SHeiner Kallweit
64225e992a4SHeiner Kallweit typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
64325e992a4SHeiner Kallweit
64425e992a4SHeiner Kallweit MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
64525e992a4SHeiner Kallweit MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
64625e992a4SHeiner Kallweit MODULE_SOFTDEP("pre: realtek");
64725e992a4SHeiner Kallweit MODULE_LICENSE("GPL");
64825e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168D_1);
64925e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168D_2);
65025e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_1);
65125e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_2);
65225e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168E_3);
65325e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8105E_1);
65425e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168F_1);
65525e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168F_2);
65625e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8402_1);
65725e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8411_1);
65825e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8411_2);
65925e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8106E_1);
66025e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8106E_2);
66125e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168G_2);
66225e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168G_3);
66325e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168H_2);
664229c1e0dSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8168FP_3);
66525e992a4SHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8107E_2);
66602bf642bSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8125A_3);
6670439297bSHeiner Kallweit MODULE_FIRMWARE(FIRMWARE_8125B_2);
66825e992a4SHeiner Kallweit
tp_to_dev(struct rtl8169_private * tp)66925e992a4SHeiner Kallweit static inline struct device *tp_to_dev(struct rtl8169_private *tp)
67025e992a4SHeiner Kallweit {
67125e992a4SHeiner Kallweit return &tp->pci_dev->dev;
67225e992a4SHeiner Kallweit }
67325e992a4SHeiner Kallweit
rtl_lock_config_regs(struct rtl8169_private * tp)67425e992a4SHeiner Kallweit static void rtl_lock_config_regs(struct rtl8169_private *tp)
67525e992a4SHeiner Kallweit {
67659ee97c0SHeiner Kallweit unsigned long flags;
67759ee97c0SHeiner Kallweit
678d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags);
67959ee97c0SHeiner Kallweit if (!--tp->cfg9346_usage_count)
68025e992a4SHeiner Kallweit RTL_W8(tp, Cfg9346, Cfg9346_Lock);
681d6c36cbcSSebastian Andrzej Siewior raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags);
68225e992a4SHeiner Kallweit }
68325e992a4SHeiner Kallweit
rtl_unlock_config_regs(struct rtl8169_private * tp)68425e992a4SHeiner Kallweit static void rtl_unlock_config_regs(struct rtl8169_private *tp)
68525e992a4SHeiner Kallweit {
68659ee97c0SHeiner Kallweit unsigned long flags;
68759ee97c0SHeiner Kallweit
688d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags);
68959ee97c0SHeiner Kallweit if (!tp->cfg9346_usage_count++)
69025e992a4SHeiner Kallweit RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
691d6c36cbcSSebastian Andrzej Siewior raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags);
69225e992a4SHeiner Kallweit }
69325e992a4SHeiner Kallweit
rtl_pci_commit(struct rtl8169_private * tp)694711463f8SHeiner Kallweit static void rtl_pci_commit(struct rtl8169_private *tp)
695711463f8SHeiner Kallweit {
696711463f8SHeiner Kallweit /* Read an arbitrary register to commit a preceding PCI write */
697711463f8SHeiner Kallweit RTL_R8(tp, ChipCmd);
698711463f8SHeiner Kallweit }
699711463f8SHeiner Kallweit
rtl_mod_config2(struct rtl8169_private * tp,u8 clear,u8 set)7006bc6c4e6SHeiner Kallweit static void rtl_mod_config2(struct rtl8169_private *tp, u8 clear, u8 set)
7016bc6c4e6SHeiner Kallweit {
7026bc6c4e6SHeiner Kallweit unsigned long flags;
7036bc6c4e6SHeiner Kallweit u8 val;
7046bc6c4e6SHeiner Kallweit
705d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_irqsave(&tp->config25_lock, flags);
7066bc6c4e6SHeiner Kallweit val = RTL_R8(tp, Config2);
7076bc6c4e6SHeiner Kallweit RTL_W8(tp, Config2, (val & ~clear) | set);
708d6c36cbcSSebastian Andrzej Siewior raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
7096bc6c4e6SHeiner Kallweit }
7106bc6c4e6SHeiner Kallweit
rtl_mod_config5(struct rtl8169_private * tp,u8 clear,u8 set)7116bc6c4e6SHeiner Kallweit static void rtl_mod_config5(struct rtl8169_private *tp, u8 clear, u8 set)
7126bc6c4e6SHeiner Kallweit {
7136bc6c4e6SHeiner Kallweit unsigned long flags;
7146bc6c4e6SHeiner Kallweit u8 val;
7156bc6c4e6SHeiner Kallweit
716d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_irqsave(&tp->config25_lock, flags);
7176bc6c4e6SHeiner Kallweit val = RTL_R8(tp, Config5);
7186bc6c4e6SHeiner Kallweit RTL_W8(tp, Config5, (val & ~clear) | set);
719d6c36cbcSSebastian Andrzej Siewior raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
7206bc6c4e6SHeiner Kallweit }
7216bc6c4e6SHeiner Kallweit
rtl_is_8125(struct rtl8169_private * tp)722f1bce4adSHeiner Kallweit static bool rtl_is_8125(struct rtl8169_private *tp)
723f1bce4adSHeiner Kallweit {
724efc37109SHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_61;
725f1bce4adSHeiner Kallweit }
726f1bce4adSHeiner Kallweit
rtl_is_8168evl_up(struct rtl8169_private * tp)7279e9f33baSHeiner Kallweit static bool rtl_is_8168evl_up(struct rtl8169_private *tp)
7289e9f33baSHeiner Kallweit {
7299e9f33baSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_34 &&
730c623305bSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_39 &&
731e6d6ca6eSKai-Heng Feng tp->mac_version <= RTL_GIGA_MAC_VER_53;
7329e9f33baSHeiner Kallweit }
7339e9f33baSHeiner Kallweit
rtl_supports_eee(struct rtl8169_private * tp)7342e779ddbSHeiner Kallweit static bool rtl_supports_eee(struct rtl8169_private *tp)
7352e779ddbSHeiner Kallweit {
7362e779ddbSHeiner Kallweit return tp->mac_version >= RTL_GIGA_MAC_VER_34 &&
7372e779ddbSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_37 &&
7382e779ddbSHeiner Kallweit tp->mac_version != RTL_GIGA_MAC_VER_39;
7392e779ddbSHeiner Kallweit }
7402e779ddbSHeiner Kallweit
rtl_read_mac_from_reg(struct rtl8169_private * tp,u8 * mac,int reg)741ce37115eSHeiner Kallweit static void rtl_read_mac_from_reg(struct rtl8169_private *tp, u8 *mac, int reg)
742ce37115eSHeiner Kallweit {
743ce37115eSHeiner Kallweit int i;
744ce37115eSHeiner Kallweit
745ce37115eSHeiner Kallweit for (i = 0; i < ETH_ALEN; i++)
746ce37115eSHeiner Kallweit mac[i] = RTL_R8(tp, reg + i);
747ce37115eSHeiner Kallweit }
748ce37115eSHeiner Kallweit
74925e992a4SHeiner Kallweit struct rtl_cond {
75025e992a4SHeiner Kallweit bool (*check)(struct rtl8169_private *);
75125e992a4SHeiner Kallweit const char *msg;
75225e992a4SHeiner Kallweit };
75325e992a4SHeiner Kallweit
rtl_loop_wait(struct rtl8169_private * tp,const struct rtl_cond * c,unsigned long usecs,int n,bool high)75425e992a4SHeiner Kallweit static bool rtl_loop_wait(struct rtl8169_private *tp, const struct rtl_cond *c,
755d6836ef0SHeiner Kallweit unsigned long usecs, int n, bool high)
75625e992a4SHeiner Kallweit {
75725e992a4SHeiner Kallweit int i;
75825e992a4SHeiner Kallweit
75925e992a4SHeiner Kallweit for (i = 0; i < n; i++) {
76025e992a4SHeiner Kallweit if (c->check(tp) == high)
76125e992a4SHeiner Kallweit return true;
762d6836ef0SHeiner Kallweit fsleep(usecs);
76325e992a4SHeiner Kallweit }
76493882c6fSHeiner Kallweit
76593882c6fSHeiner Kallweit if (net_ratelimit())
766d6836ef0SHeiner Kallweit netdev_err(tp->dev, "%s == %d (loop: %d, delay: %lu).\n",
767d6836ef0SHeiner Kallweit c->msg, !high, n, usecs);
76825e992a4SHeiner Kallweit return false;
76925e992a4SHeiner Kallweit }
77025e992a4SHeiner Kallweit
rtl_loop_wait_high(struct rtl8169_private * tp,const struct rtl_cond * c,unsigned long d,int n)771d6836ef0SHeiner Kallweit static bool rtl_loop_wait_high(struct rtl8169_private *tp,
77225e992a4SHeiner Kallweit const struct rtl_cond *c,
773d6836ef0SHeiner Kallweit unsigned long d, int n)
77425e992a4SHeiner Kallweit {
775d6836ef0SHeiner Kallweit return rtl_loop_wait(tp, c, d, n, true);
77625e992a4SHeiner Kallweit }
77725e992a4SHeiner Kallweit
rtl_loop_wait_low(struct rtl8169_private * tp,const struct rtl_cond * c,unsigned long d,int n)778d6836ef0SHeiner Kallweit static bool rtl_loop_wait_low(struct rtl8169_private *tp,
77925e992a4SHeiner Kallweit const struct rtl_cond *c,
780d6836ef0SHeiner Kallweit unsigned long d, int n)
78125e992a4SHeiner Kallweit {
782d6836ef0SHeiner Kallweit return rtl_loop_wait(tp, c, d, n, false);
78325e992a4SHeiner Kallweit }
78425e992a4SHeiner Kallweit
78525e992a4SHeiner Kallweit #define DECLARE_RTL_COND(name) \
78625e992a4SHeiner Kallweit static bool name ## _check(struct rtl8169_private *); \
78725e992a4SHeiner Kallweit \
78825e992a4SHeiner Kallweit static const struct rtl_cond name = { \
78925e992a4SHeiner Kallweit .check = name ## _check, \
79025e992a4SHeiner Kallweit .msg = #name \
79125e992a4SHeiner Kallweit }; \
79225e992a4SHeiner Kallweit \
79325e992a4SHeiner Kallweit static bool name ## _check(struct rtl8169_private *tp)
79425e992a4SHeiner Kallweit
r8168fp_adjust_ocp_cmd(struct rtl8169_private * tp,u32 * cmd,int type)795c6cff9dfSHeiner Kallweit static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
796c6cff9dfSHeiner Kallweit {
797c6cff9dfSHeiner Kallweit /* based on RTL8168FP_OOBMAC_BASE in vendor driver */
798e6d6ca6eSKai-Heng Feng if (type == ERIAR_OOB &&
799e6d6ca6eSKai-Heng Feng (tp->mac_version == RTL_GIGA_MAC_VER_52 ||
800e6d6ca6eSKai-Heng Feng tp->mac_version == RTL_GIGA_MAC_VER_53))
801abbf9a0eSHayes Wang *cmd |= 0xf70 << 18;
802c6cff9dfSHeiner Kallweit }
803c6cff9dfSHeiner Kallweit
DECLARE_RTL_COND(rtl_eriar_cond)804c6cff9dfSHeiner Kallweit DECLARE_RTL_COND(rtl_eriar_cond)
805c6cff9dfSHeiner Kallweit {
806c6cff9dfSHeiner Kallweit return RTL_R32(tp, ERIAR) & ERIAR_FLAG;
807c6cff9dfSHeiner Kallweit }
808c6cff9dfSHeiner Kallweit
_rtl_eri_write(struct rtl8169_private * tp,int addr,u32 mask,u32 val,int type)809c6cff9dfSHeiner Kallweit static void _rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask,
810c6cff9dfSHeiner Kallweit u32 val, int type)
811c6cff9dfSHeiner Kallweit {
812c6cff9dfSHeiner Kallweit u32 cmd = ERIAR_WRITE_CMD | type | mask | addr;
813c6cff9dfSHeiner Kallweit
8145f1e1224SHeiner Kallweit if (WARN(addr & 3 || !mask, "addr: 0x%x, mask: 0x%08x\n", addr, mask))
8155f1e1224SHeiner Kallweit return;
8165f1e1224SHeiner Kallweit
817c6cff9dfSHeiner Kallweit RTL_W32(tp, ERIDR, val);
818c6cff9dfSHeiner Kallweit r8168fp_adjust_ocp_cmd(tp, &cmd, type);
819c6cff9dfSHeiner Kallweit RTL_W32(tp, ERIAR, cmd);
820c6cff9dfSHeiner Kallweit
821c6cff9dfSHeiner Kallweit rtl_loop_wait_low(tp, &rtl_eriar_cond, 100, 100);
822c6cff9dfSHeiner Kallweit }
823c6cff9dfSHeiner Kallweit
rtl_eri_write(struct rtl8169_private * tp,int addr,u32 mask,u32 val)824c6cff9dfSHeiner Kallweit static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask,
825c6cff9dfSHeiner Kallweit u32 val)
826c6cff9dfSHeiner Kallweit {
827c6cff9dfSHeiner Kallweit _rtl_eri_write(tp, addr, mask, val, ERIAR_EXGMAC);
828c6cff9dfSHeiner Kallweit }
829c6cff9dfSHeiner Kallweit
_rtl_eri_read(struct rtl8169_private * tp,int addr,int type)830c6cff9dfSHeiner Kallweit static u32 _rtl_eri_read(struct rtl8169_private *tp, int addr, int type)
831c6cff9dfSHeiner Kallweit {
832c6cff9dfSHeiner Kallweit u32 cmd = ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr;
833c6cff9dfSHeiner Kallweit
834c6cff9dfSHeiner Kallweit r8168fp_adjust_ocp_cmd(tp, &cmd, type);
835c6cff9dfSHeiner Kallweit RTL_W32(tp, ERIAR, cmd);
836c6cff9dfSHeiner Kallweit
837c6cff9dfSHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ?
838c6cff9dfSHeiner Kallweit RTL_R32(tp, ERIDR) : ~0;
839c6cff9dfSHeiner Kallweit }
840c6cff9dfSHeiner Kallweit
rtl_eri_read(struct rtl8169_private * tp,int addr)841c6cff9dfSHeiner Kallweit static u32 rtl_eri_read(struct rtl8169_private *tp, int addr)
842c6cff9dfSHeiner Kallweit {
843c6cff9dfSHeiner Kallweit return _rtl_eri_read(tp, addr, ERIAR_EXGMAC);
844c6cff9dfSHeiner Kallweit }
845c6cff9dfSHeiner Kallweit
rtl_w0w1_eri(struct rtl8169_private * tp,int addr,u32 p,u32 m)846c6cff9dfSHeiner Kallweit static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 p, u32 m)
847c6cff9dfSHeiner Kallweit {
848c6cff9dfSHeiner Kallweit u32 val = rtl_eri_read(tp, addr);
849c6cff9dfSHeiner Kallweit
850c6cff9dfSHeiner Kallweit rtl_eri_write(tp, addr, ERIAR_MASK_1111, (val & ~m) | p);
851c6cff9dfSHeiner Kallweit }
852c6cff9dfSHeiner Kallweit
rtl_eri_set_bits(struct rtl8169_private * tp,int addr,u32 p)853c6cff9dfSHeiner Kallweit static void rtl_eri_set_bits(struct rtl8169_private *tp, int addr, u32 p)
854c6cff9dfSHeiner Kallweit {
855c6cff9dfSHeiner Kallweit rtl_w0w1_eri(tp, addr, p, 0);
856c6cff9dfSHeiner Kallweit }
857c6cff9dfSHeiner Kallweit
rtl_eri_clear_bits(struct rtl8169_private * tp,int addr,u32 m)858c6cff9dfSHeiner Kallweit static void rtl_eri_clear_bits(struct rtl8169_private *tp, int addr, u32 m)
859c6cff9dfSHeiner Kallweit {
860c6cff9dfSHeiner Kallweit rtl_w0w1_eri(tp, addr, 0, m);
861c6cff9dfSHeiner Kallweit }
862c6cff9dfSHeiner Kallweit
rtl_ocp_reg_failure(u32 reg)863a46604d7SHeiner Kallweit static bool rtl_ocp_reg_failure(u32 reg)
86425e992a4SHeiner Kallweit {
865a46604d7SHeiner Kallweit return WARN_ONCE(reg & 0xffff0001, "Invalid ocp reg %x!\n", reg);
86625e992a4SHeiner Kallweit }
86725e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_ocp_gphy_cond)86825e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocp_gphy_cond)
86925e992a4SHeiner Kallweit {
87025e992a4SHeiner Kallweit return RTL_R32(tp, GPHY_OCP) & OCPAR_FLAG;
87125e992a4SHeiner Kallweit }
87225e992a4SHeiner Kallweit
r8168_phy_ocp_write(struct rtl8169_private * tp,u32 reg,u32 data)87325e992a4SHeiner Kallweit static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
87425e992a4SHeiner Kallweit {
875a46604d7SHeiner Kallweit if (rtl_ocp_reg_failure(reg))
87625e992a4SHeiner Kallweit return;
87725e992a4SHeiner Kallweit
87825e992a4SHeiner Kallweit RTL_W32(tp, GPHY_OCP, OCPAR_FLAG | (reg << 15) | data);
87925e992a4SHeiner Kallweit
880d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10);
88125e992a4SHeiner Kallweit }
88225e992a4SHeiner Kallweit
r8168_phy_ocp_read(struct rtl8169_private * tp,u32 reg)8839b994b4aSHeiner Kallweit static int r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg)
88425e992a4SHeiner Kallweit {
885a46604d7SHeiner Kallweit if (rtl_ocp_reg_failure(reg))
88625e992a4SHeiner Kallweit return 0;
88725e992a4SHeiner Kallweit
88825e992a4SHeiner Kallweit RTL_W32(tp, GPHY_OCP, reg << 15);
88925e992a4SHeiner Kallweit
890d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ?
8919b994b4aSHeiner Kallweit (RTL_R32(tp, GPHY_OCP) & 0xffff) : -ETIMEDOUT;
89225e992a4SHeiner Kallweit }
89325e992a4SHeiner Kallweit
__r8168_mac_ocp_write(struct rtl8169_private * tp,u32 reg,u32 data)89491c86435SHeiner Kallweit static void __r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
89525e992a4SHeiner Kallweit {
896a46604d7SHeiner Kallweit if (rtl_ocp_reg_failure(reg))
89725e992a4SHeiner Kallweit return;
89825e992a4SHeiner Kallweit
89925e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, OCPAR_FLAG | (reg << 15) | data);
90025e992a4SHeiner Kallweit }
90125e992a4SHeiner Kallweit
r8168_mac_ocp_write(struct rtl8169_private * tp,u32 reg,u32 data)90291c86435SHeiner Kallweit static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
90391c86435SHeiner Kallweit {
90491c86435SHeiner Kallweit unsigned long flags;
90591c86435SHeiner Kallweit
906d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags);
90791c86435SHeiner Kallweit __r8168_mac_ocp_write(tp, reg, data);
908d6c36cbcSSebastian Andrzej Siewior raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
90991c86435SHeiner Kallweit }
91091c86435SHeiner Kallweit
__r8168_mac_ocp_read(struct rtl8169_private * tp,u32 reg)91191c86435SHeiner Kallweit static u16 __r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
91225e992a4SHeiner Kallweit {
913a46604d7SHeiner Kallweit if (rtl_ocp_reg_failure(reg))
91425e992a4SHeiner Kallweit return 0;
91525e992a4SHeiner Kallweit
91625e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, reg << 15);
91725e992a4SHeiner Kallweit
91825e992a4SHeiner Kallweit return RTL_R32(tp, OCPDR);
91925e992a4SHeiner Kallweit }
92025e992a4SHeiner Kallweit
r8168_mac_ocp_read(struct rtl8169_private * tp,u32 reg)92191c86435SHeiner Kallweit static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
92291c86435SHeiner Kallweit {
92391c86435SHeiner Kallweit unsigned long flags;
92491c86435SHeiner Kallweit u16 val;
92591c86435SHeiner Kallweit
926d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags);
92791c86435SHeiner Kallweit val = __r8168_mac_ocp_read(tp, reg);
928d6c36cbcSSebastian Andrzej Siewior raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
92991c86435SHeiner Kallweit
93091c86435SHeiner Kallweit return val;
93191c86435SHeiner Kallweit }
93291c86435SHeiner Kallweit
r8168_mac_ocp_modify(struct rtl8169_private * tp,u32 reg,u16 mask,u16 set)933ef712edeSHeiner Kallweit static void r8168_mac_ocp_modify(struct rtl8169_private *tp, u32 reg, u16 mask,
934ef712edeSHeiner Kallweit u16 set)
935ef712edeSHeiner Kallweit {
93691c86435SHeiner Kallweit unsigned long flags;
93791c86435SHeiner Kallweit u16 data;
938ef712edeSHeiner Kallweit
939d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags);
94091c86435SHeiner Kallweit data = __r8168_mac_ocp_read(tp, reg);
94191c86435SHeiner Kallweit __r8168_mac_ocp_write(tp, reg, (data & ~mask) | set);
942d6c36cbcSSebastian Andrzej Siewior raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
943ef712edeSHeiner Kallweit }
944ef712edeSHeiner Kallweit
945acb58657SHeiner Kallweit /* Work around a hw issue with RTL8168g PHY, the quirk disables
946acb58657SHeiner Kallweit * PHY MCU interrupts before PHY power-down.
947acb58657SHeiner Kallweit */
rtl8168g_phy_suspend_quirk(struct rtl8169_private * tp,int value)948acb58657SHeiner Kallweit static void rtl8168g_phy_suspend_quirk(struct rtl8169_private *tp, int value)
949acb58657SHeiner Kallweit {
950acb58657SHeiner Kallweit switch (tp->mac_version) {
951acb58657SHeiner Kallweit case RTL_GIGA_MAC_VER_40:
952acb58657SHeiner Kallweit if (value & BMCR_RESET || !(value & BMCR_PDOWN))
953acb58657SHeiner Kallweit rtl_eri_set_bits(tp, 0x1a8, 0xfc000000);
954acb58657SHeiner Kallweit else
955acb58657SHeiner Kallweit rtl_eri_clear_bits(tp, 0x1a8, 0xfc000000);
956acb58657SHeiner Kallweit break;
957acb58657SHeiner Kallweit default:
958acb58657SHeiner Kallweit break;
959acb58657SHeiner Kallweit }
960acb58657SHeiner Kallweit };
961acb58657SHeiner Kallweit
r8168g_mdio_write(struct rtl8169_private * tp,int reg,int value)96225e992a4SHeiner Kallweit static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value)
96325e992a4SHeiner Kallweit {
96425e992a4SHeiner Kallweit if (reg == 0x1f) {
96525e992a4SHeiner Kallweit tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE;
96625e992a4SHeiner Kallweit return;
96725e992a4SHeiner Kallweit }
96825e992a4SHeiner Kallweit
96925e992a4SHeiner Kallweit if (tp->ocp_base != OCP_STD_PHY_BASE)
97025e992a4SHeiner Kallweit reg -= 0x10;
97125e992a4SHeiner Kallweit
972acb58657SHeiner Kallweit if (tp->ocp_base == OCP_STD_PHY_BASE && reg == MII_BMCR)
973acb58657SHeiner Kallweit rtl8168g_phy_suspend_quirk(tp, value);
974acb58657SHeiner Kallweit
97525e992a4SHeiner Kallweit r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value);
97625e992a4SHeiner Kallweit }
97725e992a4SHeiner Kallweit
r8168g_mdio_read(struct rtl8169_private * tp,int reg)97825e992a4SHeiner Kallweit static int r8168g_mdio_read(struct rtl8169_private *tp, int reg)
97925e992a4SHeiner Kallweit {
9809c6850feSHeiner Kallweit if (reg == 0x1f)
9819c6850feSHeiner Kallweit return tp->ocp_base == OCP_STD_PHY_BASE ? 0 : tp->ocp_base >> 4;
9829c6850feSHeiner Kallweit
98325e992a4SHeiner Kallweit if (tp->ocp_base != OCP_STD_PHY_BASE)
98425e992a4SHeiner Kallweit reg -= 0x10;
98525e992a4SHeiner Kallweit
98625e992a4SHeiner Kallweit return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2);
98725e992a4SHeiner Kallweit }
98825e992a4SHeiner Kallweit
mac_mcu_write(struct rtl8169_private * tp,int reg,int value)98925e992a4SHeiner Kallweit static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value)
99025e992a4SHeiner Kallweit {
99125e992a4SHeiner Kallweit if (reg == 0x1f) {
99225e992a4SHeiner Kallweit tp->ocp_base = value << 4;
99325e992a4SHeiner Kallweit return;
99425e992a4SHeiner Kallweit }
99525e992a4SHeiner Kallweit
99625e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, tp->ocp_base + reg, value);
99725e992a4SHeiner Kallweit }
99825e992a4SHeiner Kallweit
mac_mcu_read(struct rtl8169_private * tp,int reg)99925e992a4SHeiner Kallweit static int mac_mcu_read(struct rtl8169_private *tp, int reg)
100025e992a4SHeiner Kallweit {
100125e992a4SHeiner Kallweit return r8168_mac_ocp_read(tp, tp->ocp_base + reg);
100225e992a4SHeiner Kallweit }
100325e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_phyar_cond)100425e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_phyar_cond)
100525e992a4SHeiner Kallweit {
100625e992a4SHeiner Kallweit return RTL_R32(tp, PHYAR) & 0x80000000;
100725e992a4SHeiner Kallweit }
100825e992a4SHeiner Kallweit
r8169_mdio_write(struct rtl8169_private * tp,int reg,int value)100925e992a4SHeiner Kallweit static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value)
101025e992a4SHeiner Kallweit {
101125e992a4SHeiner Kallweit RTL_W32(tp, PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff));
101225e992a4SHeiner Kallweit
1013d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_phyar_cond, 25, 20);
101425e992a4SHeiner Kallweit /*
101525e992a4SHeiner Kallweit * According to hardware specs a 20us delay is required after write
101625e992a4SHeiner Kallweit * complete indication, but before sending next command.
101725e992a4SHeiner Kallweit */
101825e992a4SHeiner Kallweit udelay(20);
101925e992a4SHeiner Kallweit }
102025e992a4SHeiner Kallweit
r8169_mdio_read(struct rtl8169_private * tp,int reg)102125e992a4SHeiner Kallweit static int r8169_mdio_read(struct rtl8169_private *tp, int reg)
102225e992a4SHeiner Kallweit {
102325e992a4SHeiner Kallweit int value;
102425e992a4SHeiner Kallweit
102525e992a4SHeiner Kallweit RTL_W32(tp, PHYAR, 0x0 | (reg & 0x1f) << 16);
102625e992a4SHeiner Kallweit
1027d6836ef0SHeiner Kallweit value = rtl_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ?
10289b994b4aSHeiner Kallweit RTL_R32(tp, PHYAR) & 0xffff : -ETIMEDOUT;
102925e992a4SHeiner Kallweit
103025e992a4SHeiner Kallweit /*
103125e992a4SHeiner Kallweit * According to hardware specs a 20us delay is required after read
103225e992a4SHeiner Kallweit * complete indication, but before sending next command.
103325e992a4SHeiner Kallweit */
103425e992a4SHeiner Kallweit udelay(20);
103525e992a4SHeiner Kallweit
103625e992a4SHeiner Kallweit return value;
103725e992a4SHeiner Kallweit }
103825e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_ocpar_cond)103925e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocpar_cond)
104025e992a4SHeiner Kallweit {
104125e992a4SHeiner Kallweit return RTL_R32(tp, OCPAR) & OCPAR_FLAG;
104225e992a4SHeiner Kallweit }
104325e992a4SHeiner Kallweit
104425e992a4SHeiner Kallweit #define R8168DP_1_MDIO_ACCESS_BIT 0x00020000
104525e992a4SHeiner Kallweit
r8168dp_2_mdio_start(struct rtl8169_private * tp)104625e992a4SHeiner Kallweit static void r8168dp_2_mdio_start(struct rtl8169_private *tp)
104725e992a4SHeiner Kallweit {
104825e992a4SHeiner Kallweit RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT);
104925e992a4SHeiner Kallweit }
105025e992a4SHeiner Kallweit
r8168dp_2_mdio_stop(struct rtl8169_private * tp)105125e992a4SHeiner Kallweit static void r8168dp_2_mdio_stop(struct rtl8169_private *tp)
105225e992a4SHeiner Kallweit {
105325e992a4SHeiner Kallweit RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) | R8168DP_1_MDIO_ACCESS_BIT);
105425e992a4SHeiner Kallweit }
105525e992a4SHeiner Kallweit
r8168dp_2_mdio_write(struct rtl8169_private * tp,int reg,int value)105625e992a4SHeiner Kallweit static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value)
105725e992a4SHeiner Kallweit {
105825e992a4SHeiner Kallweit r8168dp_2_mdio_start(tp);
105925e992a4SHeiner Kallweit
106025e992a4SHeiner Kallweit r8169_mdio_write(tp, reg, value);
106125e992a4SHeiner Kallweit
106225e992a4SHeiner Kallweit r8168dp_2_mdio_stop(tp);
106325e992a4SHeiner Kallweit }
106425e992a4SHeiner Kallweit
r8168dp_2_mdio_read(struct rtl8169_private * tp,int reg)106525e992a4SHeiner Kallweit static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg)
106625e992a4SHeiner Kallweit {
106725e992a4SHeiner Kallweit int value;
106825e992a4SHeiner Kallweit
106962bdc8fdSHeiner Kallweit /* Work around issue with chip reporting wrong PHY ID */
107062bdc8fdSHeiner Kallweit if (reg == MII_PHYSID2)
107162bdc8fdSHeiner Kallweit return 0xc912;
107262bdc8fdSHeiner Kallweit
107325e992a4SHeiner Kallweit r8168dp_2_mdio_start(tp);
107425e992a4SHeiner Kallweit
107525e992a4SHeiner Kallweit value = r8169_mdio_read(tp, reg);
107625e992a4SHeiner Kallweit
107725e992a4SHeiner Kallweit r8168dp_2_mdio_stop(tp);
107825e992a4SHeiner Kallweit
107925e992a4SHeiner Kallweit return value;
108025e992a4SHeiner Kallweit }
108125e992a4SHeiner Kallweit
rtl_writephy(struct rtl8169_private * tp,int location,int val)108225e992a4SHeiner Kallweit static void rtl_writephy(struct rtl8169_private *tp, int location, int val)
108325e992a4SHeiner Kallweit {
108425e992a4SHeiner Kallweit switch (tp->mac_version) {
108525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28:
108625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31:
108725e992a4SHeiner Kallweit r8168dp_2_mdio_write(tp, location, val);
108825e992a4SHeiner Kallweit break;
10890439297bSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
109025e992a4SHeiner Kallweit r8168g_mdio_write(tp, location, val);
109125e992a4SHeiner Kallweit break;
109225e992a4SHeiner Kallweit default:
109325e992a4SHeiner Kallweit r8169_mdio_write(tp, location, val);
109425e992a4SHeiner Kallweit break;
109525e992a4SHeiner Kallweit }
109625e992a4SHeiner Kallweit }
109725e992a4SHeiner Kallweit
rtl_readphy(struct rtl8169_private * tp,int location)109825e992a4SHeiner Kallweit static int rtl_readphy(struct rtl8169_private *tp, int location)
109925e992a4SHeiner Kallweit {
110025e992a4SHeiner Kallweit switch (tp->mac_version) {
110125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28:
110225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31:
110325e992a4SHeiner Kallweit return r8168dp_2_mdio_read(tp, location);
11040439297bSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
110525e992a4SHeiner Kallweit return r8168g_mdio_read(tp, location);
110625e992a4SHeiner Kallweit default:
110725e992a4SHeiner Kallweit return r8169_mdio_read(tp, location);
110825e992a4SHeiner Kallweit }
110925e992a4SHeiner Kallweit }
111025e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_ephyar_cond)111125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ephyar_cond)
111225e992a4SHeiner Kallweit {
111325e992a4SHeiner Kallweit return RTL_R32(tp, EPHYAR) & EPHYAR_FLAG;
111425e992a4SHeiner Kallweit }
111525e992a4SHeiner Kallweit
rtl_ephy_write(struct rtl8169_private * tp,int reg_addr,int value)111625e992a4SHeiner Kallweit static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value)
111725e992a4SHeiner Kallweit {
111825e992a4SHeiner Kallweit RTL_W32(tp, EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
111925e992a4SHeiner Kallweit (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
112025e992a4SHeiner Kallweit
1121d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100);
112225e992a4SHeiner Kallweit
112325e992a4SHeiner Kallweit udelay(10);
112425e992a4SHeiner Kallweit }
112525e992a4SHeiner Kallweit
rtl_ephy_read(struct rtl8169_private * tp,int reg_addr)112625e992a4SHeiner Kallweit static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr)
112725e992a4SHeiner Kallweit {
112825e992a4SHeiner Kallweit RTL_W32(tp, EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
112925e992a4SHeiner Kallweit
1130d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ?
113125e992a4SHeiner Kallweit RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0;
113225e992a4SHeiner Kallweit }
113325e992a4SHeiner Kallweit
r8168dp_ocp_read(struct rtl8169_private * tp,u16 reg)1134a15aaa03SHeiner Kallweit static u32 r8168dp_ocp_read(struct rtl8169_private *tp, u16 reg)
113525e992a4SHeiner Kallweit {
1136a15aaa03SHeiner Kallweit RTL_W32(tp, OCPAR, 0x0fu << 12 | (reg & 0x0fff));
1137d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ?
113825e992a4SHeiner Kallweit RTL_R32(tp, OCPDR) : ~0;
113925e992a4SHeiner Kallweit }
114025e992a4SHeiner Kallweit
r8168ep_ocp_read(struct rtl8169_private * tp,u16 reg)1141787c0c04SHeiner Kallweit static u32 r8168ep_ocp_read(struct rtl8169_private *tp, u16 reg)
114225e992a4SHeiner Kallweit {
114325e992a4SHeiner Kallweit return _rtl_eri_read(tp, reg, ERIAR_OOB);
114425e992a4SHeiner Kallweit }
114525e992a4SHeiner Kallweit
r8168dp_ocp_write(struct rtl8169_private * tp,u8 mask,u16 reg,u32 data)114625e992a4SHeiner Kallweit static void r8168dp_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg,
114725e992a4SHeiner Kallweit u32 data)
114825e992a4SHeiner Kallweit {
114925e992a4SHeiner Kallweit RTL_W32(tp, OCPDR, data);
115025e992a4SHeiner Kallweit RTL_W32(tp, OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
1151d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20);
115225e992a4SHeiner Kallweit }
115325e992a4SHeiner Kallweit
r8168ep_ocp_write(struct rtl8169_private * tp,u8 mask,u16 reg,u32 data)115425e992a4SHeiner Kallweit static void r8168ep_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg,
115525e992a4SHeiner Kallweit u32 data)
115625e992a4SHeiner Kallweit {
115725e992a4SHeiner Kallweit _rtl_eri_write(tp, reg, ((u32)mask & 0x0f) << ERIAR_MASK_SHIFT,
115825e992a4SHeiner Kallweit data, ERIAR_OOB);
115925e992a4SHeiner Kallweit }
116025e992a4SHeiner Kallweit
r8168dp_oob_notify(struct rtl8169_private * tp,u8 cmd)116125e992a4SHeiner Kallweit static void r8168dp_oob_notify(struct rtl8169_private *tp, u8 cmd)
116225e992a4SHeiner Kallweit {
116325e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe8, ERIAR_MASK_0001, cmd);
116425e992a4SHeiner Kallweit
116525e992a4SHeiner Kallweit r8168dp_ocp_write(tp, 0x1, 0x30, 0x00000001);
116625e992a4SHeiner Kallweit }
116725e992a4SHeiner Kallweit
116825e992a4SHeiner Kallweit #define OOB_CMD_RESET 0x00
116925e992a4SHeiner Kallweit #define OOB_CMD_DRIVER_START 0x05
117025e992a4SHeiner Kallweit #define OOB_CMD_DRIVER_STOP 0x06
117125e992a4SHeiner Kallweit
rtl8168_get_ocp_reg(struct rtl8169_private * tp)117225e992a4SHeiner Kallweit static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp)
117325e992a4SHeiner Kallweit {
117425e992a4SHeiner Kallweit return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10;
117525e992a4SHeiner Kallweit }
117625e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_dp_ocp_read_cond)117725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_dp_ocp_read_cond)
117825e992a4SHeiner Kallweit {
117925e992a4SHeiner Kallweit u16 reg;
118025e992a4SHeiner Kallweit
118125e992a4SHeiner Kallweit reg = rtl8168_get_ocp_reg(tp);
118225e992a4SHeiner Kallweit
1183a15aaa03SHeiner Kallweit return r8168dp_ocp_read(tp, reg) & 0x00000800;
118425e992a4SHeiner Kallweit }
118525e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_ep_ocp_read_cond)118625e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ep_ocp_read_cond)
118725e992a4SHeiner Kallweit {
1188787c0c04SHeiner Kallweit return r8168ep_ocp_read(tp, 0x124) & 0x00000001;
118925e992a4SHeiner Kallweit }
119025e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_ocp_tx_cond)119125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_ocp_tx_cond)
119225e992a4SHeiner Kallweit {
119325e992a4SHeiner Kallweit return RTL_R8(tp, IBISR0) & 0x20;
119425e992a4SHeiner Kallweit }
119525e992a4SHeiner Kallweit
rtl8168ep_stop_cmac(struct rtl8169_private * tp)119625e992a4SHeiner Kallweit static void rtl8168ep_stop_cmac(struct rtl8169_private *tp)
119725e992a4SHeiner Kallweit {
119825e992a4SHeiner Kallweit RTL_W8(tp, IBCR2, RTL_R8(tp, IBCR2) & ~0x01);
1199d6836ef0SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_ocp_tx_cond, 50000, 2000);
120025e992a4SHeiner Kallweit RTL_W8(tp, IBISR0, RTL_R8(tp, IBISR0) | 0x20);
120125e992a4SHeiner Kallweit RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01);
120225e992a4SHeiner Kallweit }
120325e992a4SHeiner Kallweit
rtl_dash_loop_wait(struct rtl8169_private * tp,const struct rtl_cond * c,unsigned long usecs,int n,bool high)1204a5eae74fSAtlas Yu static void rtl_dash_loop_wait(struct rtl8169_private *tp,
1205a5eae74fSAtlas Yu const struct rtl_cond *c,
1206a5eae74fSAtlas Yu unsigned long usecs, int n, bool high)
1207a5eae74fSAtlas Yu {
1208a5eae74fSAtlas Yu if (!tp->dash_enabled)
1209a5eae74fSAtlas Yu return;
1210a5eae74fSAtlas Yu rtl_loop_wait(tp, c, usecs, n, high);
1211a5eae74fSAtlas Yu }
1212a5eae74fSAtlas Yu
rtl_dash_loop_wait_high(struct rtl8169_private * tp,const struct rtl_cond * c,unsigned long d,int n)1213a5eae74fSAtlas Yu static void rtl_dash_loop_wait_high(struct rtl8169_private *tp,
1214a5eae74fSAtlas Yu const struct rtl_cond *c,
1215a5eae74fSAtlas Yu unsigned long d, int n)
1216a5eae74fSAtlas Yu {
1217a5eae74fSAtlas Yu rtl_dash_loop_wait(tp, c, d, n, true);
1218a5eae74fSAtlas Yu }
1219a5eae74fSAtlas Yu
rtl_dash_loop_wait_low(struct rtl8169_private * tp,const struct rtl_cond * c,unsigned long d,int n)1220a5eae74fSAtlas Yu static void rtl_dash_loop_wait_low(struct rtl8169_private *tp,
1221a5eae74fSAtlas Yu const struct rtl_cond *c,
1222a5eae74fSAtlas Yu unsigned long d, int n)
1223a5eae74fSAtlas Yu {
1224a5eae74fSAtlas Yu rtl_dash_loop_wait(tp, c, d, n, false);
1225a5eae74fSAtlas Yu }
1226a5eae74fSAtlas Yu
rtl8168dp_driver_start(struct rtl8169_private * tp)122725e992a4SHeiner Kallweit static void rtl8168dp_driver_start(struct rtl8169_private *tp)
122825e992a4SHeiner Kallweit {
122925e992a4SHeiner Kallweit r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START);
1230a5eae74fSAtlas Yu rtl_dash_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
123125e992a4SHeiner Kallweit }
123225e992a4SHeiner Kallweit
rtl8168ep_driver_start(struct rtl8169_private * tp)123325e992a4SHeiner Kallweit static void rtl8168ep_driver_start(struct rtl8169_private *tp)
123425e992a4SHeiner Kallweit {
123525e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START);
1236787c0c04SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
1237a5eae74fSAtlas Yu rtl_dash_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
123825e992a4SHeiner Kallweit }
123925e992a4SHeiner Kallweit
rtl8168_driver_start(struct rtl8169_private * tp)124025e992a4SHeiner Kallweit static void rtl8168_driver_start(struct rtl8169_private *tp)
124125e992a4SHeiner Kallweit {
1242e0d38b58SHeiner Kallweit if (tp->dash_type == RTL_DASH_DP)
124325e992a4SHeiner Kallweit rtl8168dp_driver_start(tp);
1244e0d38b58SHeiner Kallweit else
124525e992a4SHeiner Kallweit rtl8168ep_driver_start(tp);
124625e992a4SHeiner Kallweit }
124725e992a4SHeiner Kallweit
rtl8168dp_driver_stop(struct rtl8169_private * tp)124825e992a4SHeiner Kallweit static void rtl8168dp_driver_stop(struct rtl8169_private *tp)
124925e992a4SHeiner Kallweit {
125025e992a4SHeiner Kallweit r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP);
1251a5eae74fSAtlas Yu rtl_dash_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
125225e992a4SHeiner Kallweit }
125325e992a4SHeiner Kallweit
rtl8168ep_driver_stop(struct rtl8169_private * tp)125425e992a4SHeiner Kallweit static void rtl8168ep_driver_stop(struct rtl8169_private *tp)
125525e992a4SHeiner Kallweit {
125625e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp);
125725e992a4SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP);
1258787c0c04SHeiner Kallweit r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
1259a5eae74fSAtlas Yu rtl_dash_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
126025e992a4SHeiner Kallweit }
126125e992a4SHeiner Kallweit
rtl8168_driver_stop(struct rtl8169_private * tp)126225e992a4SHeiner Kallweit static void rtl8168_driver_stop(struct rtl8169_private *tp)
126325e992a4SHeiner Kallweit {
1264e0d38b58SHeiner Kallweit if (tp->dash_type == RTL_DASH_DP)
126525e992a4SHeiner Kallweit rtl8168dp_driver_stop(tp);
1266e0d38b58SHeiner Kallweit else
126725e992a4SHeiner Kallweit rtl8168ep_driver_stop(tp);
126825e992a4SHeiner Kallweit }
126925e992a4SHeiner Kallweit
r8168dp_check_dash(struct rtl8169_private * tp)127025e992a4SHeiner Kallweit static bool r8168dp_check_dash(struct rtl8169_private *tp)
127125e992a4SHeiner Kallweit {
127225e992a4SHeiner Kallweit u16 reg = rtl8168_get_ocp_reg(tp);
127325e992a4SHeiner Kallweit
1274e0d38b58SHeiner Kallweit return r8168dp_ocp_read(tp, reg) & BIT(15);
127525e992a4SHeiner Kallweit }
127625e992a4SHeiner Kallweit
r8168ep_check_dash(struct rtl8169_private * tp)127725e992a4SHeiner Kallweit static bool r8168ep_check_dash(struct rtl8169_private *tp)
127825e992a4SHeiner Kallweit {
1279e0d38b58SHeiner Kallweit return r8168ep_ocp_read(tp, 0x128) & BIT(0);
128025e992a4SHeiner Kallweit }
128125e992a4SHeiner Kallweit
rtl_dash_is_enabled(struct rtl8169_private * tp)1282c61d525fSChunHao Lin static bool rtl_dash_is_enabled(struct rtl8169_private *tp)
1283c61d525fSChunHao Lin {
1284c61d525fSChunHao Lin switch (tp->dash_type) {
1285c61d525fSChunHao Lin case RTL_DASH_DP:
1286c61d525fSChunHao Lin return r8168dp_check_dash(tp);
1287c61d525fSChunHao Lin case RTL_DASH_EP:
1288c61d525fSChunHao Lin return r8168ep_check_dash(tp);
1289c61d525fSChunHao Lin default:
1290c61d525fSChunHao Lin return false;
1291c61d525fSChunHao Lin }
1292c61d525fSChunHao Lin }
1293c61d525fSChunHao Lin
rtl_get_dash_type(struct rtl8169_private * tp)1294c61d525fSChunHao Lin static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp)
129525e992a4SHeiner Kallweit {
129625e992a4SHeiner Kallweit switch (tp->mac_version) {
129725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_28:
129825e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_31:
1299c61d525fSChunHao Lin return RTL_DASH_DP;
1300133706a9SHeiner Kallweit case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
1301c61d525fSChunHao Lin return RTL_DASH_EP;
130225e992a4SHeiner Kallweit default:
1303e0d38b58SHeiner Kallweit return RTL_DASH_NONE;
130425e992a4SHeiner Kallweit }
130525e992a4SHeiner Kallweit }
130625e992a4SHeiner Kallweit
rtl_set_d3_pll_down(struct rtl8169_private * tp,bool enable)1307128735a1SHeiner Kallweit static void rtl_set_d3_pll_down(struct rtl8169_private *tp, bool enable)
1308128735a1SHeiner Kallweit {
1309128735a1SHeiner Kallweit switch (tp->mac_version) {
1310128735a1SHeiner Kallweit case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
1311d2a04370SHeiner Kallweit case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
1312128735a1SHeiner Kallweit case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
1313128735a1SHeiner Kallweit case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
1314128735a1SHeiner Kallweit if (enable)
1315128735a1SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
1316128735a1SHeiner Kallweit else
1317128735a1SHeiner Kallweit RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | D3_NO_PLL_DOWN);
1318128735a1SHeiner Kallweit break;
1319128735a1SHeiner Kallweit default:
1320128735a1SHeiner Kallweit break;
1321128735a1SHeiner Kallweit }
1322128735a1SHeiner Kallweit }
1323128735a1SHeiner Kallweit
rtl_reset_packet_filter(struct rtl8169_private * tp)132425e992a4SHeiner Kallweit static void rtl_reset_packet_filter(struct rtl8169_private *tp)
132525e992a4SHeiner Kallweit {
132654113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0xdc, BIT(0));
132754113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0xdc, BIT(0));
132825e992a4SHeiner Kallweit }
132925e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_efusear_cond)133025e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_efusear_cond)
133125e992a4SHeiner Kallweit {
133225e992a4SHeiner Kallweit return RTL_R32(tp, EFUSEAR) & EFUSEAR_FLAG;
133325e992a4SHeiner Kallweit }
133425e992a4SHeiner Kallweit
rtl8168d_efuse_read(struct rtl8169_private * tp,int reg_addr)13352992bdfaSHeiner Kallweit u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr)
133625e992a4SHeiner Kallweit {
133725e992a4SHeiner Kallweit RTL_W32(tp, EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
133825e992a4SHeiner Kallweit
1339d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ?
134025e992a4SHeiner Kallweit RTL_R32(tp, EFUSEAR) & EFUSEAR_DATA_MASK : ~0;
134125e992a4SHeiner Kallweit }
134225e992a4SHeiner Kallweit
rtl_get_events(struct rtl8169_private * tp)1343c1d532d2SHeiner Kallweit static u32 rtl_get_events(struct rtl8169_private *tp)
1344c1d532d2SHeiner Kallweit {
1345f1bce4adSHeiner Kallweit if (rtl_is_8125(tp))
1346f1bce4adSHeiner Kallweit return RTL_R32(tp, IntrStatus_8125);
1347f1bce4adSHeiner Kallweit else
1348c1d532d2SHeiner Kallweit return RTL_R16(tp, IntrStatus);
1349c1d532d2SHeiner Kallweit }
1350c1d532d2SHeiner Kallweit
rtl_ack_events(struct rtl8169_private * tp,u32 bits)1351c1d532d2SHeiner Kallweit static void rtl_ack_events(struct rtl8169_private *tp, u32 bits)
135225e992a4SHeiner Kallweit {
1353f1bce4adSHeiner Kallweit if (rtl_is_8125(tp))
1354f1bce4adSHeiner Kallweit RTL_W32(tp, IntrStatus_8125, bits);
1355f1bce4adSHeiner Kallweit else
135625e992a4SHeiner Kallweit RTL_W16(tp, IntrStatus, bits);
135725e992a4SHeiner Kallweit }
135825e992a4SHeiner Kallweit
rtl_irq_disable(struct rtl8169_private * tp)135925e992a4SHeiner Kallweit static void rtl_irq_disable(struct rtl8169_private *tp)
136025e992a4SHeiner Kallweit {
1361f1bce4adSHeiner Kallweit if (rtl_is_8125(tp))
1362f1bce4adSHeiner Kallweit RTL_W32(tp, IntrMask_8125, 0);
1363f1bce4adSHeiner Kallweit else
136425e992a4SHeiner Kallweit RTL_W16(tp, IntrMask, 0);
136525e992a4SHeiner Kallweit }
136625e992a4SHeiner Kallweit
rtl_irq_enable(struct rtl8169_private * tp)136725e992a4SHeiner Kallweit static void rtl_irq_enable(struct rtl8169_private *tp)
136825e992a4SHeiner Kallweit {
1369f1bce4adSHeiner Kallweit if (rtl_is_8125(tp))
1370f1bce4adSHeiner Kallweit RTL_W32(tp, IntrMask_8125, tp->irq_mask);
1371f1bce4adSHeiner Kallweit else
137225e992a4SHeiner Kallweit RTL_W16(tp, IntrMask, tp->irq_mask);
137325e992a4SHeiner Kallweit }
137425e992a4SHeiner Kallweit
rtl8169_irq_mask_and_ack(struct rtl8169_private * tp)137525e992a4SHeiner Kallweit static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp)
137625e992a4SHeiner Kallweit {
137725e992a4SHeiner Kallweit rtl_irq_disable(tp);
1378c1d532d2SHeiner Kallweit rtl_ack_events(tp, 0xffffffff);
1379711463f8SHeiner Kallweit rtl_pci_commit(tp);
138025e992a4SHeiner Kallweit }
138125e992a4SHeiner Kallweit
rtl_link_chg_patch(struct rtl8169_private * tp)138225e992a4SHeiner Kallweit static void rtl_link_chg_patch(struct rtl8169_private *tp)
138325e992a4SHeiner Kallweit {
138425e992a4SHeiner Kallweit struct phy_device *phydev = tp->phydev;
138525e992a4SHeiner Kallweit
138625e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34 ||
138725e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_38) {
138825e992a4SHeiner Kallweit if (phydev->speed == SPEED_1000) {
138925e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011);
139025e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005);
139125e992a4SHeiner Kallweit } else if (phydev->speed == SPEED_100) {
139225e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f);
139325e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005);
139425e992a4SHeiner Kallweit } else {
139525e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f);
139625e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f);
139725e992a4SHeiner Kallweit }
139825e992a4SHeiner Kallweit rtl_reset_packet_filter(tp);
139925e992a4SHeiner Kallweit } else if (tp->mac_version == RTL_GIGA_MAC_VER_35 ||
140025e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_36) {
140125e992a4SHeiner Kallweit if (phydev->speed == SPEED_1000) {
140225e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011);
140325e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005);
140425e992a4SHeiner Kallweit } else {
140525e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f);
140625e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f);
140725e992a4SHeiner Kallweit }
140825e992a4SHeiner Kallweit } else if (tp->mac_version == RTL_GIGA_MAC_VER_37) {
140925e992a4SHeiner Kallweit if (phydev->speed == SPEED_10) {
141025e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02);
141125e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060a);
141225e992a4SHeiner Kallweit } else {
141325e992a4SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000);
141425e992a4SHeiner Kallweit }
141525e992a4SHeiner Kallweit }
141625e992a4SHeiner Kallweit }
141725e992a4SHeiner Kallweit
141825e992a4SHeiner Kallweit #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
141925e992a4SHeiner Kallweit
rtl8169_get_wol(struct net_device * dev,struct ethtool_wolinfo * wol)142025e992a4SHeiner Kallweit static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
142125e992a4SHeiner Kallweit {
142225e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
142325e992a4SHeiner Kallweit
142425e992a4SHeiner Kallweit wol->supported = WAKE_ANY;
142525e992a4SHeiner Kallweit wol->wolopts = tp->saved_wolopts;
142625e992a4SHeiner Kallweit }
142725e992a4SHeiner Kallweit
__rtl8169_set_wol(struct rtl8169_private * tp,u32 wolopts)142825e992a4SHeiner Kallweit static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
142925e992a4SHeiner Kallweit {
143025e992a4SHeiner Kallweit static const struct {
143125e992a4SHeiner Kallweit u32 opt;
143225e992a4SHeiner Kallweit u16 reg;
143325e992a4SHeiner Kallweit u8 mask;
143425e992a4SHeiner Kallweit } cfg[] = {
143525e992a4SHeiner Kallweit { WAKE_PHY, Config3, LinkUp },
143625e992a4SHeiner Kallweit { WAKE_UCAST, Config5, UWF },
143725e992a4SHeiner Kallweit { WAKE_BCAST, Config5, BWF },
143825e992a4SHeiner Kallweit { WAKE_MCAST, Config5, MWF },
143925e992a4SHeiner Kallweit { WAKE_ANY, Config5, LanWake },
144025e992a4SHeiner Kallweit { WAKE_MAGIC, Config3, MagicPacket }
144125e992a4SHeiner Kallweit };
1442f1bce4adSHeiner Kallweit unsigned int i, tmp = ARRAY_SIZE(cfg);
14436bc6c4e6SHeiner Kallweit unsigned long flags;
144425e992a4SHeiner Kallweit u8 options;
144525e992a4SHeiner Kallweit
144625e992a4SHeiner Kallweit rtl_unlock_config_regs(tp);
144725e992a4SHeiner Kallweit
14489e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp)) {
1449f1bce4adSHeiner Kallweit tmp--;
145025e992a4SHeiner Kallweit if (wolopts & WAKE_MAGIC)
145154113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x0dc, MagicPacket_v2);
145225e992a4SHeiner Kallweit else
145354113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x0dc, MagicPacket_v2);
1454f1bce4adSHeiner Kallweit } else if (rtl_is_8125(tp)) {
1455f1bce4adSHeiner Kallweit tmp--;
1456f1bce4adSHeiner Kallweit if (wolopts & WAKE_MAGIC)
1457f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b6, 0, BIT(0));
1458f1bce4adSHeiner Kallweit else
1459f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0);
146025e992a4SHeiner Kallweit }
146125e992a4SHeiner Kallweit
1462d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_irqsave(&tp->config25_lock, flags);
146325e992a4SHeiner Kallweit for (i = 0; i < tmp; i++) {
146425e992a4SHeiner Kallweit options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask;
146525e992a4SHeiner Kallweit if (wolopts & cfg[i].opt)
146625e992a4SHeiner Kallweit options |= cfg[i].mask;
146725e992a4SHeiner Kallweit RTL_W8(tp, cfg[i].reg, options);
146825e992a4SHeiner Kallweit }
1469d6c36cbcSSebastian Andrzej Siewior raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
147025e992a4SHeiner Kallweit
147125e992a4SHeiner Kallweit switch (tp->mac_version) {
1472edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
147325e992a4SHeiner Kallweit options = RTL_R8(tp, Config1) & ~PMEnable;
147425e992a4SHeiner Kallweit if (wolopts)
147525e992a4SHeiner Kallweit options |= PMEnable;
147625e992a4SHeiner Kallweit RTL_W8(tp, Config1, options);
147725e992a4SHeiner Kallweit break;
1478edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_34:
1479edcde3eeSHeiner Kallweit case RTL_GIGA_MAC_VER_37:
14800439297bSHeiner Kallweit case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
148125e992a4SHeiner Kallweit if (wolopts)
14826bc6c4e6SHeiner Kallweit rtl_mod_config2(tp, 0, PME_SIGNAL);
14836bc6c4e6SHeiner Kallweit else
14846bc6c4e6SHeiner Kallweit rtl_mod_config2(tp, PME_SIGNAL, 0);
148525e992a4SHeiner Kallweit break;
1486edcde3eeSHeiner Kallweit default:
1487edcde3eeSHeiner Kallweit break;
148825e992a4SHeiner Kallweit }
148925e992a4SHeiner Kallweit
149025e992a4SHeiner Kallweit rtl_lock_config_regs(tp);
149125e992a4SHeiner Kallweit
149225e992a4SHeiner Kallweit device_set_wakeup_enable(tp_to_dev(tp), wolopts);
149354744510SHeiner Kallweit
1494c61d525fSChunHao Lin if (!tp->dash_enabled) {
1495128735a1SHeiner Kallweit rtl_set_d3_pll_down(tp, !wolopts);
1496398fd408SHeiner Kallweit tp->dev->wol_enabled = wolopts ? 1 : 0;
149725e992a4SHeiner Kallweit }
149854744510SHeiner Kallweit }
149925e992a4SHeiner Kallweit
rtl8169_set_wol(struct net_device * dev,struct ethtool_wolinfo * wol)150025e992a4SHeiner Kallweit static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
150125e992a4SHeiner Kallweit {
150225e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
150325e992a4SHeiner Kallweit
150425e992a4SHeiner Kallweit if (wol->wolopts & ~WAKE_ANY)
150525e992a4SHeiner Kallweit return -EINVAL;
150625e992a4SHeiner Kallweit
150725e992a4SHeiner Kallweit tp->saved_wolopts = wol->wolopts;
150825e992a4SHeiner Kallweit __rtl8169_set_wol(tp, tp->saved_wolopts);
150925e992a4SHeiner Kallweit
151025e992a4SHeiner Kallweit return 0;
151125e992a4SHeiner Kallweit }
151225e992a4SHeiner Kallweit
rtl8169_get_drvinfo(struct net_device * dev,struct ethtool_drvinfo * info)151325e992a4SHeiner Kallweit static void rtl8169_get_drvinfo(struct net_device *dev,
151425e992a4SHeiner Kallweit struct ethtool_drvinfo *info)
151525e992a4SHeiner Kallweit {
151625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
151725e992a4SHeiner Kallweit struct rtl_fw *rtl_fw = tp->rtl_fw;
151825e992a4SHeiner Kallweit
1519f029c781SWolfram Sang strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
1520f029c781SWolfram Sang strscpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info));
152125e992a4SHeiner Kallweit BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version));
152225e992a4SHeiner Kallweit if (rtl_fw)
1523f029c781SWolfram Sang strscpy(info->fw_version, rtl_fw->version,
152425e992a4SHeiner Kallweit sizeof(info->fw_version));
152525e992a4SHeiner Kallweit }
152625e992a4SHeiner Kallweit
rtl8169_get_regs_len(struct net_device * dev)152725e992a4SHeiner Kallweit static int rtl8169_get_regs_len(struct net_device *dev)
152825e992a4SHeiner Kallweit {
152925e992a4SHeiner Kallweit return R8169_REGS_SIZE;
153025e992a4SHeiner Kallweit }
153125e992a4SHeiner Kallweit
rtl8169_fix_features(struct net_device * dev,netdev_features_t features)153225e992a4SHeiner Kallweit static netdev_features_t rtl8169_fix_features(struct net_device *dev,
153325e992a4SHeiner Kallweit netdev_features_t features)
153425e992a4SHeiner Kallweit {
153525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
153625e992a4SHeiner Kallweit
153725e992a4SHeiner Kallweit if (dev->mtu > TD_MSS_MAX)
153825e992a4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO;
153925e992a4SHeiner Kallweit
1540a8ec173aSHeiner Kallweit if (dev->mtu > ETH_DATA_LEN &&
154125e992a4SHeiner Kallweit tp->mac_version > RTL_GIGA_MAC_VER_06)
15427cb83b21SHeiner Kallweit features &= ~(NETIF_F_CSUM_MASK | NETIF_F_ALL_TSO);
154325e992a4SHeiner Kallweit
154425e992a4SHeiner Kallweit return features;
154525e992a4SHeiner Kallweit }
154625e992a4SHeiner Kallweit
rtl_set_rx_config_features(struct rtl8169_private * tp,netdev_features_t features)154710478283SHeiner Kallweit static void rtl_set_rx_config_features(struct rtl8169_private *tp,
154825e992a4SHeiner Kallweit netdev_features_t features)
154925e992a4SHeiner Kallweit {
155010478283SHeiner Kallweit u32 rx_config = RTL_R32(tp, RxConfig);
155125e992a4SHeiner Kallweit
155225e992a4SHeiner Kallweit if (features & NETIF_F_RXALL)
155310478283SHeiner Kallweit rx_config |= RX_CONFIG_ACCEPT_ERR_MASK;
155425e992a4SHeiner Kallweit else
155510478283SHeiner Kallweit rx_config &= ~RX_CONFIG_ACCEPT_ERR_MASK;
155625e992a4SHeiner Kallweit
1557f1bce4adSHeiner Kallweit if (rtl_is_8125(tp)) {
1558f1bce4adSHeiner Kallweit if (features & NETIF_F_HW_VLAN_CTAG_RX)
1559f1bce4adSHeiner Kallweit rx_config |= RX_VLAN_8125;
1560f1bce4adSHeiner Kallweit else
1561f1bce4adSHeiner Kallweit rx_config &= ~RX_VLAN_8125;
1562f1bce4adSHeiner Kallweit }
1563f1bce4adSHeiner Kallweit
156425e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, rx_config);
156510478283SHeiner Kallweit }
156610478283SHeiner Kallweit
rtl8169_set_features(struct net_device * dev,netdev_features_t features)156710478283SHeiner Kallweit static int rtl8169_set_features(struct net_device *dev,
156810478283SHeiner Kallweit netdev_features_t features)
156910478283SHeiner Kallweit {
157010478283SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
157110478283SHeiner Kallweit
157210478283SHeiner Kallweit rtl_set_rx_config_features(tp, features);
157325e992a4SHeiner Kallweit
157425e992a4SHeiner Kallweit if (features & NETIF_F_RXCSUM)
157525e992a4SHeiner Kallweit tp->cp_cmd |= RxChkSum;
157625e992a4SHeiner Kallweit else
157725e992a4SHeiner Kallweit tp->cp_cmd &= ~RxChkSum;
157825e992a4SHeiner Kallweit
1579f1bce4adSHeiner Kallweit if (!rtl_is_8125(tp)) {
158025e992a4SHeiner Kallweit if (features & NETIF_F_HW_VLAN_CTAG_RX)
158125e992a4SHeiner Kallweit tp->cp_cmd |= RxVlan;
158225e992a4SHeiner Kallweit else
158325e992a4SHeiner Kallweit tp->cp_cmd &= ~RxVlan;
1584f1bce4adSHeiner Kallweit }
158525e992a4SHeiner Kallweit
158625e992a4SHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd);
1587711463f8SHeiner Kallweit rtl_pci_commit(tp);
158825e992a4SHeiner Kallweit
158925e992a4SHeiner Kallweit return 0;
159025e992a4SHeiner Kallweit }
159125e992a4SHeiner Kallweit
rtl8169_tx_vlan_tag(struct sk_buff * skb)159225e992a4SHeiner Kallweit static inline u32 rtl8169_tx_vlan_tag(struct sk_buff *skb)
159325e992a4SHeiner Kallweit {
159425e992a4SHeiner Kallweit return (skb_vlan_tag_present(skb)) ?
15957424edbbSHeiner Kallweit TxVlanTag | swab16(skb_vlan_tag_get(skb)) : 0x00;
159625e992a4SHeiner Kallweit }
159725e992a4SHeiner Kallweit
rtl8169_rx_vlan_tag(struct RxDesc * desc,struct sk_buff * skb)159825e992a4SHeiner Kallweit static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
159925e992a4SHeiner Kallweit {
160025e992a4SHeiner Kallweit u32 opts2 = le32_to_cpu(desc->opts2);
160125e992a4SHeiner Kallweit
160225e992a4SHeiner Kallweit if (opts2 & RxVlanTag)
16037424edbbSHeiner Kallweit __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), swab16(opts2 & 0xffff));
160425e992a4SHeiner Kallweit }
160525e992a4SHeiner Kallweit
rtl8169_get_regs(struct net_device * dev,struct ethtool_regs * regs,void * p)160625e992a4SHeiner Kallweit static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
160725e992a4SHeiner Kallweit void *p)
160825e992a4SHeiner Kallweit {
160925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
161025e992a4SHeiner Kallweit u32 __iomem *data = tp->mmio_addr;
161125e992a4SHeiner Kallweit u32 *dw = p;
161225e992a4SHeiner Kallweit int i;
161325e992a4SHeiner Kallweit
161425e992a4SHeiner Kallweit for (i = 0; i < R8169_REGS_SIZE; i += 4)
161525e992a4SHeiner Kallweit memcpy_fromio(dw++, data++, 4);
161625e992a4SHeiner Kallweit }
161725e992a4SHeiner Kallweit
161825e992a4SHeiner Kallweit static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
161925e992a4SHeiner Kallweit "tx_packets",
162025e992a4SHeiner Kallweit "rx_packets",
162125e992a4SHeiner Kallweit "tx_errors",
162225e992a4SHeiner Kallweit "rx_errors",
162325e992a4SHeiner Kallweit "rx_missed",
162425e992a4SHeiner Kallweit "align_errors",
162525e992a4SHeiner Kallweit "tx_single_collisions",
162625e992a4SHeiner Kallweit "tx_multi_collisions",
162725e992a4SHeiner Kallweit "unicast",
162825e992a4SHeiner Kallweit "broadcast",
162925e992a4SHeiner Kallweit "multicast",
163025e992a4SHeiner Kallweit "tx_aborted",
163125e992a4SHeiner Kallweit "tx_underrun",
163225e992a4SHeiner Kallweit };
163325e992a4SHeiner Kallweit
rtl8169_get_sset_count(struct net_device * dev,int sset)163425e992a4SHeiner Kallweit static int rtl8169_get_sset_count(struct net_device *dev, int sset)
163525e992a4SHeiner Kallweit {
163625e992a4SHeiner Kallweit switch (sset) {
163725e992a4SHeiner Kallweit case ETH_SS_STATS:
163825e992a4SHeiner Kallweit return ARRAY_SIZE(rtl8169_gstrings);
163925e992a4SHeiner Kallweit default:
164025e992a4SHeiner Kallweit return -EOPNOTSUPP;
164125e992a4SHeiner Kallweit }
164225e992a4SHeiner Kallweit }
164325e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_counters_cond)164425e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_counters_cond)
164525e992a4SHeiner Kallweit {
164625e992a4SHeiner Kallweit return RTL_R32(tp, CounterAddrLow) & (CounterReset | CounterDump);
164725e992a4SHeiner Kallweit }
164825e992a4SHeiner Kallweit
rtl8169_do_counters(struct rtl8169_private * tp,u32 counter_cmd)1649d56f58ceSHeiner Kallweit static void rtl8169_do_counters(struct rtl8169_private *tp, u32 counter_cmd)
165025e992a4SHeiner Kallweit {
1651b498ee3fSHeiner Kallweit u32 cmd = lower_32_bits(tp->counters_phys_addr);
165225e992a4SHeiner Kallweit
1653b498ee3fSHeiner Kallweit RTL_W32(tp, CounterAddrHigh, upper_32_bits(tp->counters_phys_addr));
1654711463f8SHeiner Kallweit rtl_pci_commit(tp);
165525e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrLow, cmd);
165625e992a4SHeiner Kallweit RTL_W32(tp, CounterAddrLow, cmd | counter_cmd);
165725e992a4SHeiner Kallweit
1658d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_counters_cond, 10, 1000);
165925e992a4SHeiner Kallweit }
166025e992a4SHeiner Kallweit
rtl8169_update_counters(struct rtl8169_private * tp)1661d56f58ceSHeiner Kallweit static void rtl8169_update_counters(struct rtl8169_private *tp)
166225e992a4SHeiner Kallweit {
166325e992a4SHeiner Kallweit u8 val = RTL_R8(tp, ChipCmd);
166425e992a4SHeiner Kallweit
166525e992a4SHeiner Kallweit /*
166625e992a4SHeiner Kallweit * Some chips are unable to dump tally counters when the receiver
166725e992a4SHeiner Kallweit * is disabled. If 0xff chip may be in a PCI power-save state.
166825e992a4SHeiner Kallweit */
1669d56f58ceSHeiner Kallweit if (val & CmdRxEnb && val != 0xff)
1670d56f58ceSHeiner Kallweit rtl8169_do_counters(tp, CounterDump);
167125e992a4SHeiner Kallweit }
167225e992a4SHeiner Kallweit
rtl8169_init_counter_offsets(struct rtl8169_private * tp)1673d56f58ceSHeiner Kallweit static void rtl8169_init_counter_offsets(struct rtl8169_private *tp)
167425e992a4SHeiner Kallweit {
167525e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters;
167625e992a4SHeiner Kallweit
167725e992a4SHeiner Kallweit /*
167825e992a4SHeiner Kallweit * rtl8169_init_counter_offsets is called from rtl_open. On chip
167925e992a4SHeiner Kallweit * versions prior to RTL_GIGA_MAC_VER_19 the tally counters are only
168025e992a4SHeiner Kallweit * reset by a power cycle, while the counter values collected by the
168125e992a4SHeiner Kallweit * driver are reset at every driver unload/load cycle.
168225e992a4SHeiner Kallweit *
168325e992a4SHeiner Kallweit * To make sure the HW values returned by @get_stats64 match the SW
168425e992a4SHeiner Kallweit * values, we collect the initial values at first open(*) and use them
168525e992a4SHeiner Kallweit * as offsets to normalize the values returned by @get_stats64.
168625e992a4SHeiner Kallweit *
168725e992a4SHeiner Kallweit * (*) We can't call rtl8169_init_counter_offsets from rtl_init_one
168825e992a4SHeiner Kallweit * for the reason stated in rtl8169_update_counters; CmdRxEnb is only
168925e992a4SHeiner Kallweit * set at open time by rtl_hw_start.
169025e992a4SHeiner Kallweit */
169125e992a4SHeiner Kallweit
169225e992a4SHeiner Kallweit if (tp->tc_offset.inited)
1693d56f58ceSHeiner Kallweit return;
169425e992a4SHeiner Kallweit
16956b4f5031SHeiner Kallweit if (tp->mac_version >= RTL_GIGA_MAC_VER_19) {
16966b4f5031SHeiner Kallweit rtl8169_do_counters(tp, CounterReset);
16976b4f5031SHeiner Kallweit } else {
1698d56f58ceSHeiner Kallweit rtl8169_update_counters(tp);
169925e992a4SHeiner Kallweit tp->tc_offset.tx_errors = counters->tx_errors;
170025e992a4SHeiner Kallweit tp->tc_offset.tx_multi_collision = counters->tx_multi_collision;
170125e992a4SHeiner Kallweit tp->tc_offset.tx_aborted = counters->tx_aborted;
17020da3359aSHeiner Kallweit tp->tc_offset.rx_missed = counters->rx_missed;
17036b4f5031SHeiner Kallweit }
17046b4f5031SHeiner Kallweit
170525e992a4SHeiner Kallweit tp->tc_offset.inited = true;
170625e992a4SHeiner Kallweit }
170725e992a4SHeiner Kallweit
rtl8169_get_ethtool_stats(struct net_device * dev,struct ethtool_stats * stats,u64 * data)170825e992a4SHeiner Kallweit static void rtl8169_get_ethtool_stats(struct net_device *dev,
170925e992a4SHeiner Kallweit struct ethtool_stats *stats, u64 *data)
171025e992a4SHeiner Kallweit {
171125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
1712ec2f204bSHeiner Kallweit struct rtl8169_counters *counters;
171325e992a4SHeiner Kallweit
1714ec2f204bSHeiner Kallweit counters = tp->counters;
171525e992a4SHeiner Kallweit rtl8169_update_counters(tp);
171625e992a4SHeiner Kallweit
171725e992a4SHeiner Kallweit data[0] = le64_to_cpu(counters->tx_packets);
171825e992a4SHeiner Kallweit data[1] = le64_to_cpu(counters->rx_packets);
171925e992a4SHeiner Kallweit data[2] = le64_to_cpu(counters->tx_errors);
172025e992a4SHeiner Kallweit data[3] = le32_to_cpu(counters->rx_errors);
172125e992a4SHeiner Kallweit data[4] = le16_to_cpu(counters->rx_missed);
172225e992a4SHeiner Kallweit data[5] = le16_to_cpu(counters->align_errors);
172325e992a4SHeiner Kallweit data[6] = le32_to_cpu(counters->tx_one_collision);
172425e992a4SHeiner Kallweit data[7] = le32_to_cpu(counters->tx_multi_collision);
172525e992a4SHeiner Kallweit data[8] = le64_to_cpu(counters->rx_unicast);
172625e992a4SHeiner Kallweit data[9] = le64_to_cpu(counters->rx_broadcast);
172725e992a4SHeiner Kallweit data[10] = le32_to_cpu(counters->rx_multicast);
172825e992a4SHeiner Kallweit data[11] = le16_to_cpu(counters->tx_aborted);
172925e992a4SHeiner Kallweit data[12] = le16_to_cpu(counters->tx_underun);
173025e992a4SHeiner Kallweit }
173125e992a4SHeiner Kallweit
rtl8169_get_strings(struct net_device * dev,u32 stringset,u8 * data)173225e992a4SHeiner Kallweit static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
173325e992a4SHeiner Kallweit {
173425e992a4SHeiner Kallweit switch(stringset) {
173525e992a4SHeiner Kallweit case ETH_SS_STATS:
1736da5ac772SKees Cook memcpy(data, rtl8169_gstrings, sizeof(rtl8169_gstrings));
173725e992a4SHeiner Kallweit break;
173825e992a4SHeiner Kallweit }
173925e992a4SHeiner Kallweit }
174025e992a4SHeiner Kallweit
174125e992a4SHeiner Kallweit /*
174225e992a4SHeiner Kallweit * Interrupt coalescing
174325e992a4SHeiner Kallweit *
174425e992a4SHeiner Kallweit * > 1 - the availability of the IntrMitigate (0xe2) register through the
174525e992a4SHeiner Kallweit * > 8169, 8168 and 810x line of chipsets
174625e992a4SHeiner Kallweit *
174725e992a4SHeiner Kallweit * 8169, 8168, and 8136(810x) serial chipsets support it.
174825e992a4SHeiner Kallweit *
174925e992a4SHeiner Kallweit * > 2 - the Tx timer unit at gigabit speed
175025e992a4SHeiner Kallweit *
175125e992a4SHeiner Kallweit * The unit of the timer depends on both the speed and the setting of CPlusCmd
175225e992a4SHeiner Kallweit * (0xe0) bit 1 and bit 0.
175325e992a4SHeiner Kallweit *
175425e992a4SHeiner Kallweit * For 8169
175525e992a4SHeiner Kallweit * bit[1:0] \ speed 1000M 100M 10M
175625e992a4SHeiner Kallweit * 0 0 320ns 2.56us 40.96us
175725e992a4SHeiner Kallweit * 0 1 2.56us 20.48us 327.7us
175825e992a4SHeiner Kallweit * 1 0 5.12us 40.96us 655.4us
175925e992a4SHeiner Kallweit * 1 1 10.24us 81.92us 1.31ms
176025e992a4SHeiner Kallweit *
176125e992a4SHeiner Kallweit * For the other
176225e992a4SHeiner Kallweit * bit[1:0] \ speed 1000M 100M 10M
176325e992a4SHeiner Kallweit * 0 0 5us 2.56us 40.96us
176425e992a4SHeiner Kallweit * 0 1 40us 20.48us 327.7us
176525e992a4SHeiner Kallweit * 1 0 80us 40.96us 655.4us
176625e992a4SHeiner Kallweit * 1 1 160us 81.92us 1.31ms
176725e992a4SHeiner Kallweit */
176825e992a4SHeiner Kallweit
176925e992a4SHeiner Kallweit /* rx/tx scale factors for all CPlusCmd[0:1] cases */
177025e992a4SHeiner Kallweit struct rtl_coalesce_info {
177125e992a4SHeiner Kallweit u32 speed;
17722815b305SHeiner Kallweit u32 scale_nsecs[4];
177325e992a4SHeiner Kallweit };
177425e992a4SHeiner Kallweit
17752815b305SHeiner Kallweit /* produce array with base delay *1, *8, *8*2, *8*2*2 */
17762815b305SHeiner Kallweit #define COALESCE_DELAY(d) { (d), 8 * (d), 16 * (d), 32 * (d) }
17772815b305SHeiner Kallweit
177825e992a4SHeiner Kallweit static const struct rtl_coalesce_info rtl_coalesce_info_8169[] = {
17792815b305SHeiner Kallweit { SPEED_1000, COALESCE_DELAY(320) },
178051f6291bSHeiner Kallweit { SPEED_100, COALESCE_DELAY(2560) },
178151f6291bSHeiner Kallweit { SPEED_10, COALESCE_DELAY(40960) },
178225e992a4SHeiner Kallweit { 0 },
178325e992a4SHeiner Kallweit };
178425e992a4SHeiner Kallweit
178525e992a4SHeiner Kallweit static const struct rtl_coalesce_info rtl_coalesce_info_8168_8136[] = {
17862815b305SHeiner Kallweit { SPEED_1000, COALESCE_DELAY(5000) },
178751f6291bSHeiner Kallweit { SPEED_100, COALESCE_DELAY(2560) },
178851f6291bSHeiner Kallweit { SPEED_10, COALESCE_DELAY(40960) },
178925e992a4SHeiner Kallweit { 0 },
179025e992a4SHeiner Kallweit };
17912815b305SHeiner Kallweit #undef COALESCE_DELAY
179225e992a4SHeiner Kallweit
179325e992a4SHeiner Kallweit /* get rx/tx scale vector corresponding to current speed */
1794ef2c0a78SHeiner Kallweit static const struct rtl_coalesce_info *
rtl_coalesce_info(struct rtl8169_private * tp)1795ef2c0a78SHeiner Kallweit rtl_coalesce_info(struct rtl8169_private *tp)
179625e992a4SHeiner Kallweit {
179725e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci;
179825e992a4SHeiner Kallweit
179920023d3eSHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
180020023d3eSHeiner Kallweit ci = rtl_coalesce_info_8169;
180120023d3eSHeiner Kallweit else
180220023d3eSHeiner Kallweit ci = rtl_coalesce_info_8168_8136;
180325e992a4SHeiner Kallweit
180451f6291bSHeiner Kallweit /* if speed is unknown assume highest one */
180551f6291bSHeiner Kallweit if (tp->phydev->speed == SPEED_UNKNOWN)
180651f6291bSHeiner Kallweit return ci;
180751f6291bSHeiner Kallweit
180820023d3eSHeiner Kallweit for (; ci->speed; ci++) {
180920023d3eSHeiner Kallweit if (tp->phydev->speed == ci->speed)
181025e992a4SHeiner Kallweit return ci;
181125e992a4SHeiner Kallweit }
181225e992a4SHeiner Kallweit
181325e992a4SHeiner Kallweit return ERR_PTR(-ELNRNG);
181425e992a4SHeiner Kallweit }
181525e992a4SHeiner Kallweit
rtl_get_coalesce(struct net_device * dev,struct ethtool_coalesce * ec,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)1816f3ccfda1SYufeng Mo static int rtl_get_coalesce(struct net_device *dev,
1817f3ccfda1SYufeng Mo struct ethtool_coalesce *ec,
1818f3ccfda1SYufeng Mo struct kernel_ethtool_coalesce *kernel_coal,
1819f3ccfda1SYufeng Mo struct netlink_ext_ack *extack)
182025e992a4SHeiner Kallweit {
182125e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
182225e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci;
18236cf96dd4SHeiner Kallweit u32 scale, c_us, c_fr;
18246cf96dd4SHeiner Kallweit u16 intrmit;
182525e992a4SHeiner Kallweit
1826f1bce4adSHeiner Kallweit if (rtl_is_8125(tp))
1827f1bce4adSHeiner Kallweit return -EOPNOTSUPP;
1828f1bce4adSHeiner Kallweit
182925e992a4SHeiner Kallweit memset(ec, 0, sizeof(*ec));
183025e992a4SHeiner Kallweit
183125e992a4SHeiner Kallweit /* get rx/tx scale corresponding to current speed and CPlusCmd[0:1] */
1832ef2c0a78SHeiner Kallweit ci = rtl_coalesce_info(tp);
183325e992a4SHeiner Kallweit if (IS_ERR(ci))
183425e992a4SHeiner Kallweit return PTR_ERR(ci);
183525e992a4SHeiner Kallweit
18362815b305SHeiner Kallweit scale = ci->scale_nsecs[tp->cp_cmd & INTT_MASK];
183725e992a4SHeiner Kallweit
18386cf96dd4SHeiner Kallweit intrmit = RTL_R16(tp, IntrMitigate);
183925e992a4SHeiner Kallweit
18406cf96dd4SHeiner Kallweit c_us = FIELD_GET(RTL_COALESCE_TX_USECS, intrmit);
18416cf96dd4SHeiner Kallweit ec->tx_coalesce_usecs = DIV_ROUND_UP(c_us * scale, 1000);
184225e992a4SHeiner Kallweit
18436cf96dd4SHeiner Kallweit c_fr = FIELD_GET(RTL_COALESCE_TX_FRAMES, intrmit);
18446cf96dd4SHeiner Kallweit /* ethtool_coalesce states usecs and max_frames must not both be 0 */
18456cf96dd4SHeiner Kallweit ec->tx_max_coalesced_frames = (c_us || c_fr) ? c_fr * 4 : 1;
18466cf96dd4SHeiner Kallweit
18476cf96dd4SHeiner Kallweit c_us = FIELD_GET(RTL_COALESCE_RX_USECS, intrmit);
18486cf96dd4SHeiner Kallweit ec->rx_coalesce_usecs = DIV_ROUND_UP(c_us * scale, 1000);
18496cf96dd4SHeiner Kallweit
18506cf96dd4SHeiner Kallweit c_fr = FIELD_GET(RTL_COALESCE_RX_FRAMES, intrmit);
18516cf96dd4SHeiner Kallweit ec->rx_max_coalesced_frames = (c_us || c_fr) ? c_fr * 4 : 1;
185225e992a4SHeiner Kallweit
185325e992a4SHeiner Kallweit return 0;
185425e992a4SHeiner Kallweit }
185525e992a4SHeiner Kallweit
1856cb9d97deSHeiner Kallweit /* choose appropriate scale factor and CPlusCmd[0:1] for (speed, usec) */
rtl_coalesce_choose_scale(struct rtl8169_private * tp,u32 usec,u16 * cp01)1857cb9d97deSHeiner Kallweit static int rtl_coalesce_choose_scale(struct rtl8169_private *tp, u32 usec,
18582815b305SHeiner Kallweit u16 *cp01)
185925e992a4SHeiner Kallweit {
186025e992a4SHeiner Kallweit const struct rtl_coalesce_info *ci;
186125e992a4SHeiner Kallweit u16 i;
186225e992a4SHeiner Kallweit
1863ef2c0a78SHeiner Kallweit ci = rtl_coalesce_info(tp);
186425e992a4SHeiner Kallweit if (IS_ERR(ci))
18652815b305SHeiner Kallweit return PTR_ERR(ci);
186625e992a4SHeiner Kallweit
186725e992a4SHeiner Kallweit for (i = 0; i < 4; i++) {
1868cb9d97deSHeiner Kallweit if (usec <= ci->scale_nsecs[i] * RTL_COALESCE_T_MAX / 1000U) {
186925e992a4SHeiner Kallweit *cp01 = i;
18702815b305SHeiner Kallweit return ci->scale_nsecs[i];
187125e992a4SHeiner Kallweit }
187225e992a4SHeiner Kallweit }
187325e992a4SHeiner Kallweit
1874cb9d97deSHeiner Kallweit return -ERANGE;
187525e992a4SHeiner Kallweit }
187625e992a4SHeiner Kallweit
rtl_set_coalesce(struct net_device * dev,struct ethtool_coalesce * ec,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)1877f3ccfda1SYufeng Mo static int rtl_set_coalesce(struct net_device *dev,
1878f3ccfda1SYufeng Mo struct ethtool_coalesce *ec,
1879f3ccfda1SYufeng Mo struct kernel_ethtool_coalesce *kernel_coal,
1880f3ccfda1SYufeng Mo struct netlink_ext_ack *extack)
188125e992a4SHeiner Kallweit {
188225e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
18832b3e48b6SHeiner Kallweit u32 tx_fr = ec->tx_max_coalesced_frames;
18842b3e48b6SHeiner Kallweit u32 rx_fr = ec->rx_max_coalesced_frames;
18852b3e48b6SHeiner Kallweit u32 coal_usec_max, units;
18862815b305SHeiner Kallweit u16 w = 0, cp01 = 0;
18872b3e48b6SHeiner Kallweit int scale;
188825e992a4SHeiner Kallweit
1889f1bce4adSHeiner Kallweit if (rtl_is_8125(tp))
1890f1bce4adSHeiner Kallweit return -EOPNOTSUPP;
1891f1bce4adSHeiner Kallweit
18922b3e48b6SHeiner Kallweit if (rx_fr > RTL_COALESCE_FRAME_MAX || tx_fr > RTL_COALESCE_FRAME_MAX)
18932b3e48b6SHeiner Kallweit return -ERANGE;
18942b3e48b6SHeiner Kallweit
1895cb9d97deSHeiner Kallweit coal_usec_max = max(ec->rx_coalesce_usecs, ec->tx_coalesce_usecs);
1896cb9d97deSHeiner Kallweit scale = rtl_coalesce_choose_scale(tp, coal_usec_max, &cp01);
18972815b305SHeiner Kallweit if (scale < 0)
18982815b305SHeiner Kallweit return scale;
189925e992a4SHeiner Kallweit
19002b3e48b6SHeiner Kallweit /* Accept max_frames=1 we returned in rtl_get_coalesce. Accept it
19012b3e48b6SHeiner Kallweit * not only when usecs=0 because of e.g. the following scenario:
190225e992a4SHeiner Kallweit *
190325e992a4SHeiner Kallweit * - both rx_usecs=0 & rx_frames=0 in hardware (no delay on RX)
190425e992a4SHeiner Kallweit * - rtl_get_coalesce returns rx_usecs=0, rx_frames=1
190525e992a4SHeiner Kallweit * - then user does `ethtool -C eth0 rx-usecs 100`
190625e992a4SHeiner Kallweit *
19072b3e48b6SHeiner Kallweit * Since ethtool sends to kernel whole ethtool_coalesce settings,
19082b3e48b6SHeiner Kallweit * if we want to ignore rx_frames then it has to be set to 0.
190925e992a4SHeiner Kallweit */
19102b3e48b6SHeiner Kallweit if (rx_fr == 1)
19112b3e48b6SHeiner Kallweit rx_fr = 0;
19122b3e48b6SHeiner Kallweit if (tx_fr == 1)
19132b3e48b6SHeiner Kallweit tx_fr = 0;
191425e992a4SHeiner Kallweit
191581496b72SHeiner Kallweit /* HW requires time limit to be set if frame limit is set */
191681496b72SHeiner Kallweit if ((tx_fr && !ec->tx_coalesce_usecs) ||
191781496b72SHeiner Kallweit (rx_fr && !ec->rx_coalesce_usecs))
191881496b72SHeiner Kallweit return -EINVAL;
191981496b72SHeiner Kallweit
19202b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_TX_FRAMES, DIV_ROUND_UP(tx_fr, 4));
19212b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_RX_FRAMES, DIV_ROUND_UP(rx_fr, 4));
192225e992a4SHeiner Kallweit
19232b3e48b6SHeiner Kallweit units = DIV_ROUND_UP(ec->tx_coalesce_usecs * 1000U, scale);
19242b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_TX_USECS, units);
19252b3e48b6SHeiner Kallweit units = DIV_ROUND_UP(ec->rx_coalesce_usecs * 1000U, scale);
19262b3e48b6SHeiner Kallweit w |= FIELD_PREP(RTL_COALESCE_RX_USECS, units);
192725e992a4SHeiner Kallweit
19282b3e48b6SHeiner Kallweit RTL_W16(tp, IntrMitigate, w);
192925e992a4SHeiner Kallweit
19305cdfe830SHeiner Kallweit /* Meaning of PktCntrDisable bit changed from RTL8168e-vl */
19315cdfe830SHeiner Kallweit if (rtl_is_8168evl_up(tp)) {
19325cdfe830SHeiner Kallweit if (!rx_fr && !tx_fr)
19335cdfe830SHeiner Kallweit /* disable packet counter */
19345cdfe830SHeiner Kallweit tp->cp_cmd |= PktCntrDisable;
19355cdfe830SHeiner Kallweit else
19365cdfe830SHeiner Kallweit tp->cp_cmd &= ~PktCntrDisable;
19375cdfe830SHeiner Kallweit }
19385cdfe830SHeiner Kallweit
193925e992a4SHeiner Kallweit tp->cp_cmd = (tp->cp_cmd & ~INTT_MASK) | cp01;
194025e992a4SHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd);
1941711463f8SHeiner Kallweit rtl_pci_commit(tp);
194225e992a4SHeiner Kallweit
194325e992a4SHeiner Kallweit return 0;
194425e992a4SHeiner Kallweit }
194525e992a4SHeiner Kallweit
rtl8169_get_eee(struct net_device * dev,struct ethtool_eee * data)194625e992a4SHeiner Kallweit static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data)
194725e992a4SHeiner Kallweit {
194825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
194925e992a4SHeiner Kallweit
19502e779ddbSHeiner Kallweit if (!rtl_supports_eee(tp))
19512e779ddbSHeiner Kallweit return -EOPNOTSUPP;
19522e779ddbSHeiner Kallweit
1953ec2f204bSHeiner Kallweit return phy_ethtool_get_eee(tp->phydev, data);
195425e992a4SHeiner Kallweit }
195525e992a4SHeiner Kallweit
rtl8169_set_eee(struct net_device * dev,struct ethtool_eee * data)195625e992a4SHeiner Kallweit static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
195725e992a4SHeiner Kallweit {
195825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
19592e779ddbSHeiner Kallweit int ret;
19602e779ddbSHeiner Kallweit
19612e779ddbSHeiner Kallweit if (!rtl_supports_eee(tp))
19622e779ddbSHeiner Kallweit return -EOPNOTSUPP;
196325e992a4SHeiner Kallweit
19642e779ddbSHeiner Kallweit ret = phy_ethtool_set_eee(tp->phydev, data);
19657ec3f872SHeiner Kallweit
19667ec3f872SHeiner Kallweit if (!ret)
19677ec3f872SHeiner Kallweit tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN,
19687ec3f872SHeiner Kallweit MDIO_AN_EEE_ADV);
19692e779ddbSHeiner Kallweit return ret;
197025e992a4SHeiner Kallweit }
197125e992a4SHeiner Kallweit
rtl8169_get_ringparam(struct net_device * dev,struct ethtool_ringparam * data,struct kernel_ethtool_ringparam * kernel_data,struct netlink_ext_ack * extack)1972dc4aa50bSHeiner Kallweit static void rtl8169_get_ringparam(struct net_device *dev,
197374624944SHao Chen struct ethtool_ringparam *data,
197474624944SHao Chen struct kernel_ethtool_ringparam *kernel_data,
197574624944SHao Chen struct netlink_ext_ack *extack)
1976dc4aa50bSHeiner Kallweit {
1977dc4aa50bSHeiner Kallweit data->rx_max_pending = NUM_RX_DESC;
1978dc4aa50bSHeiner Kallweit data->rx_pending = NUM_RX_DESC;
1979dc4aa50bSHeiner Kallweit data->tx_max_pending = NUM_TX_DESC;
1980dc4aa50bSHeiner Kallweit data->tx_pending = NUM_TX_DESC;
1981dc4aa50bSHeiner Kallweit }
1982dc4aa50bSHeiner Kallweit
rtl8169_get_pauseparam(struct net_device * dev,struct ethtool_pauseparam * data)1983216f78eaSHeiner Kallweit static void rtl8169_get_pauseparam(struct net_device *dev,
1984216f78eaSHeiner Kallweit struct ethtool_pauseparam *data)
1985216f78eaSHeiner Kallweit {
1986216f78eaSHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
1987216f78eaSHeiner Kallweit bool tx_pause, rx_pause;
1988216f78eaSHeiner Kallweit
1989216f78eaSHeiner Kallweit phy_get_pause(tp->phydev, &tx_pause, &rx_pause);
1990216f78eaSHeiner Kallweit
1991216f78eaSHeiner Kallweit data->autoneg = tp->phydev->autoneg;
1992216f78eaSHeiner Kallweit data->tx_pause = tx_pause ? 1 : 0;
1993216f78eaSHeiner Kallweit data->rx_pause = rx_pause ? 1 : 0;
1994216f78eaSHeiner Kallweit }
1995216f78eaSHeiner Kallweit
rtl8169_set_pauseparam(struct net_device * dev,struct ethtool_pauseparam * data)1996216f78eaSHeiner Kallweit static int rtl8169_set_pauseparam(struct net_device *dev,
1997216f78eaSHeiner Kallweit struct ethtool_pauseparam *data)
1998216f78eaSHeiner Kallweit {
1999216f78eaSHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
2000216f78eaSHeiner Kallweit
2001216f78eaSHeiner Kallweit if (dev->mtu > ETH_DATA_LEN)
2002216f78eaSHeiner Kallweit return -EOPNOTSUPP;
2003216f78eaSHeiner Kallweit
2004216f78eaSHeiner Kallweit phy_set_asym_pause(tp->phydev, data->rx_pause, data->tx_pause);
2005216f78eaSHeiner Kallweit
2006216f78eaSHeiner Kallweit return 0;
2007216f78eaSHeiner Kallweit }
2008216f78eaSHeiner Kallweit
200925e992a4SHeiner Kallweit static const struct ethtool_ops rtl8169_ethtool_ops = {
2010b604eb31SJakub Kicinski .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
2011b604eb31SJakub Kicinski ETHTOOL_COALESCE_MAX_FRAMES,
201225e992a4SHeiner Kallweit .get_drvinfo = rtl8169_get_drvinfo,
201325e992a4SHeiner Kallweit .get_regs_len = rtl8169_get_regs_len,
201425e992a4SHeiner Kallweit .get_link = ethtool_op_get_link,
201525e992a4SHeiner Kallweit .get_coalesce = rtl_get_coalesce,
201625e992a4SHeiner Kallweit .set_coalesce = rtl_set_coalesce,
201725e992a4SHeiner Kallweit .get_regs = rtl8169_get_regs,
201825e992a4SHeiner Kallweit .get_wol = rtl8169_get_wol,
201925e992a4SHeiner Kallweit .set_wol = rtl8169_set_wol,
202025e992a4SHeiner Kallweit .get_strings = rtl8169_get_strings,
202125e992a4SHeiner Kallweit .get_sset_count = rtl8169_get_sset_count,
202225e992a4SHeiner Kallweit .get_ethtool_stats = rtl8169_get_ethtool_stats,
202325e992a4SHeiner Kallweit .get_ts_info = ethtool_op_get_ts_info,
202425e992a4SHeiner Kallweit .nway_reset = phy_ethtool_nway_reset,
202525e992a4SHeiner Kallweit .get_eee = rtl8169_get_eee,
202625e992a4SHeiner Kallweit .set_eee = rtl8169_set_eee,
202725e992a4SHeiner Kallweit .get_link_ksettings = phy_ethtool_get_link_ksettings,
202825e992a4SHeiner Kallweit .set_link_ksettings = phy_ethtool_set_link_ksettings,
2029dc4aa50bSHeiner Kallweit .get_ringparam = rtl8169_get_ringparam,
2030216f78eaSHeiner Kallweit .get_pauseparam = rtl8169_get_pauseparam,
2031216f78eaSHeiner Kallweit .set_pauseparam = rtl8169_set_pauseparam,
203225e992a4SHeiner Kallweit };
203325e992a4SHeiner Kallweit
rtl_enable_eee(struct rtl8169_private * tp)203425e992a4SHeiner Kallweit static void rtl_enable_eee(struct rtl8169_private *tp)
203525e992a4SHeiner Kallweit {
20362e779ddbSHeiner Kallweit struct phy_device *phydev = tp->phydev;
20377ec3f872SHeiner Kallweit int adv;
203825e992a4SHeiner Kallweit
20397ec3f872SHeiner Kallweit /* respect EEE advertisement the user may have set */
20407ec3f872SHeiner Kallweit if (tp->eee_adv >= 0)
20417ec3f872SHeiner Kallweit adv = tp->eee_adv;
20427ec3f872SHeiner Kallweit else
20437ec3f872SHeiner Kallweit adv = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
20447ec3f872SHeiner Kallweit
20457ec3f872SHeiner Kallweit if (adv >= 0)
20467ec3f872SHeiner Kallweit phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);
204725e992a4SHeiner Kallweit }
204825e992a4SHeiner Kallweit
rtl8169_get_mac_version(u16 xid,bool gmii)2049f1f9ca28SHeiner Kallweit static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
205025e992a4SHeiner Kallweit {
205125e992a4SHeiner Kallweit /*
205225e992a4SHeiner Kallweit * The driver currently handles the 8168Bf and the 8168Be identically
205325e992a4SHeiner Kallweit * but they can be identified more specifically through the test below
205425e992a4SHeiner Kallweit * if needed:
205525e992a4SHeiner Kallweit *
205625e992a4SHeiner Kallweit * (RTL_R32(tp, TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
205725e992a4SHeiner Kallweit *
205825e992a4SHeiner Kallweit * Same thing for the 8101Eb and the 8101Ec:
205925e992a4SHeiner Kallweit *
206025e992a4SHeiner Kallweit * (RTL_R32(tp, TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
206125e992a4SHeiner Kallweit */
206225e992a4SHeiner Kallweit static const struct rtl_mac_info {
206325e992a4SHeiner Kallweit u16 mask;
206425e992a4SHeiner Kallweit u16 val;
2065f1f9ca28SHeiner Kallweit enum mac_version ver;
206625e992a4SHeiner Kallweit } mac_info[] = {
20670439297bSHeiner Kallweit /* 8125B family. */
20680439297bSHeiner Kallweit { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
20690439297bSHeiner Kallweit
20700439297bSHeiner Kallweit /* 8125A family. */
20714e9c91cfSHeiner Kallweit { 0x7cf, 0x609, RTL_GIGA_MAC_VER_61 },
20724e9c91cfSHeiner Kallweit /* It seems only XID 609 made it to the mass market.
20734e9c91cfSHeiner Kallweit * { 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 },
20744e9c91cfSHeiner Kallweit * { 0x7c8, 0x608, RTL_GIGA_MAC_VER_61 },
20754e9c91cfSHeiner Kallweit */
2076f1bce4adSHeiner Kallweit
20771287723aSHeiner Kallweit /* RTL8117 */
2078e6d6ca6eSKai-Heng Feng { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_53 },
20791287723aSHeiner Kallweit { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52 },
20801287723aSHeiner Kallweit
208125e992a4SHeiner Kallweit /* 8168EP family. */
208225e992a4SHeiner Kallweit { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51 },
20832d6600c7SHeiner Kallweit /* It seems this chip version never made it to
20842d6600c7SHeiner Kallweit * the wild. Let's disable detection.
20852d6600c7SHeiner Kallweit * { 0x7cf, 0x501, RTL_GIGA_MAC_VER_50 },
20862d6600c7SHeiner Kallweit * { 0x7cf, 0x500, RTL_GIGA_MAC_VER_49 },
20872d6600c7SHeiner Kallweit */
208825e992a4SHeiner Kallweit
208925e992a4SHeiner Kallweit /* 8168H family. */
209025e992a4SHeiner Kallweit { 0x7cf, 0x541, RTL_GIGA_MAC_VER_46 },
20916c8a5cf9SHeiner Kallweit /* It seems this chip version never made it to
20926c8a5cf9SHeiner Kallweit * the wild. Let's disable detection.
20936c8a5cf9SHeiner Kallweit * { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 },
20946c8a5cf9SHeiner Kallweit */
209525e992a4SHeiner Kallweit
209625e992a4SHeiner Kallweit /* 8168G family. */
209725e992a4SHeiner Kallweit { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 },
209825e992a4SHeiner Kallweit { 0x7cf, 0x509, RTL_GIGA_MAC_VER_42 },
2099364ef1f3SHeiner Kallweit /* It seems this chip version never made it to
2100364ef1f3SHeiner Kallweit * the wild. Let's disable detection.
2101364ef1f3SHeiner Kallweit * { 0x7cf, 0x4c1, RTL_GIGA_MAC_VER_41 },
2102364ef1f3SHeiner Kallweit */
210325e992a4SHeiner Kallweit { 0x7cf, 0x4c0, RTL_GIGA_MAC_VER_40 },
210425e992a4SHeiner Kallweit
210525e992a4SHeiner Kallweit /* 8168F family. */
210625e992a4SHeiner Kallweit { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38 },
21072ea26b4dSHeiner Kallweit { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36 },
210825e992a4SHeiner Kallweit { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35 },
210925e992a4SHeiner Kallweit
211025e992a4SHeiner Kallweit /* 8168E family. */
211125e992a4SHeiner Kallweit { 0x7c8, 0x2c8, RTL_GIGA_MAC_VER_34 },
211225e992a4SHeiner Kallweit { 0x7cf, 0x2c1, RTL_GIGA_MAC_VER_32 },
211325e992a4SHeiner Kallweit { 0x7c8, 0x2c0, RTL_GIGA_MAC_VER_33 },
211425e992a4SHeiner Kallweit
211525e992a4SHeiner Kallweit /* 8168D family. */
211625e992a4SHeiner Kallweit { 0x7cf, 0x281, RTL_GIGA_MAC_VER_25 },
211725e992a4SHeiner Kallweit { 0x7c8, 0x280, RTL_GIGA_MAC_VER_26 },
211825e992a4SHeiner Kallweit
211925e992a4SHeiner Kallweit /* 8168DP family. */
2120beb401ecSHeiner Kallweit /* It seems this early RTL8168dp version never made it to
212101649011SHeiner Kallweit * the wild. Support has been removed.
2122beb401ecSHeiner Kallweit * { 0x7cf, 0x288, RTL_GIGA_MAC_VER_27 },
2123beb401ecSHeiner Kallweit */
212425e992a4SHeiner Kallweit { 0x7cf, 0x28a, RTL_GIGA_MAC_VER_28 },
212525e992a4SHeiner Kallweit { 0x7cf, 0x28b, RTL_GIGA_MAC_VER_31 },
212625e992a4SHeiner Kallweit
212725e992a4SHeiner Kallweit /* 8168C family. */
212825e992a4SHeiner Kallweit { 0x7cf, 0x3c9, RTL_GIGA_MAC_VER_23 },
212925e992a4SHeiner Kallweit { 0x7cf, 0x3c8, RTL_GIGA_MAC_VER_18 },
213025e992a4SHeiner Kallweit { 0x7c8, 0x3c8, RTL_GIGA_MAC_VER_24 },
213125e992a4SHeiner Kallweit { 0x7cf, 0x3c0, RTL_GIGA_MAC_VER_19 },
213225e992a4SHeiner Kallweit { 0x7cf, 0x3c2, RTL_GIGA_MAC_VER_20 },
213325e992a4SHeiner Kallweit { 0x7cf, 0x3c3, RTL_GIGA_MAC_VER_21 },
213425e992a4SHeiner Kallweit { 0x7c8, 0x3c0, RTL_GIGA_MAC_VER_22 },
213525e992a4SHeiner Kallweit
213625e992a4SHeiner Kallweit /* 8168B family. */
213725e992a4SHeiner Kallweit { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 },
213825e992a4SHeiner Kallweit { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 },
213925e992a4SHeiner Kallweit
214025e992a4SHeiner Kallweit /* 8101 family. */
214125e992a4SHeiner Kallweit { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 },
214225e992a4SHeiner Kallweit { 0x7c8, 0x440, RTL_GIGA_MAC_VER_37 },
214325e992a4SHeiner Kallweit { 0x7cf, 0x409, RTL_GIGA_MAC_VER_29 },
214425e992a4SHeiner Kallweit { 0x7c8, 0x408, RTL_GIGA_MAC_VER_30 },
214525e992a4SHeiner Kallweit { 0x7cf, 0x349, RTL_GIGA_MAC_VER_08 },
214625e992a4SHeiner Kallweit { 0x7cf, 0x249, RTL_GIGA_MAC_VER_08 },
214725e992a4SHeiner Kallweit { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 },
214825e992a4SHeiner Kallweit { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 },
2149cdafdc29SHeiner Kallweit { 0x7cf, 0x240, RTL_GIGA_MAC_VER_14 },
215025e992a4SHeiner Kallweit { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 },
215125e992a4SHeiner Kallweit { 0x7c8, 0x248, RTL_GIGA_MAC_VER_09 },
2152e66d6586SHeiner Kallweit { 0x7c8, 0x340, RTL_GIGA_MAC_VER_10 },
215325e992a4SHeiner Kallweit
215425e992a4SHeiner Kallweit /* 8110 family. */
215525e992a4SHeiner Kallweit { 0xfc8, 0x980, RTL_GIGA_MAC_VER_06 },
215625e992a4SHeiner Kallweit { 0xfc8, 0x180, RTL_GIGA_MAC_VER_05 },
215725e992a4SHeiner Kallweit { 0xfc8, 0x100, RTL_GIGA_MAC_VER_04 },
215825e992a4SHeiner Kallweit { 0xfc8, 0x040, RTL_GIGA_MAC_VER_03 },
215925e992a4SHeiner Kallweit { 0xfc8, 0x008, RTL_GIGA_MAC_VER_02 },
216025e992a4SHeiner Kallweit
216125e992a4SHeiner Kallweit /* Catch-all */
216225e992a4SHeiner Kallweit { 0x000, 0x000, RTL_GIGA_MAC_NONE }
216325e992a4SHeiner Kallweit };
216425e992a4SHeiner Kallweit const struct rtl_mac_info *p = mac_info;
2165f1f9ca28SHeiner Kallweit enum mac_version ver;
216625e992a4SHeiner Kallweit
2167f1f9ca28SHeiner Kallweit while ((xid & p->mask) != p->val)
216825e992a4SHeiner Kallweit p++;
2169f1f9ca28SHeiner Kallweit ver = p->ver;
217025e992a4SHeiner Kallweit
2171f1f9ca28SHeiner Kallweit if (ver != RTL_GIGA_MAC_NONE && !gmii) {
2172f1f9ca28SHeiner Kallweit if (ver == RTL_GIGA_MAC_VER_42)
2173f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_43;
2174f1f9ca28SHeiner Kallweit else if (ver == RTL_GIGA_MAC_VER_46)
2175f1f9ca28SHeiner Kallweit ver = RTL_GIGA_MAC_VER_48;
217625e992a4SHeiner Kallweit }
2177f1f9ca28SHeiner Kallweit
2178f1f9ca28SHeiner Kallweit return ver;
217925e992a4SHeiner Kallweit }
218025e992a4SHeiner Kallweit
rtl_release_firmware(struct rtl8169_private * tp)218125e992a4SHeiner Kallweit static void rtl_release_firmware(struct rtl8169_private *tp)
218225e992a4SHeiner Kallweit {
218325e992a4SHeiner Kallweit if (tp->rtl_fw) {
218425e992a4SHeiner Kallweit rtl_fw_release_firmware(tp->rtl_fw);
218525e992a4SHeiner Kallweit kfree(tp->rtl_fw);
218625e992a4SHeiner Kallweit tp->rtl_fw = NULL;
218725e992a4SHeiner Kallweit }
218825e992a4SHeiner Kallweit }
218925e992a4SHeiner Kallweit
r8169_apply_firmware(struct rtl8169_private * tp)21902992bdfaSHeiner Kallweit void r8169_apply_firmware(struct rtl8169_private *tp)
219125e992a4SHeiner Kallweit {
219247dda786SHeiner Kallweit int val;
219347dda786SHeiner Kallweit
219425e992a4SHeiner Kallweit /* TODO: release firmware if rtl_fw_write_firmware signals failure. */
219589fbd26cSHeiner Kallweit if (tp->rtl_fw) {
219625e992a4SHeiner Kallweit rtl_fw_write_firmware(tp, tp->rtl_fw);
219789fbd26cSHeiner Kallweit /* At least one firmware doesn't reset tp->ocp_base. */
219889fbd26cSHeiner Kallweit tp->ocp_base = OCP_STD_PHY_BASE;
219947dda786SHeiner Kallweit
220047dda786SHeiner Kallweit /* PHY soft reset may still be in progress */
220147dda786SHeiner Kallweit phy_read_poll_timeout(tp->phydev, MII_BMCR, val,
220247dda786SHeiner Kallweit !(val & BMCR_RESET),
220347dda786SHeiner Kallweit 50000, 600000, true);
220489fbd26cSHeiner Kallweit }
220525e992a4SHeiner Kallweit }
220625e992a4SHeiner Kallweit
rtl8168_config_eee_mac(struct rtl8169_private * tp)220725e992a4SHeiner Kallweit static void rtl8168_config_eee_mac(struct rtl8169_private *tp)
220825e992a4SHeiner Kallweit {
220925e992a4SHeiner Kallweit /* Adjust EEE LED frequency */
221025e992a4SHeiner Kallweit if (tp->mac_version != RTL_GIGA_MAC_VER_38)
221125e992a4SHeiner Kallweit RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
221225e992a4SHeiner Kallweit
221354113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, 0x0003);
221425e992a4SHeiner Kallweit }
221525e992a4SHeiner Kallweit
rtl8125a_config_eee_mac(struct rtl8169_private * tp)22164640338cSHeiner Kallweit static void rtl8125a_config_eee_mac(struct rtl8169_private *tp)
2217b3a42e3aSHeiner Kallweit {
2218b3a42e3aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0));
2219b3a42e3aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb62, 0, BIT(2) | BIT(1));
2220b3a42e3aSHeiner Kallweit }
2221b3a42e3aSHeiner Kallweit
rtl8125_set_eee_txidle_timer(struct rtl8169_private * tp)22220439297bSHeiner Kallweit static void rtl8125_set_eee_txidle_timer(struct rtl8169_private *tp)
22230439297bSHeiner Kallweit {
22240439297bSHeiner Kallweit RTL_W16(tp, EEE_TXIDLE_TIMER_8125, tp->dev->mtu + ETH_HLEN + 0x20);
22250439297bSHeiner Kallweit }
22260439297bSHeiner Kallweit
rtl8125b_config_eee_mac(struct rtl8169_private * tp)22270439297bSHeiner Kallweit static void rtl8125b_config_eee_mac(struct rtl8169_private *tp)
22280439297bSHeiner Kallweit {
22290439297bSHeiner Kallweit rtl8125_set_eee_txidle_timer(tp);
22300439297bSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0));
22310439297bSHeiner Kallweit }
22320439297bSHeiner Kallweit
rtl_rar_exgmac_set(struct rtl8169_private * tp,const u8 * addr)2233ae1e82c6SHeiner Kallweit static void rtl_rar_exgmac_set(struct rtl8169_private *tp, const u8 *addr)
223425e992a4SHeiner Kallweit {
2235ae1e82c6SHeiner Kallweit rtl_eri_write(tp, 0xe0, ERIAR_MASK_1111, get_unaligned_le32(addr));
2236ae1e82c6SHeiner Kallweit rtl_eri_write(tp, 0xe4, ERIAR_MASK_1111, get_unaligned_le16(addr + 4));
2237ae1e82c6SHeiner Kallweit rtl_eri_write(tp, 0xf0, ERIAR_MASK_1111, get_unaligned_le16(addr) << 16);
2238ae1e82c6SHeiner Kallweit rtl_eri_write(tp, 0xf4, ERIAR_MASK_1111, get_unaligned_le32(addr + 2));
223925e992a4SHeiner Kallweit }
224025e992a4SHeiner Kallweit
rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private * tp)22412992bdfaSHeiner Kallweit u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp)
22423127f7c9SHeiner Kallweit {
22433127f7c9SHeiner Kallweit u16 data1, data2, ioffset;
22443127f7c9SHeiner Kallweit
22453127f7c9SHeiner Kallweit r8168_mac_ocp_write(tp, 0xdd02, 0x807d);
22463127f7c9SHeiner Kallweit data1 = r8168_mac_ocp_read(tp, 0xdd02);
22473127f7c9SHeiner Kallweit data2 = r8168_mac_ocp_read(tp, 0xdd00);
22483127f7c9SHeiner Kallweit
22493127f7c9SHeiner Kallweit ioffset = (data2 >> 1) & 0x7ff8;
22503127f7c9SHeiner Kallweit ioffset |= data2 & 0x0007;
22513127f7c9SHeiner Kallweit if (data1 & BIT(7))
22523127f7c9SHeiner Kallweit ioffset |= BIT(15);
22533127f7c9SHeiner Kallweit
22543127f7c9SHeiner Kallweit return ioffset;
22553127f7c9SHeiner Kallweit }
22563127f7c9SHeiner Kallweit
rtl_schedule_task(struct rtl8169_private * tp,enum rtl_flag flag)225725e992a4SHeiner Kallweit static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
225825e992a4SHeiner Kallweit {
22593f6ca6c7SHeiner Kallweit set_bit(flag, tp->wk.flags);
226025e992a4SHeiner Kallweit schedule_work(&tp->wk.work);
226125e992a4SHeiner Kallweit }
226225e992a4SHeiner Kallweit
rtl8169_init_phy(struct rtl8169_private * tp)2263b5aed0b3SHeiner Kallweit static void rtl8169_init_phy(struct rtl8169_private *tp)
226425e992a4SHeiner Kallweit {
2265becd837eSHeiner Kallweit r8169_hw_phy_config(tp, tp->phydev, tp->mac_version);
226625e992a4SHeiner Kallweit
226725e992a4SHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
226825e992a4SHeiner Kallweit pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
226925e992a4SHeiner Kallweit pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
2270b5aed0b3SHeiner Kallweit /* set undocumented MAC Reg C+CR Offset 0x82h */
227125e992a4SHeiner Kallweit RTL_W8(tp, 0x82, 0x01);
227225e992a4SHeiner Kallweit }
227325e992a4SHeiner Kallweit
2274fc712387SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05 &&
2275fc712387SHeiner Kallweit tp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_GIGABYTE &&
2276fc712387SHeiner Kallweit tp->pci_dev->subsystem_device == 0xe000)
2277fc712387SHeiner Kallweit phy_write_paged(tp->phydev, 0x0001, 0x10, 0xf01b);
2278fc712387SHeiner Kallweit
227925e992a4SHeiner Kallweit /* We may have called phy_speed_down before */
228025e992a4SHeiner Kallweit phy_speed_up(tp->phydev);
228125e992a4SHeiner Kallweit
2282af779778SHeiner Kallweit if (rtl_supports_eee(tp))
2283af779778SHeiner Kallweit rtl_enable_eee(tp);
2284af779778SHeiner Kallweit
228525e992a4SHeiner Kallweit genphy_soft_reset(tp->phydev);
228625e992a4SHeiner Kallweit }
228725e992a4SHeiner Kallweit
rtl_rar_set(struct rtl8169_private * tp,const u8 * addr)2288ae1e82c6SHeiner Kallweit static void rtl_rar_set(struct rtl8169_private *tp, const u8 *addr)
228925e992a4SHeiner Kallweit {
229025e992a4SHeiner Kallweit rtl_unlock_config_regs(tp);
229125e992a4SHeiner Kallweit
2292ae1e82c6SHeiner Kallweit RTL_W32(tp, MAC4, get_unaligned_le16(addr + 4));
2293711463f8SHeiner Kallweit rtl_pci_commit(tp);
229425e992a4SHeiner Kallweit
2295ae1e82c6SHeiner Kallweit RTL_W32(tp, MAC0, get_unaligned_le32(addr));
2296711463f8SHeiner Kallweit rtl_pci_commit(tp);
229725e992a4SHeiner Kallweit
229825e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34)
229925e992a4SHeiner Kallweit rtl_rar_exgmac_set(tp, addr);
230025e992a4SHeiner Kallweit
230125e992a4SHeiner Kallweit rtl_lock_config_regs(tp);
230225e992a4SHeiner Kallweit }
230325e992a4SHeiner Kallweit
rtl_set_mac_address(struct net_device * dev,void * p)230425e992a4SHeiner Kallweit static int rtl_set_mac_address(struct net_device *dev, void *p)
230525e992a4SHeiner Kallweit {
230625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
230725e992a4SHeiner Kallweit int ret;
230825e992a4SHeiner Kallweit
230925e992a4SHeiner Kallweit ret = eth_mac_addr(dev, p);
231025e992a4SHeiner Kallweit if (ret)
231125e992a4SHeiner Kallweit return ret;
231225e992a4SHeiner Kallweit
231325e992a4SHeiner Kallweit rtl_rar_set(tp, dev->dev_addr);
231425e992a4SHeiner Kallweit
231525e992a4SHeiner Kallweit return 0;
231625e992a4SHeiner Kallweit }
231725e992a4SHeiner Kallweit
rtl_init_rxcfg(struct rtl8169_private * tp)231825e992a4SHeiner Kallweit static void rtl_init_rxcfg(struct rtl8169_private *tp)
231925e992a4SHeiner Kallweit {
232025e992a4SHeiner Kallweit switch (tp->mac_version) {
232125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
232225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17:
232325e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX_FIFO_THRESH | RX_DMA_BURST);
232425e992a4SHeiner Kallweit break;
232525e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24:
232625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_36:
232725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_38:
232825e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
232925e992a4SHeiner Kallweit break;
2330e6d6ca6eSKai-Heng Feng case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53:
233125e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
233225e992a4SHeiner Kallweit break;
23332e04cfddSChunHao Lin case RTL_GIGA_MAC_VER_61:
233410478283SHeiner Kallweit RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
2335f1bce4adSHeiner Kallweit break;
23362e04cfddSChunHao Lin case RTL_GIGA_MAC_VER_63:
23372e04cfddSChunHao Lin RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
23382e04cfddSChunHao Lin RX_PAUSE_SLOT_ON);
23392e04cfddSChunHao Lin break;
234025e992a4SHeiner Kallweit default:
234125e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
234225e992a4SHeiner Kallweit break;
234325e992a4SHeiner Kallweit }
234425e992a4SHeiner Kallweit }
234525e992a4SHeiner Kallweit
rtl8169_init_ring_indexes(struct rtl8169_private * tp)234625e992a4SHeiner Kallweit static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
234725e992a4SHeiner Kallweit {
234825e992a4SHeiner Kallweit tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0;
234925e992a4SHeiner Kallweit }
235025e992a4SHeiner Kallweit
r8168c_hw_jumbo_enable(struct rtl8169_private * tp)235125e992a4SHeiner Kallweit static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp)
235225e992a4SHeiner Kallweit {
235325e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
235425e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1);
235525e992a4SHeiner Kallweit }
235625e992a4SHeiner Kallweit
r8168c_hw_jumbo_disable(struct rtl8169_private * tp)235725e992a4SHeiner Kallweit static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp)
235825e992a4SHeiner Kallweit {
235925e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
236025e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1);
236125e992a4SHeiner Kallweit }
236225e992a4SHeiner Kallweit
r8168dp_hw_jumbo_enable(struct rtl8169_private * tp)236325e992a4SHeiner Kallweit static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp)
236425e992a4SHeiner Kallweit {
236525e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
236625e992a4SHeiner Kallweit }
236725e992a4SHeiner Kallweit
r8168dp_hw_jumbo_disable(struct rtl8169_private * tp)236825e992a4SHeiner Kallweit static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp)
236925e992a4SHeiner Kallweit {
237025e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
237125e992a4SHeiner Kallweit }
237225e992a4SHeiner Kallweit
r8168e_hw_jumbo_enable(struct rtl8169_private * tp)237325e992a4SHeiner Kallweit static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp)
237425e992a4SHeiner Kallweit {
23756cf73913SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, 0x24);
237625e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
237725e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01);
237825e992a4SHeiner Kallweit }
237925e992a4SHeiner Kallweit
r8168e_hw_jumbo_disable(struct rtl8169_private * tp)238025e992a4SHeiner Kallweit static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
238125e992a4SHeiner Kallweit {
23826cf73913SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, 0x3f);
238325e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
238425e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01);
238525e992a4SHeiner Kallweit }
238625e992a4SHeiner Kallweit
r8168b_1_hw_jumbo_enable(struct rtl8169_private * tp)238725e992a4SHeiner Kallweit static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp)
238825e992a4SHeiner Kallweit {
238925e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0));
239025e992a4SHeiner Kallweit }
239125e992a4SHeiner Kallweit
r8168b_1_hw_jumbo_disable(struct rtl8169_private * tp)239225e992a4SHeiner Kallweit static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp)
239325e992a4SHeiner Kallweit {
239425e992a4SHeiner Kallweit RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0));
239525e992a4SHeiner Kallweit }
239625e992a4SHeiner Kallweit
rtl_jumbo_config(struct rtl8169_private * tp)23979db0ac57SHeiner Kallweit static void rtl_jumbo_config(struct rtl8169_private *tp)
239825e992a4SHeiner Kallweit {
23999db0ac57SHeiner Kallweit bool jumbo = tp->dev->mtu > ETH_DATA_LEN;
24005e00e16cSHeiner Kallweit int readrq = 4096;
24019db0ac57SHeiner Kallweit
240225e992a4SHeiner Kallweit rtl_unlock_config_regs(tp);
240325e992a4SHeiner Kallweit switch (tp->mac_version) {
240425e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17:
24059db0ac57SHeiner Kallweit if (jumbo) {
24065e00e16cSHeiner Kallweit readrq = 512;
240725e992a4SHeiner Kallweit r8168b_1_hw_jumbo_enable(tp);
24089db0ac57SHeiner Kallweit } else {
24099db0ac57SHeiner Kallweit r8168b_1_hw_jumbo_disable(tp);
24109db0ac57SHeiner Kallweit }
241125e992a4SHeiner Kallweit break;
241225e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26:
24139db0ac57SHeiner Kallweit if (jumbo) {
24145e00e16cSHeiner Kallweit readrq = 512;
241525e992a4SHeiner Kallweit r8168c_hw_jumbo_enable(tp);
24169db0ac57SHeiner Kallweit } else {
241725e992a4SHeiner Kallweit r8168c_hw_jumbo_disable(tp);
24189db0ac57SHeiner Kallweit }
241925e992a4SHeiner Kallweit break;
242001649011SHeiner Kallweit case RTL_GIGA_MAC_VER_28:
24219db0ac57SHeiner Kallweit if (jumbo)
24229db0ac57SHeiner Kallweit r8168dp_hw_jumbo_enable(tp);
24239db0ac57SHeiner Kallweit else
242425e992a4SHeiner Kallweit r8168dp_hw_jumbo_disable(tp);
242525e992a4SHeiner Kallweit break;
24260fc75219SHeiner Kallweit case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33:
24272007317eSHeiner Kallweit if (jumbo)
24289db0ac57SHeiner Kallweit r8168e_hw_jumbo_enable(tp);
24292007317eSHeiner Kallweit else
243025e992a4SHeiner Kallweit r8168e_hw_jumbo_disable(tp);
243125e992a4SHeiner Kallweit break;
243225e992a4SHeiner Kallweit default:
243325e992a4SHeiner Kallweit break;
243425e992a4SHeiner Kallweit }
243525e992a4SHeiner Kallweit rtl_lock_config_regs(tp);
243621b5f672SHeiner Kallweit
24375e00e16cSHeiner Kallweit if (pci_is_pcie(tp->pci_dev) && tp->supports_gmii)
24385e00e16cSHeiner Kallweit pcie_set_readrq(tp->pci_dev, readrq);
2439453a7789SHeiner Kallweit
2440453a7789SHeiner Kallweit /* Chip doesn't support pause in jumbo mode */
244111ac4e66SHeiner Kallweit if (jumbo) {
244211ac4e66SHeiner Kallweit linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
244311ac4e66SHeiner Kallweit tp->phydev->advertising);
244411ac4e66SHeiner Kallweit linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
244511ac4e66SHeiner Kallweit tp->phydev->advertising);
2446453a7789SHeiner Kallweit phy_start_aneg(tp->phydev);
244725e992a4SHeiner Kallweit }
244811ac4e66SHeiner Kallweit }
244925e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_chipcmd_cond)245025e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_chipcmd_cond)
245125e992a4SHeiner Kallweit {
245225e992a4SHeiner Kallweit return RTL_R8(tp, ChipCmd) & CmdReset;
245325e992a4SHeiner Kallweit }
245425e992a4SHeiner Kallweit
rtl_hw_reset(struct rtl8169_private * tp)245525e992a4SHeiner Kallweit static void rtl_hw_reset(struct rtl8169_private *tp)
245625e992a4SHeiner Kallweit {
245725e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, CmdReset);
245825e992a4SHeiner Kallweit
2459d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100);
246025e992a4SHeiner Kallweit }
246125e992a4SHeiner Kallweit
rtl_request_firmware(struct rtl8169_private * tp)246225e992a4SHeiner Kallweit static void rtl_request_firmware(struct rtl8169_private *tp)
246325e992a4SHeiner Kallweit {
246425e992a4SHeiner Kallweit struct rtl_fw *rtl_fw;
246525e992a4SHeiner Kallweit
246625e992a4SHeiner Kallweit /* firmware loaded already or no firmware available */
246725e992a4SHeiner Kallweit if (tp->rtl_fw || !tp->fw_name)
246825e992a4SHeiner Kallweit return;
246925e992a4SHeiner Kallweit
247025e992a4SHeiner Kallweit rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL);
24713bf6ff3cSHeiner Kallweit if (!rtl_fw)
247225e992a4SHeiner Kallweit return;
247325e992a4SHeiner Kallweit
247425e992a4SHeiner Kallweit rtl_fw->phy_write = rtl_writephy;
247525e992a4SHeiner Kallweit rtl_fw->phy_read = rtl_readphy;
247625e992a4SHeiner Kallweit rtl_fw->mac_mcu_write = mac_mcu_write;
247725e992a4SHeiner Kallweit rtl_fw->mac_mcu_read = mac_mcu_read;
247825e992a4SHeiner Kallweit rtl_fw->fw_name = tp->fw_name;
247925e992a4SHeiner Kallweit rtl_fw->dev = tp_to_dev(tp);
248025e992a4SHeiner Kallweit
248125e992a4SHeiner Kallweit if (rtl_fw_request_firmware(rtl_fw))
248225e992a4SHeiner Kallweit kfree(rtl_fw);
248325e992a4SHeiner Kallweit else
248425e992a4SHeiner Kallweit tp->rtl_fw = rtl_fw;
248525e992a4SHeiner Kallweit }
248625e992a4SHeiner Kallweit
rtl_rx_close(struct rtl8169_private * tp)248725e992a4SHeiner Kallweit static void rtl_rx_close(struct rtl8169_private *tp)
248825e992a4SHeiner Kallweit {
248925e992a4SHeiner Kallweit RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~RX_CONFIG_ACCEPT_MASK);
249025e992a4SHeiner Kallweit }
249125e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_npq_cond)249225e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_npq_cond)
249325e992a4SHeiner Kallweit {
249425e992a4SHeiner Kallweit return RTL_R8(tp, TxPoll) & NPQ;
249525e992a4SHeiner Kallweit }
249625e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_txcfg_empty_cond)249725e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_txcfg_empty_cond)
249825e992a4SHeiner Kallweit {
249925e992a4SHeiner Kallweit return RTL_R32(tp, TxConfig) & TXCFG_EMPTY;
250025e992a4SHeiner Kallweit }
250125e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_rxtx_empty_cond)25026f9395c6SHeiner Kallweit DECLARE_RTL_COND(rtl_rxtx_empty_cond)
25036f9395c6SHeiner Kallweit {
25046f9395c6SHeiner Kallweit return (RTL_R8(tp, MCU) & RXTX_EMPTY) == RXTX_EMPTY;
25056f9395c6SHeiner Kallweit }
25066f9395c6SHeiner Kallweit
DECLARE_RTL_COND(rtl_rxtx_empty_cond_2)25070439297bSHeiner Kallweit DECLARE_RTL_COND(rtl_rxtx_empty_cond_2)
25080439297bSHeiner Kallweit {
25090439297bSHeiner Kallweit /* IntrMitigate has new functionality on RTL8125 */
25100439297bSHeiner Kallweit return (RTL_R16(tp, IntrMitigate) & 0x0103) == 0x0103;
25110439297bSHeiner Kallweit }
25120439297bSHeiner Kallweit
rtl_wait_txrx_fifo_empty(struct rtl8169_private * tp)25136f9395c6SHeiner Kallweit static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp)
25146f9395c6SHeiner Kallweit {
25156f9395c6SHeiner Kallweit switch (tp->mac_version) {
2516e6d6ca6eSKai-Heng Feng case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53:
25176f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42);
25186f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
25196f9395c6SHeiner Kallweit break;
2520efc37109SHeiner Kallweit case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
25216f9395c6SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
25226f9395c6SHeiner Kallweit break;
25230439297bSHeiner Kallweit case RTL_GIGA_MAC_VER_63:
25240439297bSHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
25250439297bSHeiner Kallweit rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
25260439297bSHeiner Kallweit rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
25270439297bSHeiner Kallweit break;
25286f9395c6SHeiner Kallweit default:
25296f9395c6SHeiner Kallweit break;
25306f9395c6SHeiner Kallweit }
25316f9395c6SHeiner Kallweit }
25326f9395c6SHeiner Kallweit
rtl_disable_rxdvgate(struct rtl8169_private * tp)25333406079bSChunhao Lin static void rtl_disable_rxdvgate(struct rtl8169_private *tp)
25343406079bSChunhao Lin {
25353406079bSChunhao Lin RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN);
25363406079bSChunhao Lin }
25373406079bSChunhao Lin
rtl_enable_rxdvgate(struct rtl8169_private * tp)25389617886fSHeiner Kallweit static void rtl_enable_rxdvgate(struct rtl8169_private *tp)
25399617886fSHeiner Kallweit {
25409617886fSHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN);
25419617886fSHeiner Kallweit fsleep(2000);
25426f9395c6SHeiner Kallweit rtl_wait_txrx_fifo_empty(tp);
25439617886fSHeiner Kallweit }
25449617886fSHeiner Kallweit
rtl_wol_enable_rx(struct rtl8169_private * tp)2545ad425666SChunhao Lin static void rtl_wol_enable_rx(struct rtl8169_private *tp)
2546ad425666SChunhao Lin {
2547ad425666SChunhao Lin if (tp->mac_version >= RTL_GIGA_MAC_VER_25)
2548ad425666SChunhao Lin RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) |
2549ad425666SChunhao Lin AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
2550bb41c13cSChunhao Lin
2551bb41c13cSChunhao Lin if (tp->mac_version >= RTL_GIGA_MAC_VER_40)
2552bb41c13cSChunhao Lin rtl_disable_rxdvgate(tp);
2553ad425666SChunhao Lin }
2554ad425666SChunhao Lin
rtl_prepare_power_down(struct rtl8169_private * tp)2555ad425666SChunhao Lin static void rtl_prepare_power_down(struct rtl8169_private *tp)
2556ad425666SChunhao Lin {
2557c61d525fSChunHao Lin if (tp->dash_enabled)
2558ad425666SChunhao Lin return;
2559ad425666SChunhao Lin
2560ad425666SChunhao Lin if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
2561ad425666SChunhao Lin tp->mac_version == RTL_GIGA_MAC_VER_33)
2562ad425666SChunhao Lin rtl_ephy_write(tp, 0x19, 0xff64);
2563ad425666SChunhao Lin
2564ad425666SChunhao Lin if (device_may_wakeup(tp_to_dev(tp))) {
2565ad425666SChunhao Lin phy_speed_down(tp->phydev, false);
2566ad425666SChunhao Lin rtl_wol_enable_rx(tp);
2567ad425666SChunhao Lin }
2568ad425666SChunhao Lin }
2569ad425666SChunhao Lin
rtl_set_tx_config_registers(struct rtl8169_private * tp)257025e992a4SHeiner Kallweit static void rtl_set_tx_config_registers(struct rtl8169_private *tp)
257125e992a4SHeiner Kallweit {
257225e992a4SHeiner Kallweit u32 val = TX_DMA_BURST << TxDMAShift |
257325e992a4SHeiner Kallweit InterFrameGap << TxInterFrameGapShift;
257425e992a4SHeiner Kallweit
25759e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp))
257625e992a4SHeiner Kallweit val |= TXCFG_AUTO_FIFO;
257725e992a4SHeiner Kallweit
257825e992a4SHeiner Kallweit RTL_W32(tp, TxConfig, val);
257925e992a4SHeiner Kallweit }
258025e992a4SHeiner Kallweit
rtl_set_rx_max_size(struct rtl8169_private * tp)258125e992a4SHeiner Kallweit static void rtl_set_rx_max_size(struct rtl8169_private *tp)
258225e992a4SHeiner Kallweit {
258325e992a4SHeiner Kallweit /* Low hurts. Let's disable the filtering. */
258425e992a4SHeiner Kallweit RTL_W16(tp, RxMaxSize, R8169_RX_BUF_SIZE + 1);
258525e992a4SHeiner Kallweit }
258625e992a4SHeiner Kallweit
rtl_set_rx_tx_desc_registers(struct rtl8169_private * tp)258725e992a4SHeiner Kallweit static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp)
258825e992a4SHeiner Kallweit {
258925e992a4SHeiner Kallweit /*
259025e992a4SHeiner Kallweit * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
259125e992a4SHeiner Kallweit * register to be written before TxDescAddrLow to work.
259225e992a4SHeiner Kallweit * Switching from MMIO to I/O access fixes the issue as well.
259325e992a4SHeiner Kallweit */
259425e992a4SHeiner Kallweit RTL_W32(tp, TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
259525e992a4SHeiner Kallweit RTL_W32(tp, TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32));
259625e992a4SHeiner Kallweit RTL_W32(tp, RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
259725e992a4SHeiner Kallweit RTL_W32(tp, RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32));
259825e992a4SHeiner Kallweit }
259925e992a4SHeiner Kallweit
rtl8169_set_magic_reg(struct rtl8169_private * tp)2600ef891284SHeiner Kallweit static void rtl8169_set_magic_reg(struct rtl8169_private *tp)
260125e992a4SHeiner Kallweit {
260225e992a4SHeiner Kallweit u32 val;
260325e992a4SHeiner Kallweit
260425e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05)
260525e992a4SHeiner Kallweit val = 0x000fff00;
260625e992a4SHeiner Kallweit else if (tp->mac_version == RTL_GIGA_MAC_VER_06)
260725e992a4SHeiner Kallweit val = 0x00ffff00;
260825e992a4SHeiner Kallweit else
260925e992a4SHeiner Kallweit return;
261025e992a4SHeiner Kallweit
261125e992a4SHeiner Kallweit if (RTL_R8(tp, Config2) & PCI_Clock_66MHz)
261225e992a4SHeiner Kallweit val |= 0xff;
261325e992a4SHeiner Kallweit
261425e992a4SHeiner Kallweit RTL_W32(tp, 0x7c, val);
261525e992a4SHeiner Kallweit }
261625e992a4SHeiner Kallweit
rtl_set_rx_mode(struct net_device * dev)261725e992a4SHeiner Kallweit static void rtl_set_rx_mode(struct net_device *dev)
261825e992a4SHeiner Kallweit {
261981cd17a4SHeiner Kallweit u32 rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
262081cd17a4SHeiner Kallweit /* Multicast hash filter */
262181cd17a4SHeiner Kallweit u32 mc_filter[2] = { 0xffffffff, 0xffffffff };
262225e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
262381cd17a4SHeiner Kallweit u32 tmp;
262425e992a4SHeiner Kallweit
262525e992a4SHeiner Kallweit if (dev->flags & IFF_PROMISC) {
262681cd17a4SHeiner Kallweit rx_mode |= AcceptAllPhys;
26271a76fd99SHeiner Kallweit } else if (!(dev->flags & IFF_MULTICAST)) {
26281a76fd99SHeiner Kallweit rx_mode &= ~AcceptMulticast;
262981cd17a4SHeiner Kallweit } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
263081cd17a4SHeiner Kallweit dev->flags & IFF_ALLMULTI ||
26310c7a3af8SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_35) {
263281cd17a4SHeiner Kallweit /* accept all multicasts */
263381cd17a4SHeiner Kallweit } else if (netdev_mc_empty(dev)) {
263481cd17a4SHeiner Kallweit rx_mode &= ~AcceptMulticast;
263525e992a4SHeiner Kallweit } else {
263625e992a4SHeiner Kallweit struct netdev_hw_addr *ha;
263725e992a4SHeiner Kallweit
263825e992a4SHeiner Kallweit mc_filter[1] = mc_filter[0] = 0;
263925e992a4SHeiner Kallweit netdev_for_each_mc_addr(ha, dev) {
2640bc54ac36SHeiner Kallweit u32 bit_nr = eth_hw_addr_crc(ha) >> 26;
264181cd17a4SHeiner Kallweit mc_filter[bit_nr >> 5] |= BIT(bit_nr & 31);
264281cd17a4SHeiner Kallweit }
264381cd17a4SHeiner Kallweit
264481cd17a4SHeiner Kallweit if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
264581cd17a4SHeiner Kallweit tmp = mc_filter[0];
264681cd17a4SHeiner Kallweit mc_filter[0] = swab32(mc_filter[1]);
264781cd17a4SHeiner Kallweit mc_filter[1] = swab32(tmp);
264825e992a4SHeiner Kallweit }
264925e992a4SHeiner Kallweit }
265025e992a4SHeiner Kallweit
265125e992a4SHeiner Kallweit RTL_W32(tp, MAR0 + 4, mc_filter[1]);
265225e992a4SHeiner Kallweit RTL_W32(tp, MAR0 + 0, mc_filter[0]);
265325e992a4SHeiner Kallweit
265481cd17a4SHeiner Kallweit tmp = RTL_R32(tp, RxConfig);
265510478283SHeiner Kallweit RTL_W32(tp, RxConfig, (tmp & ~RX_CONFIG_ACCEPT_OK_MASK) | rx_mode);
265625e992a4SHeiner Kallweit }
265725e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_csiar_cond)265825e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_csiar_cond)
265925e992a4SHeiner Kallweit {
266025e992a4SHeiner Kallweit return RTL_R32(tp, CSIAR) & CSIAR_FLAG;
266125e992a4SHeiner Kallweit }
266225e992a4SHeiner Kallweit
rtl_csi_write(struct rtl8169_private * tp,int addr,int value)266325e992a4SHeiner Kallweit static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value)
266425e992a4SHeiner Kallweit {
266525e992a4SHeiner Kallweit u32 func = PCI_FUNC(tp->pci_dev->devfn);
266625e992a4SHeiner Kallweit
266725e992a4SHeiner Kallweit RTL_W32(tp, CSIDR, value);
266825e992a4SHeiner Kallweit RTL_W32(tp, CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
266925e992a4SHeiner Kallweit CSIAR_BYTE_ENABLE | func << 16);
267025e992a4SHeiner Kallweit
2671d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_csiar_cond, 10, 100);
267225e992a4SHeiner Kallweit }
267325e992a4SHeiner Kallweit
rtl_csi_read(struct rtl8169_private * tp,int addr)267425e992a4SHeiner Kallweit static u32 rtl_csi_read(struct rtl8169_private *tp, int addr)
267525e992a4SHeiner Kallweit {
267625e992a4SHeiner Kallweit u32 func = PCI_FUNC(tp->pci_dev->devfn);
267725e992a4SHeiner Kallweit
267825e992a4SHeiner Kallweit RTL_W32(tp, CSIAR, (addr & CSIAR_ADDR_MASK) | func << 16 |
267925e992a4SHeiner Kallweit CSIAR_BYTE_ENABLE);
268025e992a4SHeiner Kallweit
2681d6836ef0SHeiner Kallweit return rtl_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
268225e992a4SHeiner Kallweit RTL_R32(tp, CSIDR) : ~0;
268325e992a4SHeiner Kallweit }
268425e992a4SHeiner Kallweit
rtl_set_aspm_entry_latency(struct rtl8169_private * tp,u8 val)2685c07c8ffcSHeiner Kallweit static void rtl_set_aspm_entry_latency(struct rtl8169_private *tp, u8 val)
268625e992a4SHeiner Kallweit {
268725e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev;
268825e992a4SHeiner Kallweit u32 csi;
268925e992a4SHeiner Kallweit
269025e992a4SHeiner Kallweit /* According to Realtek the value at config space address 0x070f
269125e992a4SHeiner Kallweit * controls the L0s/L1 entrance latency. We try standard ECAM access
269225e992a4SHeiner Kallweit * first and if it fails fall back to CSI.
2693c07c8ffcSHeiner Kallweit * bit 0..2: L0: 0 = 1us, 1 = 2us .. 6 = 7us, 7 = 7us (no typo)
2694c07c8ffcSHeiner Kallweit * bit 3..5: L1: 0 = 1us, 1 = 2us .. 6 = 64us, 7 = 64us
269525e992a4SHeiner Kallweit */
269625e992a4SHeiner Kallweit if (pdev->cfg_size > 0x070f &&
269725e992a4SHeiner Kallweit pci_write_config_byte(pdev, 0x070f, val) == PCIBIOS_SUCCESSFUL)
269825e992a4SHeiner Kallweit return;
269925e992a4SHeiner Kallweit
270025e992a4SHeiner Kallweit netdev_notice_once(tp->dev,
270125e992a4SHeiner Kallweit "No native access to PCI extended config space, falling back to CSI\n");
270225e992a4SHeiner Kallweit csi = rtl_csi_read(tp, 0x070c) & 0x00ffffff;
270325e992a4SHeiner Kallweit rtl_csi_write(tp, 0x070c, csi | val << 24);
270425e992a4SHeiner Kallweit }
270525e992a4SHeiner Kallweit
rtl_set_def_aspm_entry_latency(struct rtl8169_private * tp)270625e992a4SHeiner Kallweit static void rtl_set_def_aspm_entry_latency(struct rtl8169_private *tp)
270725e992a4SHeiner Kallweit {
2708c07c8ffcSHeiner Kallweit /* L0 7us, L1 16us */
2709c07c8ffcSHeiner Kallweit rtl_set_aspm_entry_latency(tp, 0x27);
271025e992a4SHeiner Kallweit }
271125e992a4SHeiner Kallweit
271225e992a4SHeiner Kallweit struct ephy_info {
271325e992a4SHeiner Kallweit unsigned int offset;
271425e992a4SHeiner Kallweit u16 mask;
271525e992a4SHeiner Kallweit u16 bits;
271625e992a4SHeiner Kallweit };
271725e992a4SHeiner Kallweit
__rtl_ephy_init(struct rtl8169_private * tp,const struct ephy_info * e,int len)271825e992a4SHeiner Kallweit static void __rtl_ephy_init(struct rtl8169_private *tp,
271925e992a4SHeiner Kallweit const struct ephy_info *e, int len)
272025e992a4SHeiner Kallweit {
272125e992a4SHeiner Kallweit u16 w;
272225e992a4SHeiner Kallweit
272325e992a4SHeiner Kallweit while (len-- > 0) {
272425e992a4SHeiner Kallweit w = (rtl_ephy_read(tp, e->offset) & ~e->mask) | e->bits;
272525e992a4SHeiner Kallweit rtl_ephy_write(tp, e->offset, w);
272625e992a4SHeiner Kallweit e++;
272725e992a4SHeiner Kallweit }
272825e992a4SHeiner Kallweit }
272925e992a4SHeiner Kallweit
273025e992a4SHeiner Kallweit #define rtl_ephy_init(tp, a) __rtl_ephy_init(tp, a, ARRAY_SIZE(a))
273125e992a4SHeiner Kallweit
rtl_disable_clock_request(struct rtl8169_private * tp)273225e992a4SHeiner Kallweit static void rtl_disable_clock_request(struct rtl8169_private *tp)
273325e992a4SHeiner Kallweit {
273425e992a4SHeiner Kallweit pcie_capability_clear_word(tp->pci_dev, PCI_EXP_LNKCTL,
273525e992a4SHeiner Kallweit PCI_EXP_LNKCTL_CLKREQ_EN);
273625e992a4SHeiner Kallweit }
273725e992a4SHeiner Kallweit
rtl_enable_clock_request(struct rtl8169_private * tp)273825e992a4SHeiner Kallweit static void rtl_enable_clock_request(struct rtl8169_private *tp)
273925e992a4SHeiner Kallweit {
274025e992a4SHeiner Kallweit pcie_capability_set_word(tp->pci_dev, PCI_EXP_LNKCTL,
274125e992a4SHeiner Kallweit PCI_EXP_LNKCTL_CLKREQ_EN);
274225e992a4SHeiner Kallweit }
274325e992a4SHeiner Kallweit
rtl_pcie_state_l2l3_disable(struct rtl8169_private * tp)274425e992a4SHeiner Kallweit static void rtl_pcie_state_l2l3_disable(struct rtl8169_private *tp)
274525e992a4SHeiner Kallweit {
274625e992a4SHeiner Kallweit /* work around an issue when PCI reset occurs during L2/L3 state */
274725e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Rdy_to_L23);
274825e992a4SHeiner Kallweit }
274925e992a4SHeiner Kallweit
rtl_enable_exit_l1(struct rtl8169_private * tp)27504b33433eSHeiner Kallweit static void rtl_enable_exit_l1(struct rtl8169_private *tp)
27514b33433eSHeiner Kallweit {
27524b33433eSHeiner Kallweit /* Bits control which events trigger ASPM L1 exit:
27534b33433eSHeiner Kallweit * Bit 12: rxdv
27544b33433eSHeiner Kallweit * Bit 11: ltr_msg
27554b33433eSHeiner Kallweit * Bit 10: txdma_poll
27564b33433eSHeiner Kallweit * Bit 9: xadm
27574b33433eSHeiner Kallweit * Bit 8: pktavi
27584b33433eSHeiner Kallweit * Bit 7: txpla
27594b33433eSHeiner Kallweit */
27604b33433eSHeiner Kallweit switch (tp->mac_version) {
27614b33433eSHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_36:
27624b33433eSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x1f00);
27634b33433eSHeiner Kallweit break;
27644b33433eSHeiner Kallweit case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
27654b33433eSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x0c00);
27664b33433eSHeiner Kallweit break;
2767d192181cSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
27684b33433eSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
27694b33433eSHeiner Kallweit break;
27704b33433eSHeiner Kallweit default:
27714b33433eSHeiner Kallweit break;
27724b33433eSHeiner Kallweit }
27734b33433eSHeiner Kallweit }
27744b33433eSHeiner Kallweit
rtl_disable_exit_l1(struct rtl8169_private * tp)2775d192181cSHeiner Kallweit static void rtl_disable_exit_l1(struct rtl8169_private *tp)
2776d192181cSHeiner Kallweit {
2777d192181cSHeiner Kallweit switch (tp->mac_version) {
2778d192181cSHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
2779d192181cSHeiner Kallweit rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
2780d192181cSHeiner Kallweit break;
2781d192181cSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
2782d192181cSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
2783d192181cSHeiner Kallweit break;
2784d192181cSHeiner Kallweit default:
2785d192181cSHeiner Kallweit break;
2786d192181cSHeiner Kallweit }
2787d192181cSHeiner Kallweit }
2788d192181cSHeiner Kallweit
rtl_hw_aspm_clkreq_enable(struct rtl8169_private * tp,bool enable)278925e992a4SHeiner Kallweit static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
279025e992a4SHeiner Kallweit {
279149ef7d84SHeiner Kallweit if (tp->mac_version < RTL_GIGA_MAC_VER_32)
279249ef7d84SHeiner Kallweit return;
279349ef7d84SHeiner Kallweit
2794cf2ffdeaSHeiner Kallweit /* Don't enable ASPM in the chip if OS can't control ASPM */
2795cf2ffdeaSHeiner Kallweit if (enable && tp->aspm_manageable) {
2796162d626fSHeiner Kallweit /* On these chip versions ASPM can even harm
2797162d626fSHeiner Kallweit * bus communication of other PCI devices.
2798162d626fSHeiner Kallweit */
2799162d626fSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_42 ||
2800162d626fSHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_43)
2801162d626fSHeiner Kallweit return;
2802162d626fSHeiner Kallweit
28036bc6c4e6SHeiner Kallweit rtl_mod_config5(tp, 0, ASPM_en);
28046bc6c4e6SHeiner Kallweit rtl_mod_config2(tp, 0, ClkReqEn);
2805c217ab7aSHeiner Kallweit
2806c217ab7aSHeiner Kallweit switch (tp->mac_version) {
2807ebe59898SHeiner Kallweit case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
2808efc37109SHeiner Kallweit case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
2809c217ab7aSHeiner Kallweit /* reset ephy tx/rx disable timer */
2810c217ab7aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
2811c217ab7aSHeiner Kallweit /* chip can trigger L1.2 */
2812c217ab7aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, BIT(2));
2813c217ab7aSHeiner Kallweit break;
2814c217ab7aSHeiner Kallweit default:
2815c217ab7aSHeiner Kallweit break;
2816c217ab7aSHeiner Kallweit }
281725e992a4SHeiner Kallweit } else {
2818c217ab7aSHeiner Kallweit switch (tp->mac_version) {
2819ebe59898SHeiner Kallweit case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
2820efc37109SHeiner Kallweit case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
2821c217ab7aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
2822c217ab7aSHeiner Kallweit break;
2823c217ab7aSHeiner Kallweit default:
2824c217ab7aSHeiner Kallweit break;
2825c217ab7aSHeiner Kallweit }
2826c217ab7aSHeiner Kallweit
28276bc6c4e6SHeiner Kallweit rtl_mod_config2(tp, ClkReqEn, 0);
28286bc6c4e6SHeiner Kallweit rtl_mod_config5(tp, ASPM_en, 0);
282925e992a4SHeiner Kallweit }
283025e992a4SHeiner Kallweit }
283125e992a4SHeiner Kallweit
rtl_set_fifo_size(struct rtl8169_private * tp,u16 rx_stat,u16 tx_stat,u16 rx_dyn,u16 tx_dyn)283225e992a4SHeiner Kallweit static void rtl_set_fifo_size(struct rtl8169_private *tp, u16 rx_stat,
283325e992a4SHeiner Kallweit u16 tx_stat, u16 rx_dyn, u16 tx_dyn)
283425e992a4SHeiner Kallweit {
283525e992a4SHeiner Kallweit /* Usage of dynamic vs. static FIFO is controlled by bit
283625e992a4SHeiner Kallweit * TXCFG_AUTO_FIFO. Exact meaning of FIFO values isn't known.
283725e992a4SHeiner Kallweit */
283825e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, (rx_stat << 16) | rx_dyn);
283925e992a4SHeiner Kallweit rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, (tx_stat << 16) | tx_dyn);
284025e992a4SHeiner Kallweit }
284125e992a4SHeiner Kallweit
rtl8168g_set_pause_thresholds(struct rtl8169_private * tp,u8 low,u8 high)284225e992a4SHeiner Kallweit static void rtl8168g_set_pause_thresholds(struct rtl8169_private *tp,
284325e992a4SHeiner Kallweit u8 low, u8 high)
284425e992a4SHeiner Kallweit {
284525e992a4SHeiner Kallweit /* FIFO thresholds for pause flow control */
284625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, low);
284725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, high);
284825e992a4SHeiner Kallweit }
284925e992a4SHeiner Kallweit
rtl_hw_start_8168b(struct rtl8169_private * tp)285094b5ff74SHeiner Kallweit static void rtl_hw_start_8168b(struct rtl8169_private *tp)
285125e992a4SHeiner Kallweit {
285225e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
285325e992a4SHeiner Kallweit }
285425e992a4SHeiner Kallweit
__rtl_hw_start_8168cp(struct rtl8169_private * tp)285525e992a4SHeiner Kallweit static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
285625e992a4SHeiner Kallweit {
285725e992a4SHeiner Kallweit RTL_W8(tp, Config1, RTL_R8(tp, Config1) | Speed_down);
285825e992a4SHeiner Kallweit
285925e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
286025e992a4SHeiner Kallweit
286125e992a4SHeiner Kallweit rtl_disable_clock_request(tp);
286225e992a4SHeiner Kallweit }
286325e992a4SHeiner Kallweit
rtl_hw_start_8168cp_1(struct rtl8169_private * tp)286425e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp)
286525e992a4SHeiner Kallweit {
286625e992a4SHeiner Kallweit static const struct ephy_info e_info_8168cp[] = {
286725e992a4SHeiner Kallweit { 0x01, 0, 0x0001 },
286825e992a4SHeiner Kallweit { 0x02, 0x0800, 0x1000 },
286925e992a4SHeiner Kallweit { 0x03, 0, 0x0042 },
287025e992a4SHeiner Kallweit { 0x06, 0x0080, 0x0000 },
287125e992a4SHeiner Kallweit { 0x07, 0, 0x2000 }
287225e992a4SHeiner Kallweit };
287325e992a4SHeiner Kallweit
287425e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
287525e992a4SHeiner Kallweit
287625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168cp);
287725e992a4SHeiner Kallweit
287825e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp);
287925e992a4SHeiner Kallweit }
288025e992a4SHeiner Kallweit
rtl_hw_start_8168cp_2(struct rtl8169_private * tp)288125e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp)
288225e992a4SHeiner Kallweit {
288325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
288425e992a4SHeiner Kallweit
288525e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
288625e992a4SHeiner Kallweit }
288725e992a4SHeiner Kallweit
rtl_hw_start_8168cp_3(struct rtl8169_private * tp)288825e992a4SHeiner Kallweit static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp)
288925e992a4SHeiner Kallweit {
289025e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
289125e992a4SHeiner Kallweit
289225e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
289325e992a4SHeiner Kallweit
289425e992a4SHeiner Kallweit /* Magic. */
289525e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, 0x20);
289625e992a4SHeiner Kallweit }
289725e992a4SHeiner Kallweit
rtl_hw_start_8168c_1(struct rtl8169_private * tp)289825e992a4SHeiner Kallweit static void rtl_hw_start_8168c_1(struct rtl8169_private *tp)
289925e992a4SHeiner Kallweit {
290025e992a4SHeiner Kallweit static const struct ephy_info e_info_8168c_1[] = {
290125e992a4SHeiner Kallweit { 0x02, 0x0800, 0x1000 },
290225e992a4SHeiner Kallweit { 0x03, 0, 0x0002 },
290325e992a4SHeiner Kallweit { 0x06, 0x0080, 0x0000 }
290425e992a4SHeiner Kallweit };
290525e992a4SHeiner Kallweit
290625e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
290725e992a4SHeiner Kallweit
290825e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2);
290925e992a4SHeiner Kallweit
291025e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168c_1);
291125e992a4SHeiner Kallweit
291225e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp);
291325e992a4SHeiner Kallweit }
291425e992a4SHeiner Kallweit
rtl_hw_start_8168c_2(struct rtl8169_private * tp)291525e992a4SHeiner Kallweit static void rtl_hw_start_8168c_2(struct rtl8169_private *tp)
291625e992a4SHeiner Kallweit {
291725e992a4SHeiner Kallweit static const struct ephy_info e_info_8168c_2[] = {
291825e992a4SHeiner Kallweit { 0x01, 0, 0x0001 },
2919a7a92cf8SHeiner Kallweit { 0x03, 0x0400, 0x0020 }
292025e992a4SHeiner Kallweit };
292125e992a4SHeiner Kallweit
292225e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
292325e992a4SHeiner Kallweit
292425e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168c_2);
292525e992a4SHeiner Kallweit
292625e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp);
292725e992a4SHeiner Kallweit }
292825e992a4SHeiner Kallweit
rtl_hw_start_8168c_4(struct rtl8169_private * tp)292925e992a4SHeiner Kallweit static void rtl_hw_start_8168c_4(struct rtl8169_private *tp)
293025e992a4SHeiner Kallweit {
293125e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
293225e992a4SHeiner Kallweit
293325e992a4SHeiner Kallweit __rtl_hw_start_8168cp(tp);
293425e992a4SHeiner Kallweit }
293525e992a4SHeiner Kallweit
rtl_hw_start_8168d(struct rtl8169_private * tp)293625e992a4SHeiner Kallweit static void rtl_hw_start_8168d(struct rtl8169_private *tp)
293725e992a4SHeiner Kallweit {
293825e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
293925e992a4SHeiner Kallweit
294025e992a4SHeiner Kallweit rtl_disable_clock_request(tp);
294125e992a4SHeiner Kallweit }
294225e992a4SHeiner Kallweit
rtl_hw_start_8168d_4(struct rtl8169_private * tp)294325e992a4SHeiner Kallweit static void rtl_hw_start_8168d_4(struct rtl8169_private *tp)
294425e992a4SHeiner Kallweit {
294525e992a4SHeiner Kallweit static const struct ephy_info e_info_8168d_4[] = {
294625e992a4SHeiner Kallweit { 0x0b, 0x0000, 0x0048 },
294725e992a4SHeiner Kallweit { 0x19, 0x0020, 0x0050 },
2948a7a92cf8SHeiner Kallweit { 0x0c, 0x0100, 0x0020 },
2949a7a92cf8SHeiner Kallweit { 0x10, 0x0004, 0x0000 },
295025e992a4SHeiner Kallweit };
295125e992a4SHeiner Kallweit
295225e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
295325e992a4SHeiner Kallweit
295425e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168d_4);
295525e992a4SHeiner Kallweit
295625e992a4SHeiner Kallweit rtl_enable_clock_request(tp);
295725e992a4SHeiner Kallweit }
295825e992a4SHeiner Kallweit
rtl_hw_start_8168e_1(struct rtl8169_private * tp)295925e992a4SHeiner Kallweit static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
296025e992a4SHeiner Kallweit {
296125e992a4SHeiner Kallweit static const struct ephy_info e_info_8168e_1[] = {
296225e992a4SHeiner Kallweit { 0x00, 0x0200, 0x0100 },
296325e992a4SHeiner Kallweit { 0x00, 0x0000, 0x0004 },
296425e992a4SHeiner Kallweit { 0x06, 0x0002, 0x0001 },
296525e992a4SHeiner Kallweit { 0x06, 0x0000, 0x0030 },
296625e992a4SHeiner Kallweit { 0x07, 0x0000, 0x2000 },
296725e992a4SHeiner Kallweit { 0x00, 0x0000, 0x0020 },
296825e992a4SHeiner Kallweit { 0x03, 0x5800, 0x2000 },
296925e992a4SHeiner Kallweit { 0x03, 0x0000, 0x0001 },
297025e992a4SHeiner Kallweit { 0x01, 0x0800, 0x1000 },
297125e992a4SHeiner Kallweit { 0x07, 0x0000, 0x4000 },
297225e992a4SHeiner Kallweit { 0x1e, 0x0000, 0x2000 },
297325e992a4SHeiner Kallweit { 0x19, 0xffff, 0xfe6c },
297425e992a4SHeiner Kallweit { 0x0a, 0x0000, 0x0040 }
297525e992a4SHeiner Kallweit };
297625e992a4SHeiner Kallweit
297725e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
297825e992a4SHeiner Kallweit
297925e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168e_1);
298025e992a4SHeiner Kallweit
298125e992a4SHeiner Kallweit rtl_disable_clock_request(tp);
298225e992a4SHeiner Kallweit
298325e992a4SHeiner Kallweit /* Reset tx FIFO pointer */
298425e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | TXPLA_RST);
298525e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~TXPLA_RST);
298625e992a4SHeiner Kallweit
29876bc6c4e6SHeiner Kallweit rtl_mod_config5(tp, Spi_en, 0);
298825e992a4SHeiner Kallweit }
298925e992a4SHeiner Kallweit
rtl_hw_start_8168e_2(struct rtl8169_private * tp)299025e992a4SHeiner Kallweit static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
299125e992a4SHeiner Kallweit {
299225e992a4SHeiner Kallweit static const struct ephy_info e_info_8168e_2[] = {
299325e992a4SHeiner Kallweit { 0x09, 0x0000, 0x0080 },
2994a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 },
2995a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0004 },
2996a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 },
299725e992a4SHeiner Kallweit };
299825e992a4SHeiner Kallweit
299925e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
300025e992a4SHeiner Kallweit
300125e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168e_2);
300225e992a4SHeiner Kallweit
300325e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
300433b00ca1SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_1111, 0x0000);
300525e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06);
300633b00ca1SHeiner Kallweit rtl_eri_set_bits(tp, 0x1d0, BIT(1));
300733b00ca1SHeiner Kallweit rtl_reset_packet_filter(tp);
300833b00ca1SHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, BIT(4));
300925e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050);
301025e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x07ff0060);
301125e992a4SHeiner Kallweit
301225e992a4SHeiner Kallweit rtl_disable_clock_request(tp);
301325e992a4SHeiner Kallweit
301425e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
301525e992a4SHeiner Kallweit
301625e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp);
301725e992a4SHeiner Kallweit
301825e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN);
301925e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN);
30206bc6c4e6SHeiner Kallweit rtl_mod_config5(tp, Spi_en, 0);
302125e992a4SHeiner Kallweit }
302225e992a4SHeiner Kallweit
rtl_hw_start_8168f(struct rtl8169_private * tp)302325e992a4SHeiner Kallweit static void rtl_hw_start_8168f(struct rtl8169_private *tp)
302425e992a4SHeiner Kallweit {
302525e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
302625e992a4SHeiner Kallweit
302725e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
3028d05890c5SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_1111, 0x0000);
302925e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06);
303025e992a4SHeiner Kallweit rtl_reset_packet_filter(tp);
303154113dedSHeiner Kallweit rtl_eri_set_bits(tp, 0x1b0, BIT(4));
3032d05890c5SHeiner Kallweit rtl_eri_set_bits(tp, 0x1d0, BIT(4) | BIT(1));
303325e992a4SHeiner Kallweit rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050);
303425e992a4SHeiner Kallweit rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060);
303525e992a4SHeiner Kallweit
303625e992a4SHeiner Kallweit rtl_disable_clock_request(tp);
303725e992a4SHeiner Kallweit
303825e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
303925e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN);
304025e992a4SHeiner Kallweit RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN);
30416bc6c4e6SHeiner Kallweit rtl_mod_config5(tp, Spi_en, 0);
304225e992a4SHeiner Kallweit
304325e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp);
304425e992a4SHeiner Kallweit }
304525e992a4SHeiner Kallweit
rtl_hw_start_8168f_1(struct rtl8169_private * tp)304625e992a4SHeiner Kallweit static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
304725e992a4SHeiner Kallweit {
304825e992a4SHeiner Kallweit static const struct ephy_info e_info_8168f_1[] = {
304925e992a4SHeiner Kallweit { 0x06, 0x00c0, 0x0020 },
305025e992a4SHeiner Kallweit { 0x08, 0x0001, 0x0002 },
305125e992a4SHeiner Kallweit { 0x09, 0x0000, 0x0080 },
3052a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 },
3053709a16beSHeiner Kallweit { 0x00, 0x0000, 0x0008 },
3054a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 },
305525e992a4SHeiner Kallweit };
305625e992a4SHeiner Kallweit
305725e992a4SHeiner Kallweit rtl_hw_start_8168f(tp);
305825e992a4SHeiner Kallweit
305925e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168f_1);
306025e992a4SHeiner Kallweit }
306125e992a4SHeiner Kallweit
rtl_hw_start_8411(struct rtl8169_private * tp)306225e992a4SHeiner Kallweit static void rtl_hw_start_8411(struct rtl8169_private *tp)
306325e992a4SHeiner Kallweit {
306425e992a4SHeiner Kallweit static const struct ephy_info e_info_8168f_1[] = {
306525e992a4SHeiner Kallweit { 0x06, 0x00c0, 0x0020 },
306625e992a4SHeiner Kallweit { 0x0f, 0xffff, 0x5200 },
3067a7a92cf8SHeiner Kallweit { 0x19, 0x0000, 0x0224 },
3068709a16beSHeiner Kallweit { 0x00, 0x0000, 0x0008 },
3069a7a92cf8SHeiner Kallweit { 0x0c, 0x3df0, 0x0200 },
307025e992a4SHeiner Kallweit };
307125e992a4SHeiner Kallweit
307225e992a4SHeiner Kallweit rtl_hw_start_8168f(tp);
307325e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
307425e992a4SHeiner Kallweit
307525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168f_1);
307625e992a4SHeiner Kallweit }
307725e992a4SHeiner Kallweit
rtl_hw_start_8168g(struct rtl8169_private * tp)307825e992a4SHeiner Kallweit static void rtl_hw_start_8168g(struct rtl8169_private *tp)
307925e992a4SHeiner Kallweit {
308025e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06);
308125e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x38, 0x48);
308225e992a4SHeiner Kallweit
308325e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
308425e992a4SHeiner Kallweit
308525e992a4SHeiner Kallweit rtl_reset_packet_filter(tp);
308625e992a4SHeiner Kallweit rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f);
308725e992a4SHeiner Kallweit
30883406079bSChunhao Lin rtl_disable_rxdvgate(tp);
308925e992a4SHeiner Kallweit
309025e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
309125e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000);
309225e992a4SHeiner Kallweit
309325e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp);
309425e992a4SHeiner Kallweit
309554113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x2fc, 0x01, 0x06);
309654113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12));
309725e992a4SHeiner Kallweit
309825e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
309925e992a4SHeiner Kallweit }
310025e992a4SHeiner Kallweit
rtl_hw_start_8168g_1(struct rtl8169_private * tp)310125e992a4SHeiner Kallweit static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
310225e992a4SHeiner Kallweit {
310325e992a4SHeiner Kallweit static const struct ephy_info e_info_8168g_1[] = {
3104a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 },
3105a7a92cf8SHeiner Kallweit { 0x0c, 0x3ff0, 0x0820 },
310625e992a4SHeiner Kallweit { 0x1e, 0x0000, 0x0001 },
310725e992a4SHeiner Kallweit { 0x19, 0x8000, 0x0000 }
310825e992a4SHeiner Kallweit };
310925e992a4SHeiner Kallweit
311025e992a4SHeiner Kallweit rtl_hw_start_8168g(tp);
311125e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168g_1);
311225e992a4SHeiner Kallweit }
311325e992a4SHeiner Kallweit
rtl_hw_start_8168g_2(struct rtl8169_private * tp)311425e992a4SHeiner Kallweit static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
311525e992a4SHeiner Kallweit {
311625e992a4SHeiner Kallweit static const struct ephy_info e_info_8168g_2[] = {
3117a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 },
3118a7a92cf8SHeiner Kallweit { 0x0c, 0x3ff0, 0x0820 },
3119a7a92cf8SHeiner Kallweit { 0x19, 0xffff, 0x7c00 },
3120a7a92cf8SHeiner Kallweit { 0x1e, 0xffff, 0x20eb },
3121a7a92cf8SHeiner Kallweit { 0x0d, 0xffff, 0x1666 },
3122a7a92cf8SHeiner Kallweit { 0x00, 0xffff, 0x10a3 },
3123a7a92cf8SHeiner Kallweit { 0x06, 0xffff, 0xf050 },
3124a7a92cf8SHeiner Kallweit { 0x04, 0x0000, 0x0010 },
3125a7a92cf8SHeiner Kallweit { 0x1d, 0x4000, 0x0000 },
312625e992a4SHeiner Kallweit };
312725e992a4SHeiner Kallweit
312825e992a4SHeiner Kallweit rtl_hw_start_8168g(tp);
312925e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168g_2);
313025e992a4SHeiner Kallweit }
313125e992a4SHeiner Kallweit
rtl_hw_start_8411_2(struct rtl8169_private * tp)313225e992a4SHeiner Kallweit static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
313325e992a4SHeiner Kallweit {
313425e992a4SHeiner Kallweit static const struct ephy_info e_info_8411_2[] = {
3135a7a92cf8SHeiner Kallweit { 0x00, 0x0008, 0x0000 },
3136a7a92cf8SHeiner Kallweit { 0x0c, 0x37d0, 0x0820 },
3137a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x0001 },
3138a7a92cf8SHeiner Kallweit { 0x19, 0x8021, 0x0000 },
3139a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x2000 },
3140a7a92cf8SHeiner Kallweit { 0x0d, 0x0100, 0x0200 },
3141a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0080 },
3142a7a92cf8SHeiner Kallweit { 0x06, 0x0000, 0x0010 },
3143a7a92cf8SHeiner Kallweit { 0x04, 0x0000, 0x0010 },
3144a7a92cf8SHeiner Kallweit { 0x1d, 0x0000, 0x4000 },
314525e992a4SHeiner Kallweit };
314625e992a4SHeiner Kallweit
314725e992a4SHeiner Kallweit rtl_hw_start_8168g(tp);
314825e992a4SHeiner Kallweit
314925e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8411_2);
3150fe4e8db0SHeiner Kallweit
3151fe4e8db0SHeiner Kallweit /* The following Realtek-provided magic fixes an issue with the RX unit
3152fe4e8db0SHeiner Kallweit * getting confused after the PHY having been powered-down.
3153fe4e8db0SHeiner Kallweit */
3154fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC28, 0x0000);
3155fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2A, 0x0000);
3156fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2C, 0x0000);
3157fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2E, 0x0000);
3158fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC30, 0x0000);
3159fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC32, 0x0000);
3160fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC34, 0x0000);
3161fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC36, 0x0000);
3162fe4e8db0SHeiner Kallweit mdelay(3);
3163fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC26, 0x0000);
3164fe4e8db0SHeiner Kallweit
3165fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF800, 0xE008);
3166fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF802, 0xE00A);
3167fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF804, 0xE00C);
3168fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF806, 0xE00E);
3169fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF808, 0xE027);
3170fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80A, 0xE04F);
3171fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80C, 0xE05E);
3172fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF80E, 0xE065);
3173fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF810, 0xC602);
3174fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF812, 0xBE00);
3175fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF814, 0x0000);
3176fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF816, 0xC502);
3177fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF818, 0xBD00);
3178fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81A, 0x074C);
3179fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81C, 0xC302);
3180fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF81E, 0xBB00);
3181fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF820, 0x080A);
3182fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF822, 0x6420);
3183fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF824, 0x48C2);
3184fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF826, 0x8C20);
3185fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF828, 0xC516);
3186fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82A, 0x64A4);
3187fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82C, 0x49C0);
3188fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF82E, 0xF009);
3189fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF830, 0x74A2);
3190fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF832, 0x8CA5);
3191fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF834, 0x74A0);
3192fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF836, 0xC50E);
3193fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF838, 0x9CA2);
3194fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83A, 0x1C11);
3195fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83C, 0x9CA0);
3196fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF83E, 0xE006);
3197fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF840, 0x74F8);
3198fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF842, 0x48C4);
3199fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF844, 0x8CF8);
3200fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF846, 0xC404);
3201fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF848, 0xBC00);
3202fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84A, 0xC403);
3203fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84C, 0xBC00);
3204fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF84E, 0x0BF2);
3205fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF850, 0x0C0A);
3206fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF852, 0xE434);
3207fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF854, 0xD3C0);
3208fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF856, 0x49D9);
3209fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF858, 0xF01F);
3210fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85A, 0xC526);
3211fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85C, 0x64A5);
3212fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF85E, 0x1400);
3213fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF860, 0xF007);
3214fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF862, 0x0C01);
3215fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF864, 0x8CA5);
3216fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF866, 0x1C15);
3217fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF868, 0xC51B);
3218fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86A, 0x9CA0);
3219fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86C, 0xE013);
3220fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF86E, 0xC519);
3221fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF870, 0x74A0);
3222fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF872, 0x48C4);
3223fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF874, 0x8CA0);
3224fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF876, 0xC516);
3225fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF878, 0x74A4);
3226fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87A, 0x48C8);
3227fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87C, 0x48CA);
3228fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF87E, 0x9CA4);
3229fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF880, 0xC512);
3230fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF882, 0x1B00);
3231fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF884, 0x9BA0);
3232fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF886, 0x1B1C);
3233fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF888, 0x483F);
3234fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88A, 0x9BA2);
3235fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88C, 0x1B04);
3236fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF88E, 0xC508);
3237fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF890, 0x9BA0);
3238fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF892, 0xC505);
3239fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF894, 0xBD00);
3240fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF896, 0xC502);
3241fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF898, 0xBD00);
3242fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89A, 0x0300);
3243fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89C, 0x051E);
3244fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF89E, 0xE434);
3245fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A0, 0xE018);
3246fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A2, 0xE092);
3247fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A4, 0xDE20);
3248fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A6, 0xD3C0);
3249fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8A8, 0xC50F);
3250fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AA, 0x76A4);
3251fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AC, 0x49E3);
3252fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8AE, 0xF007);
3253fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B0, 0x49C0);
3254fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B2, 0xF103);
3255fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B4, 0xC607);
3256fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B6, 0xBE00);
3257fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8B8, 0xC606);
3258fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BA, 0xBE00);
3259fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BC, 0xC602);
3260fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8BE, 0xBE00);
3261fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C0, 0x0C4C);
3262fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C2, 0x0C28);
3263fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C4, 0x0C2C);
3264fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C6, 0xDC00);
3265fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8C8, 0xC707);
3266fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CA, 0x1D00);
3267fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CC, 0x8DE2);
3268fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8CE, 0x48C1);
3269fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D0, 0xC502);
3270fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D2, 0xBD00);
3271fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D4, 0x00AA);
3272fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D6, 0xE0C0);
3273fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8D8, 0xC502);
3274fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8DA, 0xBD00);
3275fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xF8DC, 0x0132);
3276fe4e8db0SHeiner Kallweit
3277fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC26, 0x8000);
3278fe4e8db0SHeiner Kallweit
3279fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2A, 0x0743);
3280fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2C, 0x0801);
3281fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC2E, 0x0BE9);
3282fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC30, 0x02FD);
3283fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC32, 0x0C25);
3284fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC34, 0x00A9);
3285fe4e8db0SHeiner Kallweit r8168_mac_ocp_write(tp, 0xFC36, 0x012D);
328625e992a4SHeiner Kallweit }
328725e992a4SHeiner Kallweit
rtl_hw_start_8168h_1(struct rtl8169_private * tp)328825e992a4SHeiner Kallweit static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
328925e992a4SHeiner Kallweit {
329025e992a4SHeiner Kallweit static const struct ephy_info e_info_8168h_1[] = {
329125e992a4SHeiner Kallweit { 0x1e, 0x0800, 0x0001 },
329225e992a4SHeiner Kallweit { 0x1d, 0x0000, 0x0800 },
329325e992a4SHeiner Kallweit { 0x05, 0xffff, 0x2089 },
329425e992a4SHeiner Kallweit { 0x06, 0xffff, 0x5881 },
3295a7a92cf8SHeiner Kallweit { 0x04, 0xffff, 0x854a },
329625e992a4SHeiner Kallweit { 0x01, 0xffff, 0x068b }
329725e992a4SHeiner Kallweit };
3298ef712edeSHeiner Kallweit int rg_saw_cnt;
329925e992a4SHeiner Kallweit
330025e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168h_1);
330125e992a4SHeiner Kallweit
330225e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06);
330325e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x38, 0x48);
330425e992a4SHeiner Kallweit
330525e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
330625e992a4SHeiner Kallweit
330725e992a4SHeiner Kallweit rtl_reset_packet_filter(tp);
330825e992a4SHeiner Kallweit
3309ee1350f9SHeiner Kallweit rtl_eri_set_bits(tp, 0xdc, 0x001c);
331025e992a4SHeiner Kallweit
331125e992a4SHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87);
331225e992a4SHeiner Kallweit
33133406079bSChunhao Lin rtl_disable_rxdvgate(tp);
331425e992a4SHeiner Kallweit
331525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
331625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000);
331725e992a4SHeiner Kallweit
331825e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp);
331925e992a4SHeiner Kallweit
332025e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
332125e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN);
332225e992a4SHeiner Kallweit
332325e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN);
332425e992a4SHeiner Kallweit
332554113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12));
332625e992a4SHeiner Kallweit
332725e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
332825e992a4SHeiner Kallweit
33293ab077d2SHeiner Kallweit rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff;
333025e992a4SHeiner Kallweit if (rg_saw_cnt > 0) {
333125e992a4SHeiner Kallweit u16 sw_cnt_1ms_ini;
333225e992a4SHeiner Kallweit
333325e992a4SHeiner Kallweit sw_cnt_1ms_ini = 16000000/rg_saw_cnt;
333425e992a4SHeiner Kallweit sw_cnt_1ms_ini &= 0x0fff;
3335ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini);
333625e992a4SHeiner Kallweit }
333725e992a4SHeiner Kallweit
3338ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070);
3339ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x6000, 0x8008);
3340ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe0d6, 0x01ff, 0x017f);
3341ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f);
334225e992a4SHeiner Kallweit
334325e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0001);
334425e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0000);
334525e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xc094, 0x0000);
334625e992a4SHeiner Kallweit r8168_mac_ocp_write(tp, 0xc09e, 0x0000);
334725e992a4SHeiner Kallweit }
334825e992a4SHeiner Kallweit
rtl_hw_start_8168ep(struct rtl8169_private * tp)334925e992a4SHeiner Kallweit static void rtl_hw_start_8168ep(struct rtl8169_private *tp)
335025e992a4SHeiner Kallweit {
335125e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp);
335225e992a4SHeiner Kallweit
335325e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06);
335425e992a4SHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f);
335525e992a4SHeiner Kallweit
335625e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
335725e992a4SHeiner Kallweit
335825e992a4SHeiner Kallweit rtl_reset_packet_filter(tp);
335925e992a4SHeiner Kallweit
336025e992a4SHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87);
336125e992a4SHeiner Kallweit
33623406079bSChunhao Lin rtl_disable_rxdvgate(tp);
336325e992a4SHeiner Kallweit
336425e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
336525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000);
336625e992a4SHeiner Kallweit
336725e992a4SHeiner Kallweit rtl8168_config_eee_mac(tp);
336825e992a4SHeiner Kallweit
336954113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x2fc, 0x01, 0x06);
337025e992a4SHeiner Kallweit
337125e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN);
337225e992a4SHeiner Kallweit
337325e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
337425e992a4SHeiner Kallweit }
337525e992a4SHeiner Kallweit
rtl_hw_start_8168ep_3(struct rtl8169_private * tp)337625e992a4SHeiner Kallweit static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp)
337725e992a4SHeiner Kallweit {
337825e992a4SHeiner Kallweit static const struct ephy_info e_info_8168ep_3[] = {
3379a7a92cf8SHeiner Kallweit { 0x00, 0x0000, 0x0080 },
3380a7a92cf8SHeiner Kallweit { 0x0d, 0x0100, 0x0200 },
3381a7a92cf8SHeiner Kallweit { 0x19, 0x8021, 0x0000 },
3382a7a92cf8SHeiner Kallweit { 0x1e, 0x0000, 0x2000 },
338325e992a4SHeiner Kallweit };
338425e992a4SHeiner Kallweit
338525e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8168ep_3);
338625e992a4SHeiner Kallweit
338725e992a4SHeiner Kallweit rtl_hw_start_8168ep(tp);
338825e992a4SHeiner Kallweit
338925e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
339025e992a4SHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN);
339125e992a4SHeiner Kallweit
3392ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e2, 0x0fff, 0x0271);
3393ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e4, 0x00ff, 0x0000);
3394ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe860, 0x0000, 0x0080);
339525e992a4SHeiner Kallweit }
339625e992a4SHeiner Kallweit
rtl_hw_start_8117(struct rtl8169_private * tp)33971287723aSHeiner Kallweit static void rtl_hw_start_8117(struct rtl8169_private *tp)
33981287723aSHeiner Kallweit {
33991287723aSHeiner Kallweit static const struct ephy_info e_info_8117[] = {
34001287723aSHeiner Kallweit { 0x19, 0x0040, 0x1100 },
34011287723aSHeiner Kallweit { 0x59, 0x0040, 0x1100 },
34021287723aSHeiner Kallweit };
34031287723aSHeiner Kallweit int rg_saw_cnt;
34041287723aSHeiner Kallweit
34051287723aSHeiner Kallweit rtl8168ep_stop_cmac(tp);
34061287723aSHeiner Kallweit rtl_ephy_init(tp, e_info_8117);
34071287723aSHeiner Kallweit
34081287723aSHeiner Kallweit rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06);
34091287723aSHeiner Kallweit rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f);
34101287723aSHeiner Kallweit
34111287723aSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
34121287723aSHeiner Kallweit
34131287723aSHeiner Kallweit rtl_reset_packet_filter(tp);
34141287723aSHeiner Kallweit
34154b33433eSHeiner Kallweit rtl_eri_set_bits(tp, 0xd4, 0x0010);
34161287723aSHeiner Kallweit
34171287723aSHeiner Kallweit rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87);
34181287723aSHeiner Kallweit
34193406079bSChunhao Lin rtl_disable_rxdvgate(tp);
34201287723aSHeiner Kallweit
34211287723aSHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
34221287723aSHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000);
34231287723aSHeiner Kallweit
34241287723aSHeiner Kallweit rtl8168_config_eee_mac(tp);
34251287723aSHeiner Kallweit
34261287723aSHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
34271287723aSHeiner Kallweit RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN);
34281287723aSHeiner Kallweit
34291287723aSHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN);
34301287723aSHeiner Kallweit
343154113dedSHeiner Kallweit rtl_eri_clear_bits(tp, 0x1b0, BIT(12));
34321287723aSHeiner Kallweit
34331287723aSHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
34341287723aSHeiner Kallweit
34351287723aSHeiner Kallweit rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff;
34361287723aSHeiner Kallweit if (rg_saw_cnt > 0) {
34371287723aSHeiner Kallweit u16 sw_cnt_1ms_ini;
34381287723aSHeiner Kallweit
34391287723aSHeiner Kallweit sw_cnt_1ms_ini = (16000000 / rg_saw_cnt) & 0x0fff;
34401287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini);
34411287723aSHeiner Kallweit }
34421287723aSHeiner Kallweit
34431287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070);
34441287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xea80, 0x0003);
34451287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x0000, 0x0009);
34461287723aSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f);
34471287723aSHeiner Kallweit
34481287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0001);
34491287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe63e, 0x0000);
34501287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc094, 0x0000);
34511287723aSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc09e, 0x0000);
34521287723aSHeiner Kallweit
3453229c1e0dSHeiner Kallweit /* firmware is for MAC only */
34541c5be5e9SHeiner Kallweit r8169_apply_firmware(tp);
34551287723aSHeiner Kallweit }
34561287723aSHeiner Kallweit
rtl_hw_start_8102e_1(struct rtl8169_private * tp)345725e992a4SHeiner Kallweit static void rtl_hw_start_8102e_1(struct rtl8169_private *tp)
345825e992a4SHeiner Kallweit {
345925e992a4SHeiner Kallweit static const struct ephy_info e_info_8102e_1[] = {
346025e992a4SHeiner Kallweit { 0x01, 0, 0x6e65 },
346125e992a4SHeiner Kallweit { 0x02, 0, 0x091f },
346225e992a4SHeiner Kallweit { 0x03, 0, 0xc2f9 },
346325e992a4SHeiner Kallweit { 0x06, 0, 0xafb5 },
346425e992a4SHeiner Kallweit { 0x07, 0, 0x0e00 },
346525e992a4SHeiner Kallweit { 0x19, 0, 0xec80 },
346625e992a4SHeiner Kallweit { 0x01, 0, 0x2e65 },
346725e992a4SHeiner Kallweit { 0x01, 0, 0x6e65 }
346825e992a4SHeiner Kallweit };
346925e992a4SHeiner Kallweit u8 cfg1;
347025e992a4SHeiner Kallweit
347125e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
347225e992a4SHeiner Kallweit
347325e992a4SHeiner Kallweit RTL_W8(tp, DBG_REG, FIX_NAK_1);
347425e992a4SHeiner Kallweit
347525e992a4SHeiner Kallweit RTL_W8(tp, Config1,
347625e992a4SHeiner Kallweit LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
347725e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
347825e992a4SHeiner Kallweit
347925e992a4SHeiner Kallweit cfg1 = RTL_R8(tp, Config1);
348025e992a4SHeiner Kallweit if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
348125e992a4SHeiner Kallweit RTL_W8(tp, Config1, cfg1 & ~LEDS0);
348225e992a4SHeiner Kallweit
348325e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8102e_1);
348425e992a4SHeiner Kallweit }
348525e992a4SHeiner Kallweit
rtl_hw_start_8102e_2(struct rtl8169_private * tp)348625e992a4SHeiner Kallweit static void rtl_hw_start_8102e_2(struct rtl8169_private *tp)
348725e992a4SHeiner Kallweit {
348825e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
348925e992a4SHeiner Kallweit
349025e992a4SHeiner Kallweit RTL_W8(tp, Config1, MEMMAP | IOMAP | VPD | PMEnable);
349125e992a4SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
349225e992a4SHeiner Kallweit }
349325e992a4SHeiner Kallweit
rtl_hw_start_8102e_3(struct rtl8169_private * tp)349425e992a4SHeiner Kallweit static void rtl_hw_start_8102e_3(struct rtl8169_private *tp)
349525e992a4SHeiner Kallweit {
349625e992a4SHeiner Kallweit rtl_hw_start_8102e_2(tp);
349725e992a4SHeiner Kallweit
349825e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x03, 0xc2f9);
349925e992a4SHeiner Kallweit }
350025e992a4SHeiner Kallweit
rtl_hw_start_8401(struct rtl8169_private * tp)3501cdafdc29SHeiner Kallweit static void rtl_hw_start_8401(struct rtl8169_private *tp)
3502cdafdc29SHeiner Kallweit {
3503cdafdc29SHeiner Kallweit static const struct ephy_info e_info_8401[] = {
3504cdafdc29SHeiner Kallweit { 0x01, 0xffff, 0x6fe5 },
3505cdafdc29SHeiner Kallweit { 0x03, 0xffff, 0x0599 },
3506cdafdc29SHeiner Kallweit { 0x06, 0xffff, 0xaf25 },
3507cdafdc29SHeiner Kallweit { 0x07, 0xffff, 0x8e68 },
3508cdafdc29SHeiner Kallweit };
3509cdafdc29SHeiner Kallweit
3510cdafdc29SHeiner Kallweit rtl_ephy_init(tp, e_info_8401);
3511cdafdc29SHeiner Kallweit RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
3512cdafdc29SHeiner Kallweit }
3513cdafdc29SHeiner Kallweit
rtl_hw_start_8105e_1(struct rtl8169_private * tp)351425e992a4SHeiner Kallweit static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
351525e992a4SHeiner Kallweit {
351625e992a4SHeiner Kallweit static const struct ephy_info e_info_8105e_1[] = {
351725e992a4SHeiner Kallweit { 0x07, 0, 0x4000 },
351825e992a4SHeiner Kallweit { 0x19, 0, 0x0200 },
351925e992a4SHeiner Kallweit { 0x19, 0, 0x0020 },
352025e992a4SHeiner Kallweit { 0x1e, 0, 0x2000 },
352125e992a4SHeiner Kallweit { 0x03, 0, 0x0001 },
352225e992a4SHeiner Kallweit { 0x19, 0, 0x0100 },
352325e992a4SHeiner Kallweit { 0x19, 0, 0x0004 },
352425e992a4SHeiner Kallweit { 0x0a, 0, 0x0020 }
352525e992a4SHeiner Kallweit };
352625e992a4SHeiner Kallweit
352725e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */
352825e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800);
352925e992a4SHeiner Kallweit
353025e992a4SHeiner Kallweit /* Disable Early Tally Counter */
353125e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) & ~0x010000);
353225e992a4SHeiner Kallweit
353325e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET);
353425e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN);
353525e992a4SHeiner Kallweit
353625e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8105e_1);
353725e992a4SHeiner Kallweit
353825e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
353925e992a4SHeiner Kallweit }
354025e992a4SHeiner Kallweit
rtl_hw_start_8105e_2(struct rtl8169_private * tp)354125e992a4SHeiner Kallweit static void rtl_hw_start_8105e_2(struct rtl8169_private *tp)
354225e992a4SHeiner Kallweit {
354325e992a4SHeiner Kallweit rtl_hw_start_8105e_1(tp);
354425e992a4SHeiner Kallweit rtl_ephy_write(tp, 0x1e, rtl_ephy_read(tp, 0x1e) | 0x8000);
354525e992a4SHeiner Kallweit }
354625e992a4SHeiner Kallweit
rtl_hw_start_8402(struct rtl8169_private * tp)354725e992a4SHeiner Kallweit static void rtl_hw_start_8402(struct rtl8169_private *tp)
354825e992a4SHeiner Kallweit {
354925e992a4SHeiner Kallweit static const struct ephy_info e_info_8402[] = {
355025e992a4SHeiner Kallweit { 0x19, 0xffff, 0xff64 },
355125e992a4SHeiner Kallweit { 0x1e, 0, 0x4000 }
355225e992a4SHeiner Kallweit };
355325e992a4SHeiner Kallweit
355425e992a4SHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
355525e992a4SHeiner Kallweit
355625e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */
355725e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800);
355825e992a4SHeiner Kallweit
355925e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
356025e992a4SHeiner Kallweit
356125e992a4SHeiner Kallweit rtl_ephy_init(tp, e_info_8402);
356225e992a4SHeiner Kallweit
356325e992a4SHeiner Kallweit rtl_set_fifo_size(tp, 0x00, 0x00, 0x02, 0x06);
356425e992a4SHeiner Kallweit rtl_reset_packet_filter(tp);
356525e992a4SHeiner Kallweit rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
356625e992a4SHeiner Kallweit rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000);
356754113dedSHeiner Kallweit rtl_w0w1_eri(tp, 0x0d4, 0x0e00, 0xff00);
356825e992a4SHeiner Kallweit
35696d7a631eSHeiner Kallweit /* disable EEE */
35706d7a631eSHeiner Kallweit rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000);
35716d7a631eSHeiner Kallweit
357225e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
357325e992a4SHeiner Kallweit }
357425e992a4SHeiner Kallweit
rtl_hw_start_8106(struct rtl8169_private * tp)357525e992a4SHeiner Kallweit static void rtl_hw_start_8106(struct rtl8169_private *tp)
357625e992a4SHeiner Kallweit {
357725e992a4SHeiner Kallweit /* Force LAN exit from ASPM if Rx/Tx are not idle */
357825e992a4SHeiner Kallweit RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800);
357925e992a4SHeiner Kallweit
358025e992a4SHeiner Kallweit RTL_W32(tp, MISC, (RTL_R32(tp, MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN);
358125e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET);
358225e992a4SHeiner Kallweit RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
358325e992a4SHeiner Kallweit
3584c07c8ffcSHeiner Kallweit /* L0 7us, L1 32us - needed to avoid issues with link-up detection */
3585c07c8ffcSHeiner Kallweit rtl_set_aspm_entry_latency(tp, 0x2f);
35869c401864SHayes Wang
35878d46f620SHeiner Kallweit rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000);
35888d46f620SHeiner Kallweit
35896d7a631eSHeiner Kallweit /* disable EEE */
35906d7a631eSHeiner Kallweit rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000);
35916d7a631eSHeiner Kallweit
359225e992a4SHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
359325e992a4SHeiner Kallweit }
359425e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_mac_ocp_e00e_cond)3595f1bce4adSHeiner Kallweit DECLARE_RTL_COND(rtl_mac_ocp_e00e_cond)
3596f1bce4adSHeiner Kallweit {
3597f1bce4adSHeiner Kallweit return r8168_mac_ocp_read(tp, 0xe00e) & BIT(13);
3598f1bce4adSHeiner Kallweit }
3599f1bce4adSHeiner Kallweit
rtl_hw_start_8125_common(struct rtl8169_private * tp)3600f1bce4adSHeiner Kallweit static void rtl_hw_start_8125_common(struct rtl8169_private *tp)
3601f1bce4adSHeiner Kallweit {
3602f1bce4adSHeiner Kallweit rtl_pcie_state_l2l3_disable(tp);
3603f1bce4adSHeiner Kallweit
3604f1bce4adSHeiner Kallweit RTL_W16(tp, 0x382, 0x221b);
3605f1bce4adSHeiner Kallweit RTL_W8(tp, 0x4500, 0);
3606f1bce4adSHeiner Kallweit RTL_W16(tp, 0x4800, 0);
3607f1bce4adSHeiner Kallweit
3608f1bce4adSHeiner Kallweit /* disable UPS */
3609f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd40a, 0x0010, 0x0000);
3610f1bce4adSHeiner Kallweit
3611f1bce4adSHeiner Kallweit RTL_W8(tp, Config1, RTL_R8(tp, Config1) & ~0x10);
3612f1bce4adSHeiner Kallweit
3613f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc140, 0xffff);
3614f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc142, 0xffff);
3615f1bce4adSHeiner Kallweit
3616f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e2, 0x0fff, 0x03a9);
3617f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd3e4, 0x00ff, 0x0000);
3618f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe860, 0x0000, 0x0080);
3619f1bce4adSHeiner Kallweit
3620f1bce4adSHeiner Kallweit /* disable new tx descriptor format */
3621f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
3622f1bce4adSHeiner Kallweit
36230439297bSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_63)
36240439297bSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
36250439297bSHeiner Kallweit else
3626f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
36270439297bSHeiner Kallweit
36280439297bSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_63)
36290439297bSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0000);
36300439297bSHeiner Kallweit else
3631f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0020);
36320439297bSHeiner Kallweit
3633f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xc0b4, 0x0000, 0x000c);
3634f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb6a, 0x00ff, 0x0033);
3635f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb50, 0x03e0, 0x0040);
3636f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
3637f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
36380439297bSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
3639f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403);
36400439297bSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0068);
3641f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f);
36420439297bSHeiner Kallweit
3643f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
3644f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb54, 0x0000, 0x0001);
3645f1bce4adSHeiner Kallweit udelay(1);
3646f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xeb54, 0x0001, 0x0000);
3647f1bce4adSHeiner Kallweit RTL_W16(tp, 0x1880, RTL_R16(tp, 0x1880) & ~0x0030);
3648f1bce4adSHeiner Kallweit
3649f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xe098, 0xc302);
3650f1bce4adSHeiner Kallweit
3651d6836ef0SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10);
3652f1bce4adSHeiner Kallweit
36530439297bSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_63)
36540439297bSHeiner Kallweit rtl8125b_config_eee_mac(tp);
36550439297bSHeiner Kallweit else
36564640338cSHeiner Kallweit rtl8125a_config_eee_mac(tp);
3657b3a42e3aSHeiner Kallweit
36583406079bSChunhao Lin rtl_disable_rxdvgate(tp);
3659f1bce4adSHeiner Kallweit }
3660f1bce4adSHeiner Kallweit
rtl_hw_start_8125a_2(struct rtl8169_private * tp)36614640338cSHeiner Kallweit static void rtl_hw_start_8125a_2(struct rtl8169_private *tp)
3662f1bce4adSHeiner Kallweit {
36634640338cSHeiner Kallweit static const struct ephy_info e_info_8125a_2[] = {
3664f1bce4adSHeiner Kallweit { 0x04, 0xffff, 0xd000 },
3665f1bce4adSHeiner Kallweit { 0x0a, 0xffff, 0x8653 },
3666f1bce4adSHeiner Kallweit { 0x23, 0xffff, 0xab66 },
3667f1bce4adSHeiner Kallweit { 0x20, 0xffff, 0x9455 },
3668f1bce4adSHeiner Kallweit { 0x21, 0xffff, 0x99ff },
3669f1bce4adSHeiner Kallweit { 0x29, 0xffff, 0xfe04 },
3670f1bce4adSHeiner Kallweit
3671f1bce4adSHeiner Kallweit { 0x44, 0xffff, 0xd000 },
3672f1bce4adSHeiner Kallweit { 0x4a, 0xffff, 0x8653 },
3673f1bce4adSHeiner Kallweit { 0x63, 0xffff, 0xab66 },
3674f1bce4adSHeiner Kallweit { 0x60, 0xffff, 0x9455 },
3675f1bce4adSHeiner Kallweit { 0x61, 0xffff, 0x99ff },
3676f1bce4adSHeiner Kallweit { 0x69, 0xffff, 0xfe04 },
3677f1bce4adSHeiner Kallweit };
3678f1bce4adSHeiner Kallweit
3679f1bce4adSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
36804640338cSHeiner Kallweit rtl_ephy_init(tp, e_info_8125a_2);
3681f1bce4adSHeiner Kallweit rtl_hw_start_8125_common(tp);
3682f1bce4adSHeiner Kallweit }
3683f1bce4adSHeiner Kallweit
rtl_hw_start_8125b(struct rtl8169_private * tp)36840439297bSHeiner Kallweit static void rtl_hw_start_8125b(struct rtl8169_private *tp)
36850439297bSHeiner Kallweit {
36860439297bSHeiner Kallweit static const struct ephy_info e_info_8125b[] = {
36870439297bSHeiner Kallweit { 0x0b, 0xffff, 0xa908 },
36880439297bSHeiner Kallweit { 0x1e, 0xffff, 0x20eb },
36890439297bSHeiner Kallweit { 0x4b, 0xffff, 0xa908 },
36900439297bSHeiner Kallweit { 0x5e, 0xffff, 0x20eb },
36910439297bSHeiner Kallweit { 0x22, 0x0030, 0x0020 },
36920439297bSHeiner Kallweit { 0x62, 0x0030, 0x0020 },
36930439297bSHeiner Kallweit };
36940439297bSHeiner Kallweit
36950439297bSHeiner Kallweit rtl_set_def_aspm_entry_latency(tp);
36960439297bSHeiner Kallweit rtl_ephy_init(tp, e_info_8125b);
36970439297bSHeiner Kallweit rtl_hw_start_8125_common(tp);
36980439297bSHeiner Kallweit }
36990439297bSHeiner Kallweit
rtl_hw_config(struct rtl8169_private * tp)370025e992a4SHeiner Kallweit static void rtl_hw_config(struct rtl8169_private *tp)
370125e992a4SHeiner Kallweit {
370225e992a4SHeiner Kallweit static const rtl_generic_fct hw_configs[] = {
370325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_07] = rtl_hw_start_8102e_1,
370425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_08] = rtl_hw_start_8102e_3,
370525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_09] = rtl_hw_start_8102e_2,
370625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_10] = NULL,
370794b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b,
3708cdafdc29SHeiner Kallweit [RTL_GIGA_MAC_VER_14] = rtl_hw_start_8401,
370994b5ff74SHeiner Kallweit [RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b,
371025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1,
371125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_19] = rtl_hw_start_8168c_1,
371225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_20] = rtl_hw_start_8168c_2,
371396ef6928SHeiner Kallweit [RTL_GIGA_MAC_VER_21] = rtl_hw_start_8168c_2,
371425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_22] = rtl_hw_start_8168c_4,
371525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_23] = rtl_hw_start_8168cp_2,
371625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_24] = rtl_hw_start_8168cp_3,
371725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_25] = rtl_hw_start_8168d,
371825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_26] = rtl_hw_start_8168d,
371925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_28] = rtl_hw_start_8168d_4,
372025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_29] = rtl_hw_start_8105e_1,
372125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_30] = rtl_hw_start_8105e_2,
37220a413e6bSHeiner Kallweit [RTL_GIGA_MAC_VER_31] = rtl_hw_start_8168d,
372325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_32] = rtl_hw_start_8168e_1,
372425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_33] = rtl_hw_start_8168e_1,
372525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_34] = rtl_hw_start_8168e_2,
372625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_35] = rtl_hw_start_8168f_1,
372725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_36] = rtl_hw_start_8168f_1,
372825e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_37] = rtl_hw_start_8402,
372925e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_38] = rtl_hw_start_8411,
373025e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_39] = rtl_hw_start_8106,
373125e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_40] = rtl_hw_start_8168g_1,
373225e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_42] = rtl_hw_start_8168g_2,
373325e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_43] = rtl_hw_start_8168g_2,
373425e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_44] = rtl_hw_start_8411_2,
373525e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_46] = rtl_hw_start_8168h_1,
373625e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_48] = rtl_hw_start_8168h_1,
373725e992a4SHeiner Kallweit [RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3,
37381287723aSHeiner Kallweit [RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117,
3739e6d6ca6eSKai-Heng Feng [RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
37404640338cSHeiner Kallweit [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
37410439297bSHeiner Kallweit [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
374225e992a4SHeiner Kallweit };
374325e992a4SHeiner Kallweit
374425e992a4SHeiner Kallweit if (hw_configs[tp->mac_version])
374525e992a4SHeiner Kallweit hw_configs[tp->mac_version](tp);
374625e992a4SHeiner Kallweit }
374725e992a4SHeiner Kallweit
rtl_hw_start_8125(struct rtl8169_private * tp)3748f1bce4adSHeiner Kallweit static void rtl_hw_start_8125(struct rtl8169_private *tp)
3749f1bce4adSHeiner Kallweit {
3750f1bce4adSHeiner Kallweit int i;
3751f1bce4adSHeiner Kallweit
3752f1bce4adSHeiner Kallweit /* disable interrupt coalescing */
3753f1bce4adSHeiner Kallweit for (i = 0xa00; i < 0xb00; i += 4)
3754f1bce4adSHeiner Kallweit RTL_W32(tp, i, 0);
3755f1bce4adSHeiner Kallweit
3756f1bce4adSHeiner Kallweit rtl_hw_config(tp);
3757f1bce4adSHeiner Kallweit }
3758f1bce4adSHeiner Kallweit
rtl_hw_start_8168(struct rtl8169_private * tp)375925e992a4SHeiner Kallweit static void rtl_hw_start_8168(struct rtl8169_private *tp)
376025e992a4SHeiner Kallweit {
3761272b2265SHeiner Kallweit if (rtl_is_8168evl_up(tp))
3762272b2265SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, EarlySize);
3763272b2265SHeiner Kallweit else
376425e992a4SHeiner Kallweit RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
376525e992a4SHeiner Kallweit
376625e992a4SHeiner Kallweit rtl_hw_config(tp);
3767bcf2b868SHeiner Kallweit
3768bcf2b868SHeiner Kallweit /* disable interrupt coalescing */
3769bcf2b868SHeiner Kallweit RTL_W16(tp, IntrMitigate, 0x0000);
377025e992a4SHeiner Kallweit }
377125e992a4SHeiner Kallweit
rtl_hw_start_8169(struct rtl8169_private * tp)37726c19156eSHeiner Kallweit static void rtl_hw_start_8169(struct rtl8169_private *tp)
37736c19156eSHeiner Kallweit {
37746c19156eSHeiner Kallweit RTL_W8(tp, EarlyTxThres, NoEarlyTx);
37756c19156eSHeiner Kallweit
37766c19156eSHeiner Kallweit tp->cp_cmd |= PCIMulRW;
37776c19156eSHeiner Kallweit
37786c19156eSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_02 ||
377909e65335SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_03)
378009e65335SHeiner Kallweit tp->cp_cmd |= EnAnaPLL;
37816c19156eSHeiner Kallweit
37826c19156eSHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd);
37836c19156eSHeiner Kallweit
3784ef891284SHeiner Kallweit rtl8169_set_magic_reg(tp);
37856c19156eSHeiner Kallweit
3786bcf2b868SHeiner Kallweit /* disable interrupt coalescing */
3787bcf2b868SHeiner Kallweit RTL_W16(tp, IntrMitigate, 0x0000);
37886c19156eSHeiner Kallweit }
37896c19156eSHeiner Kallweit
rtl_hw_start(struct rtl8169_private * tp)37906c19156eSHeiner Kallweit static void rtl_hw_start(struct rtl8169_private *tp)
37916c19156eSHeiner Kallweit {
37926c19156eSHeiner Kallweit rtl_unlock_config_regs(tp);
37935fc3f6c9SHeiner Kallweit /* disable aspm and clock request before ephy access */
37945fc3f6c9SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, false);
37956c19156eSHeiner Kallweit RTL_W16(tp, CPlusCmd, tp->cp_cmd);
37966c19156eSHeiner Kallweit
37976c19156eSHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
37986c19156eSHeiner Kallweit rtl_hw_start_8169(tp);
3799f1bce4adSHeiner Kallweit else if (rtl_is_8125(tp))
3800f1bce4adSHeiner Kallweit rtl_hw_start_8125(tp);
38016c19156eSHeiner Kallweit else
38026c19156eSHeiner Kallweit rtl_hw_start_8168(tp);
38036c19156eSHeiner Kallweit
38044b33433eSHeiner Kallweit rtl_enable_exit_l1(tp);
38055fc3f6c9SHeiner Kallweit rtl_hw_aspm_clkreq_enable(tp, true);
38066c19156eSHeiner Kallweit rtl_set_rx_max_size(tp);
38076c19156eSHeiner Kallweit rtl_set_rx_tx_desc_registers(tp);
38086c19156eSHeiner Kallweit rtl_lock_config_regs(tp);
38096c19156eSHeiner Kallweit
38109db0ac57SHeiner Kallweit rtl_jumbo_config(tp);
38114ebcb113SHeiner Kallweit
38126c19156eSHeiner Kallweit /* Initially a 10 us delay. Turned it into a PCI commit. - FR */
3813711463f8SHeiner Kallweit rtl_pci_commit(tp);
3814711463f8SHeiner Kallweit
38156c19156eSHeiner Kallweit RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
38166c19156eSHeiner Kallweit rtl_init_rxcfg(tp);
38176c19156eSHeiner Kallweit rtl_set_tx_config_registers(tp);
381810478283SHeiner Kallweit rtl_set_rx_config_features(tp, tp->dev->features);
38196c19156eSHeiner Kallweit rtl_set_rx_mode(tp->dev);
38206c19156eSHeiner Kallweit rtl_irq_enable(tp);
38216c19156eSHeiner Kallweit }
38226c19156eSHeiner Kallweit
rtl8169_change_mtu(struct net_device * dev,int new_mtu)382325e992a4SHeiner Kallweit static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
382425e992a4SHeiner Kallweit {
382525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
382625e992a4SHeiner Kallweit
382725e992a4SHeiner Kallweit dev->mtu = new_mtu;
382825e992a4SHeiner Kallweit netdev_update_features(dev);
38299db0ac57SHeiner Kallweit rtl_jumbo_config(tp);
383025e992a4SHeiner Kallweit
38310439297bSHeiner Kallweit switch (tp->mac_version) {
38320439297bSHeiner Kallweit case RTL_GIGA_MAC_VER_61:
38330439297bSHeiner Kallweit case RTL_GIGA_MAC_VER_63:
38340439297bSHeiner Kallweit rtl8125_set_eee_txidle_timer(tp);
38350439297bSHeiner Kallweit break;
38360439297bSHeiner Kallweit default:
38370439297bSHeiner Kallweit break;
38380439297bSHeiner Kallweit }
38390439297bSHeiner Kallweit
384025e992a4SHeiner Kallweit return 0;
384125e992a4SHeiner Kallweit }
384225e992a4SHeiner Kallweit
rtl8169_mark_to_asic(struct RxDesc * desc)3843e2e5fb8dSHeiner Kallweit static void rtl8169_mark_to_asic(struct RxDesc *desc)
384425e992a4SHeiner Kallweit {
384525e992a4SHeiner Kallweit u32 eor = le32_to_cpu(desc->opts1) & RingEnd;
384625e992a4SHeiner Kallweit
3847047521d7SHeiner Kallweit desc->opts2 = 0;
384825e992a4SHeiner Kallweit /* Force memory writes to complete before releasing descriptor */
384925e992a4SHeiner Kallweit dma_wmb();
3850e2e5fb8dSHeiner Kallweit WRITE_ONCE(desc->opts1, cpu_to_le32(DescOwn | eor | R8169_RX_BUF_SIZE));
385125e992a4SHeiner Kallweit }
385225e992a4SHeiner Kallweit
rtl8169_alloc_rx_data(struct rtl8169_private * tp,struct RxDesc * desc)385332879f00SHeiner Kallweit static struct page *rtl8169_alloc_rx_data(struct rtl8169_private *tp,
385425e992a4SHeiner Kallweit struct RxDesc *desc)
385525e992a4SHeiner Kallweit {
385625e992a4SHeiner Kallweit struct device *d = tp_to_dev(tp);
385725e992a4SHeiner Kallweit int node = dev_to_node(d);
385832879f00SHeiner Kallweit dma_addr_t mapping;
385932879f00SHeiner Kallweit struct page *data;
386025e992a4SHeiner Kallweit
386132879f00SHeiner Kallweit data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE));
386225e992a4SHeiner Kallweit if (!data)
386325e992a4SHeiner Kallweit return NULL;
386425e992a4SHeiner Kallweit
386532879f00SHeiner Kallweit mapping = dma_map_page(d, data, 0, R8169_RX_BUF_SIZE, DMA_FROM_DEVICE);
386625e992a4SHeiner Kallweit if (unlikely(dma_mapping_error(d, mapping))) {
386793882c6fSHeiner Kallweit netdev_err(tp->dev, "Failed to map RX DMA!\n");
386832879f00SHeiner Kallweit __free_pages(data, get_order(R8169_RX_BUF_SIZE));
386932879f00SHeiner Kallweit return NULL;
387025e992a4SHeiner Kallweit }
387125e992a4SHeiner Kallweit
387225e992a4SHeiner Kallweit desc->addr = cpu_to_le64(mapping);
387325e992a4SHeiner Kallweit rtl8169_mark_to_asic(desc);
387425e992a4SHeiner Kallweit
387532879f00SHeiner Kallweit return data;
387625e992a4SHeiner Kallweit }
387725e992a4SHeiner Kallweit
rtl8169_rx_clear(struct rtl8169_private * tp)387825e992a4SHeiner Kallweit static void rtl8169_rx_clear(struct rtl8169_private *tp)
387925e992a4SHeiner Kallweit {
3880ed22a8ffSHeiner Kallweit int i;
388125e992a4SHeiner Kallweit
3882eb2e7f09SHeiner Kallweit for (i = 0; i < NUM_RX_DESC && tp->Rx_databuff[i]; i++) {
3883eb2e7f09SHeiner Kallweit dma_unmap_page(tp_to_dev(tp),
3884eb2e7f09SHeiner Kallweit le64_to_cpu(tp->RxDescArray[i].addr),
3885eb2e7f09SHeiner Kallweit R8169_RX_BUF_SIZE, DMA_FROM_DEVICE);
3886eb2e7f09SHeiner Kallweit __free_pages(tp->Rx_databuff[i], get_order(R8169_RX_BUF_SIZE));
3887eb2e7f09SHeiner Kallweit tp->Rx_databuff[i] = NULL;
38889d3679feSHeiner Kallweit tp->RxDescArray[i].addr = 0;
38899d3679feSHeiner Kallweit tp->RxDescArray[i].opts1 = 0;
389025e992a4SHeiner Kallweit }
389125e992a4SHeiner Kallweit }
389225e992a4SHeiner Kallweit
rtl8169_rx_fill(struct rtl8169_private * tp)389325e992a4SHeiner Kallweit static int rtl8169_rx_fill(struct rtl8169_private *tp)
389425e992a4SHeiner Kallweit {
3895ed22a8ffSHeiner Kallweit int i;
389625e992a4SHeiner Kallweit
389725e992a4SHeiner Kallweit for (i = 0; i < NUM_RX_DESC; i++) {
389832879f00SHeiner Kallweit struct page *data;
389925e992a4SHeiner Kallweit
390025e992a4SHeiner Kallweit data = rtl8169_alloc_rx_data(tp, tp->RxDescArray + i);
390125e992a4SHeiner Kallweit if (!data) {
3902e4b5c7a5SHeiner Kallweit rtl8169_rx_clear(tp);
3903e4b5c7a5SHeiner Kallweit return -ENOMEM;
390425e992a4SHeiner Kallweit }
390525e992a4SHeiner Kallweit tp->Rx_databuff[i] = data;
390625e992a4SHeiner Kallweit }
390725e992a4SHeiner Kallweit
39082ac1fa43SHeiner Kallweit /* mark as last descriptor in the ring */
39092ac1fa43SHeiner Kallweit tp->RxDescArray[NUM_RX_DESC - 1].opts1 |= cpu_to_le32(RingEnd);
391025e992a4SHeiner Kallweit
3911e4b5c7a5SHeiner Kallweit return 0;
391225e992a4SHeiner Kallweit }
391325e992a4SHeiner Kallweit
rtl8169_init_ring(struct rtl8169_private * tp)391425e992a4SHeiner Kallweit static int rtl8169_init_ring(struct rtl8169_private *tp)
391525e992a4SHeiner Kallweit {
391625e992a4SHeiner Kallweit rtl8169_init_ring_indexes(tp);
391725e992a4SHeiner Kallweit
391825e992a4SHeiner Kallweit memset(tp->tx_skb, 0, sizeof(tp->tx_skb));
391925e992a4SHeiner Kallweit memset(tp->Rx_databuff, 0, sizeof(tp->Rx_databuff));
392025e992a4SHeiner Kallweit
392125e992a4SHeiner Kallweit return rtl8169_rx_fill(tp);
392225e992a4SHeiner Kallweit }
392325e992a4SHeiner Kallweit
rtl8169_unmap_tx_skb(struct rtl8169_private * tp,unsigned int entry)392422d352c5SHeiner Kallweit static void rtl8169_unmap_tx_skb(struct rtl8169_private *tp, unsigned int entry)
392525e992a4SHeiner Kallweit {
392622d352c5SHeiner Kallweit struct ring_info *tx_skb = tp->tx_skb + entry;
392722d352c5SHeiner Kallweit struct TxDesc *desc = tp->TxDescArray + entry;
392825e992a4SHeiner Kallweit
392922d352c5SHeiner Kallweit dma_unmap_single(tp_to_dev(tp), le64_to_cpu(desc->addr), tx_skb->len,
393022d352c5SHeiner Kallweit DMA_TO_DEVICE);
39316a41f2b2SHeiner Kallweit memset(desc, 0, sizeof(*desc));
39326a41f2b2SHeiner Kallweit memset(tx_skb, 0, sizeof(*tx_skb));
393325e992a4SHeiner Kallweit }
393425e992a4SHeiner Kallweit
rtl8169_tx_clear_range(struct rtl8169_private * tp,u32 start,unsigned int n)393525e992a4SHeiner Kallweit static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
393625e992a4SHeiner Kallweit unsigned int n)
393725e992a4SHeiner Kallweit {
393825e992a4SHeiner Kallweit unsigned int i;
393925e992a4SHeiner Kallweit
394025e992a4SHeiner Kallweit for (i = 0; i < n; i++) {
394125e992a4SHeiner Kallweit unsigned int entry = (start + i) % NUM_TX_DESC;
394225e992a4SHeiner Kallweit struct ring_info *tx_skb = tp->tx_skb + entry;
394325e992a4SHeiner Kallweit unsigned int len = tx_skb->len;
394425e992a4SHeiner Kallweit
394525e992a4SHeiner Kallweit if (len) {
394625e992a4SHeiner Kallweit struct sk_buff *skb = tx_skb->skb;
394725e992a4SHeiner Kallweit
394822d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry);
39496a41f2b2SHeiner Kallweit if (skb)
395025e992a4SHeiner Kallweit dev_consume_skb_any(skb);
395125e992a4SHeiner Kallweit }
395225e992a4SHeiner Kallweit }
395325e992a4SHeiner Kallweit }
395425e992a4SHeiner Kallweit
rtl8169_tx_clear(struct rtl8169_private * tp)395525e992a4SHeiner Kallweit static void rtl8169_tx_clear(struct rtl8169_private *tp)
395625e992a4SHeiner Kallweit {
395725e992a4SHeiner Kallweit rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
395825e992a4SHeiner Kallweit netdev_reset_queue(tp->dev);
395925e992a4SHeiner Kallweit }
396025e992a4SHeiner Kallweit
rtl8169_cleanup(struct rtl8169_private * tp)3961bb41c13cSChunhao Lin static void rtl8169_cleanup(struct rtl8169_private *tp)
3962bac75d85SHeiner Kallweit {
39630c28a63aSHeiner Kallweit napi_disable(&tp->napi);
39640c28a63aSHeiner Kallweit
3965bac75d85SHeiner Kallweit /* Give a racing hard_start_xmit a few cycles to complete. */
39667190aeecSHeiner Kallweit synchronize_net();
3967bac75d85SHeiner Kallweit
3968bac75d85SHeiner Kallweit /* Disable interrupts */
3969bac75d85SHeiner Kallweit rtl8169_irq_mask_and_ack(tp);
3970bac75d85SHeiner Kallweit
3971bac75d85SHeiner Kallweit rtl_rx_close(tp);
3972bac75d85SHeiner Kallweit
3973bac75d85SHeiner Kallweit switch (tp->mac_version) {
3974bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_28:
3975bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_31:
3976bac75d85SHeiner Kallweit rtl_loop_wait_low(tp, &rtl_npq_cond, 20, 2000);
3977bac75d85SHeiner Kallweit break;
3978bac75d85SHeiner Kallweit case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
3979bac75d85SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
3980bac75d85SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
3981bac75d85SHeiner Kallweit break;
39820439297bSHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
3983bac75d85SHeiner Kallweit rtl_enable_rxdvgate(tp);
3984bac75d85SHeiner Kallweit fsleep(2000);
3985bac75d85SHeiner Kallweit break;
3986bac75d85SHeiner Kallweit default:
3987bac75d85SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
3988bac75d85SHeiner Kallweit fsleep(100);
3989bac75d85SHeiner Kallweit break;
3990bac75d85SHeiner Kallweit }
3991bac75d85SHeiner Kallweit
3992bac75d85SHeiner Kallweit rtl_hw_reset(tp);
3993bb41c13cSChunhao Lin
3994bac75d85SHeiner Kallweit rtl8169_tx_clear(tp);
3995bac75d85SHeiner Kallweit rtl8169_init_ring_indexes(tp);
3996bac75d85SHeiner Kallweit }
3997bac75d85SHeiner Kallweit
rtl_reset_work(struct rtl8169_private * tp)399825e992a4SHeiner Kallweit static void rtl_reset_work(struct rtl8169_private *tp)
399925e992a4SHeiner Kallweit {
400025e992a4SHeiner Kallweit int i;
400125e992a4SHeiner Kallweit
4002476c4f5dSHeiner Kallweit netif_stop_queue(tp->dev);
400325e992a4SHeiner Kallweit
4004bb41c13cSChunhao Lin rtl8169_cleanup(tp);
400525e992a4SHeiner Kallweit
400625e992a4SHeiner Kallweit for (i = 0; i < NUM_RX_DESC; i++)
400725e992a4SHeiner Kallweit rtl8169_mark_to_asic(tp->RxDescArray + i);
400825e992a4SHeiner Kallweit
400925e992a4SHeiner Kallweit napi_enable(&tp->napi);
401025e992a4SHeiner Kallweit rtl_hw_start(tp);
401125e992a4SHeiner Kallweit }
401225e992a4SHeiner Kallweit
rtl8169_tx_timeout(struct net_device * dev,unsigned int txqueue)40130290bd29SMichael S. Tsirkin static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue)
401425e992a4SHeiner Kallweit {
401525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
401625e992a4SHeiner Kallweit
401780c0576eSHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_TX_TIMEOUT);
401825e992a4SHeiner Kallweit }
401925e992a4SHeiner Kallweit
rtl8169_tx_map(struct rtl8169_private * tp,const u32 * opts,u32 len,void * addr,unsigned int entry,bool desc_own)4020b8447abcSHeiner Kallweit static int rtl8169_tx_map(struct rtl8169_private *tp, const u32 *opts, u32 len,
4021b8447abcSHeiner Kallweit void *addr, unsigned int entry, bool desc_own)
402225e992a4SHeiner Kallweit {
4023b8447abcSHeiner Kallweit struct TxDesc *txd = tp->TxDescArray + entry;
4024b8447abcSHeiner Kallweit struct device *d = tp_to_dev(tp);
4025b8447abcSHeiner Kallweit dma_addr_t mapping;
4026b8447abcSHeiner Kallweit u32 opts1;
4027b8447abcSHeiner Kallweit int ret;
402825e992a4SHeiner Kallweit
4029b8447abcSHeiner Kallweit mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE);
4030b8447abcSHeiner Kallweit ret = dma_mapping_error(d, mapping);
4031b8447abcSHeiner Kallweit if (unlikely(ret)) {
4032b8447abcSHeiner Kallweit if (net_ratelimit())
403393882c6fSHeiner Kallweit netdev_err(tp->dev, "Failed to map TX data!\n");
4034b8447abcSHeiner Kallweit return ret;
4035b8447abcSHeiner Kallweit }
4036b8447abcSHeiner Kallweit
4037b8447abcSHeiner Kallweit txd->addr = cpu_to_le64(mapping);
4038b8447abcSHeiner Kallweit txd->opts2 = cpu_to_le32(opts[1]);
4039b8447abcSHeiner Kallweit
4040b8447abcSHeiner Kallweit opts1 = opts[0] | len;
404125e992a4SHeiner Kallweit if (entry == NUM_TX_DESC - 1)
4042b8447abcSHeiner Kallweit opts1 |= RingEnd;
4043b8447abcSHeiner Kallweit if (desc_own)
4044b8447abcSHeiner Kallweit opts1 |= DescOwn;
4045b8447abcSHeiner Kallweit txd->opts1 = cpu_to_le32(opts1);
404625e992a4SHeiner Kallweit
4047b8447abcSHeiner Kallweit tp->tx_skb[entry].len = len;
4048b8447abcSHeiner Kallweit
4049b8447abcSHeiner Kallweit return 0;
405025e992a4SHeiner Kallweit }
405125e992a4SHeiner Kallweit
rtl8169_xmit_frags(struct rtl8169_private * tp,struct sk_buff * skb,const u32 * opts,unsigned int entry)405225e992a4SHeiner Kallweit static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
4053b8447abcSHeiner Kallweit const u32 *opts, unsigned int entry)
405425e992a4SHeiner Kallweit {
405525e992a4SHeiner Kallweit struct skb_shared_info *info = skb_shinfo(skb);
4056b8447abcSHeiner Kallweit unsigned int cur_frag;
405725e992a4SHeiner Kallweit
405825e992a4SHeiner Kallweit for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
405925e992a4SHeiner Kallweit const skb_frag_t *frag = info->frags + cur_frag;
4060b8447abcSHeiner Kallweit void *addr = skb_frag_address(frag);
4061b8447abcSHeiner Kallweit u32 len = skb_frag_size(frag);
406225e992a4SHeiner Kallweit
406325e992a4SHeiner Kallweit entry = (entry + 1) % NUM_TX_DESC;
406425e992a4SHeiner Kallweit
4065b8447abcSHeiner Kallweit if (unlikely(rtl8169_tx_map(tp, opts, len, addr, entry, true)))
406625e992a4SHeiner Kallweit goto err_out;
406725e992a4SHeiner Kallweit }
406825e992a4SHeiner Kallweit
40699020845fSHeiner Kallweit return 0;
407025e992a4SHeiner Kallweit
407125e992a4SHeiner Kallweit err_out:
407225e992a4SHeiner Kallweit rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag);
407325e992a4SHeiner Kallweit return -EIO;
407425e992a4SHeiner Kallweit }
407525e992a4SHeiner Kallweit
rtl_skb_is_udp(struct sk_buff * skb)40768d520b4dSHeiner Kallweit static bool rtl_skb_is_udp(struct sk_buff *skb)
407725e992a4SHeiner Kallweit {
40788d520b4dSHeiner Kallweit int no = skb_network_offset(skb);
40798d520b4dSHeiner Kallweit struct ipv6hdr *i6h, _i6h;
40808d520b4dSHeiner Kallweit struct iphdr *ih, _ih;
40818d520b4dSHeiner Kallweit
40828d520b4dSHeiner Kallweit switch (vlan_get_protocol(skb)) {
40838d520b4dSHeiner Kallweit case htons(ETH_P_IP):
40848d520b4dSHeiner Kallweit ih = skb_header_pointer(skb, no, sizeof(_ih), &_ih);
40858d520b4dSHeiner Kallweit return ih && ih->protocol == IPPROTO_UDP;
40868d520b4dSHeiner Kallweit case htons(ETH_P_IPV6):
40878d520b4dSHeiner Kallweit i6h = skb_header_pointer(skb, no, sizeof(_i6h), &_i6h);
40888d520b4dSHeiner Kallweit return i6h && i6h->nexthdr == IPPROTO_UDP;
40898d520b4dSHeiner Kallweit default:
40908d520b4dSHeiner Kallweit return false;
40918d520b4dSHeiner Kallweit }
40928d520b4dSHeiner Kallweit }
40938d520b4dSHeiner Kallweit
40948d520b4dSHeiner Kallweit #define RTL_MIN_PATCH_LEN 47
40958d520b4dSHeiner Kallweit
40968d520b4dSHeiner Kallweit /* see rtl8125_get_patch_pad_len() in r8125 vendor driver */
rtl8125_quirk_udp_padto(struct rtl8169_private * tp,struct sk_buff * skb)40978d520b4dSHeiner Kallweit static unsigned int rtl8125_quirk_udp_padto(struct rtl8169_private *tp,
40988d520b4dSHeiner Kallweit struct sk_buff *skb)
40998d520b4dSHeiner Kallweit {
41008d520b4dSHeiner Kallweit unsigned int padto = 0, len = skb->len;
41018d520b4dSHeiner Kallweit
41028d520b4dSHeiner Kallweit if (rtl_is_8125(tp) && len < 128 + RTL_MIN_PATCH_LEN &&
41038d520b4dSHeiner Kallweit rtl_skb_is_udp(skb) && skb_transport_header_was_set(skb)) {
41048d520b4dSHeiner Kallweit unsigned int trans_data_len = skb_tail_pointer(skb) -
41058d520b4dSHeiner Kallweit skb_transport_header(skb);
41068d520b4dSHeiner Kallweit
41078d520b4dSHeiner Kallweit if (trans_data_len >= offsetof(struct udphdr, len) &&
41088d520b4dSHeiner Kallweit trans_data_len < RTL_MIN_PATCH_LEN) {
41098d520b4dSHeiner Kallweit u16 dest = ntohs(udp_hdr(skb)->dest);
41108d520b4dSHeiner Kallweit
41118d520b4dSHeiner Kallweit /* dest is a standard PTP port */
41128d520b4dSHeiner Kallweit if (dest == 319 || dest == 320)
41138d520b4dSHeiner Kallweit padto = len + RTL_MIN_PATCH_LEN - trans_data_len;
41148d520b4dSHeiner Kallweit }
41158d520b4dSHeiner Kallweit
41168d520b4dSHeiner Kallweit if (trans_data_len < sizeof(struct udphdr))
41178d520b4dSHeiner Kallweit padto = max_t(unsigned int, padto,
41188d520b4dSHeiner Kallweit len + sizeof(struct udphdr) - trans_data_len);
41198d520b4dSHeiner Kallweit }
41208d520b4dSHeiner Kallweit
41218d520b4dSHeiner Kallweit return padto;
41228d520b4dSHeiner Kallweit }
41238d520b4dSHeiner Kallweit
rtl_quirk_packet_padto(struct rtl8169_private * tp,struct sk_buff * skb)41248d520b4dSHeiner Kallweit static unsigned int rtl_quirk_packet_padto(struct rtl8169_private *tp,
41258d520b4dSHeiner Kallweit struct sk_buff *skb)
41268d520b4dSHeiner Kallweit {
41278d520b4dSHeiner Kallweit unsigned int padto;
41288d520b4dSHeiner Kallweit
41298d520b4dSHeiner Kallweit padto = rtl8125_quirk_udp_padto(tp, skb);
41308d520b4dSHeiner Kallweit
41312aaf09a0SHeiner Kallweit switch (tp->mac_version) {
41322aaf09a0SHeiner Kallweit case RTL_GIGA_MAC_VER_34:
41332aaf09a0SHeiner Kallweit case RTL_GIGA_MAC_VER_61:
41342aaf09a0SHeiner Kallweit case RTL_GIGA_MAC_VER_63:
41358d520b4dSHeiner Kallweit padto = max_t(unsigned int, padto, ETH_ZLEN);
4136ffb35c67SGustavo A. R. Silva break;
41372aaf09a0SHeiner Kallweit default:
41388d520b4dSHeiner Kallweit break;
41392aaf09a0SHeiner Kallweit }
41408d520b4dSHeiner Kallweit
41418d520b4dSHeiner Kallweit return padto;
414225e992a4SHeiner Kallweit }
414325e992a4SHeiner Kallweit
rtl8169_tso_csum_v1(struct sk_buff * skb,u32 * opts)414425e992a4SHeiner Kallweit static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts)
414525e992a4SHeiner Kallweit {
414625e992a4SHeiner Kallweit u32 mss = skb_shinfo(skb)->gso_size;
414725e992a4SHeiner Kallweit
414825e992a4SHeiner Kallweit if (mss) {
414925e992a4SHeiner Kallweit opts[0] |= TD_LSO;
41504abc3c04SHeiner Kallweit opts[0] |= mss << TD0_MSS_SHIFT;
415125e992a4SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
415225e992a4SHeiner Kallweit const struct iphdr *ip = ip_hdr(skb);
415325e992a4SHeiner Kallweit
415425e992a4SHeiner Kallweit if (ip->protocol == IPPROTO_TCP)
415525e992a4SHeiner Kallweit opts[0] |= TD0_IP_CS | TD0_TCP_CS;
415625e992a4SHeiner Kallweit else if (ip->protocol == IPPROTO_UDP)
415725e992a4SHeiner Kallweit opts[0] |= TD0_IP_CS | TD0_UDP_CS;
415825e992a4SHeiner Kallweit else
415925e992a4SHeiner Kallweit WARN_ON_ONCE(1);
416025e992a4SHeiner Kallweit }
416125e992a4SHeiner Kallweit }
416225e992a4SHeiner Kallweit
rtl8169_tso_csum_v2(struct rtl8169_private * tp,struct sk_buff * skb,u32 * opts)416325e992a4SHeiner Kallweit static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
416425e992a4SHeiner Kallweit struct sk_buff *skb, u32 *opts)
416525e992a4SHeiner Kallweit {
41660623b98bSHeiner Kallweit struct skb_shared_info *shinfo = skb_shinfo(skb);
41670623b98bSHeiner Kallweit u32 mss = shinfo->gso_size;
416825e992a4SHeiner Kallweit
416925e992a4SHeiner Kallweit if (mss) {
41700623b98bSHeiner Kallweit if (shinfo->gso_type & SKB_GSO_TCPV4) {
417125e992a4SHeiner Kallweit opts[0] |= TD1_GTSENV4;
41720623b98bSHeiner Kallweit } else if (shinfo->gso_type & SKB_GSO_TCPV6) {
41738b19c68cSHeiner Kallweit if (skb_cow_head(skb, 0))
417425e992a4SHeiner Kallweit return false;
417525e992a4SHeiner Kallweit
41768b19c68cSHeiner Kallweit tcp_v6_gso_csum_prep(skb);
417725e992a4SHeiner Kallweit opts[0] |= TD1_GTSENV6;
41780623b98bSHeiner Kallweit } else {
417925e992a4SHeiner Kallweit WARN_ON_ONCE(1);
418025e992a4SHeiner Kallweit }
418125e992a4SHeiner Kallweit
4182faa4e04eSHeiner Kallweit opts[0] |= skb_transport_offset(skb) << GTTCPHO_SHIFT;
41834abc3c04SHeiner Kallweit opts[1] |= mss << TD1_MSS_SHIFT;
418425e992a4SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
418525e992a4SHeiner Kallweit u8 ip_protocol;
418625e992a4SHeiner Kallweit
418725e992a4SHeiner Kallweit switch (vlan_get_protocol(skb)) {
418825e992a4SHeiner Kallweit case htons(ETH_P_IP):
418925e992a4SHeiner Kallweit opts[1] |= TD1_IPv4_CS;
419025e992a4SHeiner Kallweit ip_protocol = ip_hdr(skb)->protocol;
419125e992a4SHeiner Kallweit break;
419225e992a4SHeiner Kallweit
419325e992a4SHeiner Kallweit case htons(ETH_P_IPV6):
419425e992a4SHeiner Kallweit opts[1] |= TD1_IPv6_CS;
419525e992a4SHeiner Kallweit ip_protocol = ipv6_hdr(skb)->nexthdr;
419625e992a4SHeiner Kallweit break;
419725e992a4SHeiner Kallweit
419825e992a4SHeiner Kallweit default:
419925e992a4SHeiner Kallweit ip_protocol = IPPROTO_RAW;
420025e992a4SHeiner Kallweit break;
420125e992a4SHeiner Kallweit }
420225e992a4SHeiner Kallweit
420325e992a4SHeiner Kallweit if (ip_protocol == IPPROTO_TCP)
420425e992a4SHeiner Kallweit opts[1] |= TD1_TCP_CS;
420525e992a4SHeiner Kallweit else if (ip_protocol == IPPROTO_UDP)
420625e992a4SHeiner Kallweit opts[1] |= TD1_UDP_CS;
420725e992a4SHeiner Kallweit else
420825e992a4SHeiner Kallweit WARN_ON_ONCE(1);
420925e992a4SHeiner Kallweit
4210faa4e04eSHeiner Kallweit opts[1] |= skb_transport_offset(skb) << TCPHO_SHIFT;
421125e992a4SHeiner Kallweit } else {
42128d520b4dSHeiner Kallweit unsigned int padto = rtl_quirk_packet_padto(tp, skb);
42138d520b4dSHeiner Kallweit
42148d520b4dSHeiner Kallweit /* skb_padto would free the skb on error */
42158d520b4dSHeiner Kallweit return !__skb_put_padto(skb, padto, false);
421625e992a4SHeiner Kallweit }
421725e992a4SHeiner Kallweit
421825e992a4SHeiner Kallweit return true;
421925e992a4SHeiner Kallweit }
422025e992a4SHeiner Kallweit
rtl_tx_slots_avail(struct rtl8169_private * tp)42218624e9bbSHeiner Kallweit static unsigned int rtl_tx_slots_avail(struct rtl8169_private *tp)
422225e992a4SHeiner Kallweit {
42238624e9bbSHeiner Kallweit return READ_ONCE(tp->dirty_tx) + NUM_TX_DESC - READ_ONCE(tp->cur_tx);
422425e992a4SHeiner Kallweit }
422525e992a4SHeiner Kallweit
422625e992a4SHeiner Kallweit /* Versions RTL8102e and from RTL8168c onwards support csum_v2 */
rtl_chip_supports_csum_v2(struct rtl8169_private * tp)422725e992a4SHeiner Kallweit static bool rtl_chip_supports_csum_v2(struct rtl8169_private *tp)
422825e992a4SHeiner Kallweit {
422925e992a4SHeiner Kallweit switch (tp->mac_version) {
423025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
423125e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_10 ... RTL_GIGA_MAC_VER_17:
423225e992a4SHeiner Kallweit return false;
423325e992a4SHeiner Kallweit default:
423425e992a4SHeiner Kallweit return true;
423525e992a4SHeiner Kallweit }
423625e992a4SHeiner Kallweit }
423725e992a4SHeiner Kallweit
rtl8169_doorbell(struct rtl8169_private * tp)4238f1bce4adSHeiner Kallweit static void rtl8169_doorbell(struct rtl8169_private *tp)
4239f1bce4adSHeiner Kallweit {
4240f1bce4adSHeiner Kallweit if (rtl_is_8125(tp))
4241f1bce4adSHeiner Kallweit RTL_W16(tp, TxPoll_8125, BIT(0));
4242f1bce4adSHeiner Kallweit else
4243f1bce4adSHeiner Kallweit RTL_W8(tp, TxPoll, NPQ);
4244f1bce4adSHeiner Kallweit }
4245f1bce4adSHeiner Kallweit
rtl8169_start_xmit(struct sk_buff * skb,struct net_device * dev)424625e992a4SHeiner Kallweit static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
424725e992a4SHeiner Kallweit struct net_device *dev)
424825e992a4SHeiner Kallweit {
424925e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
425025e992a4SHeiner Kallweit unsigned int entry = tp->cur_tx % NUM_TX_DESC;
4251b8447abcSHeiner Kallweit struct TxDesc *txd_first, *txd_last;
4252b8447abcSHeiner Kallweit bool stop_queue, door_bell;
425368222d7bSKen Milmore unsigned int frags;
4254b8447abcSHeiner Kallweit u32 opts[2];
4255b8447abcSHeiner Kallweit
425683c317d7SHeiner Kallweit if (unlikely(!rtl_tx_slots_avail(tp))) {
425793882c6fSHeiner Kallweit if (net_ratelimit())
425893882c6fSHeiner Kallweit netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
425925e992a4SHeiner Kallweit goto err_stop_0;
426025e992a4SHeiner Kallweit }
426125e992a4SHeiner Kallweit
4262355f948aSHeiner Kallweit opts[1] = rtl8169_tx_vlan_tag(skb);
4263b8447abcSHeiner Kallweit opts[0] = 0;
426425e992a4SHeiner Kallweit
4265b8447abcSHeiner Kallweit if (!rtl_chip_supports_csum_v2(tp))
426625e992a4SHeiner Kallweit rtl8169_tso_csum_v1(skb, opts);
4267b8447abcSHeiner Kallweit else if (!rtl8169_tso_csum_v2(tp, skb, opts))
426825e992a4SHeiner Kallweit goto err_dma_0;
426925e992a4SHeiner Kallweit
4270b8447abcSHeiner Kallweit if (unlikely(rtl8169_tx_map(tp, opts, skb_headlen(skb), skb->data,
4271b8447abcSHeiner Kallweit entry, false)))
4272b8447abcSHeiner Kallweit goto err_dma_0;
427325e992a4SHeiner Kallweit
4274bd4bdeb4SHeiner Kallweit txd_first = tp->TxDescArray + entry;
4275bd4bdeb4SHeiner Kallweit
427668222d7bSKen Milmore frags = skb_shinfo(skb)->nr_frags;
4277b8447abcSHeiner Kallweit if (frags) {
4278b8447abcSHeiner Kallweit if (rtl8169_xmit_frags(tp, skb, opts, entry))
42799020845fSHeiner Kallweit goto err_dma_1;
4280b8447abcSHeiner Kallweit entry = (entry + frags) % NUM_TX_DESC;
428125e992a4SHeiner Kallweit }
428225e992a4SHeiner Kallweit
4283b8447abcSHeiner Kallweit txd_last = tp->TxDescArray + entry;
4284b8447abcSHeiner Kallweit txd_last->opts1 |= cpu_to_le32(LastFrag);
4285b8447abcSHeiner Kallweit tp->tx_skb[entry].skb = skb;
428625e992a4SHeiner Kallweit
428725e992a4SHeiner Kallweit skb_tx_timestamp(skb);
428825e992a4SHeiner Kallweit
428925e992a4SHeiner Kallweit /* Force memory writes to complete before releasing descriptor */
429025e992a4SHeiner Kallweit dma_wmb();
429125e992a4SHeiner Kallweit
4292ef143585SHeiner Kallweit door_bell = __netdev_sent_queue(dev, skb->len, netdev_xmit_more());
4293ef143585SHeiner Kallweit
4294b8447abcSHeiner Kallweit txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag);
429525e992a4SHeiner Kallweit
4296794867eeSHeiner Kallweit /* rtl_tx needs to see descriptor changes before updated tp->cur_tx */
4297794867eeSHeiner Kallweit smp_wmb();
429825e992a4SHeiner Kallweit
429941294e6aSHeiner Kallweit WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1);
430025e992a4SHeiner Kallweit
43018624e9bbSHeiner Kallweit stop_queue = !netif_subqueue_maybe_stop(dev, 0, rtl_tx_slots_avail(tp),
43028624e9bbSHeiner Kallweit R8169_TX_STOP_THRS,
43038624e9bbSHeiner Kallweit R8169_TX_START_THRS);
43048624e9bbSHeiner Kallweit if (door_bell || stop_queue)
430541294e6aSHeiner Kallweit rtl8169_doorbell(tp);
430641294e6aSHeiner Kallweit
430725e992a4SHeiner Kallweit return NETDEV_TX_OK;
430825e992a4SHeiner Kallweit
430925e992a4SHeiner Kallweit err_dma_1:
431022d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry);
431125e992a4SHeiner Kallweit err_dma_0:
431225e992a4SHeiner Kallweit dev_kfree_skb_any(skb);
431325e992a4SHeiner Kallweit dev->stats.tx_dropped++;
431425e992a4SHeiner Kallweit return NETDEV_TX_OK;
431525e992a4SHeiner Kallweit
431625e992a4SHeiner Kallweit err_stop_0:
431725e992a4SHeiner Kallweit netif_stop_queue(dev);
431825e992a4SHeiner Kallweit dev->stats.tx_dropped++;
431925e992a4SHeiner Kallweit return NETDEV_TX_BUSY;
432025e992a4SHeiner Kallweit }
432125e992a4SHeiner Kallweit
rtl_last_frag_len(struct sk_buff * skb)4322773235f4SHeiner Kallweit static unsigned int rtl_last_frag_len(struct sk_buff *skb)
4323773235f4SHeiner Kallweit {
4324773235f4SHeiner Kallweit struct skb_shared_info *info = skb_shinfo(skb);
4325773235f4SHeiner Kallweit unsigned int nr_frags = info->nr_frags;
4326773235f4SHeiner Kallweit
4327773235f4SHeiner Kallweit if (!nr_frags)
4328773235f4SHeiner Kallweit return UINT_MAX;
4329773235f4SHeiner Kallweit
4330773235f4SHeiner Kallweit return skb_frag_size(info->frags + nr_frags - 1);
4331773235f4SHeiner Kallweit }
4332773235f4SHeiner Kallweit
4333773235f4SHeiner Kallweit /* Workaround for hw issues with TSO on RTL8168evl */
rtl8168evl_fix_tso(struct sk_buff * skb,netdev_features_t features)4334773235f4SHeiner Kallweit static netdev_features_t rtl8168evl_fix_tso(struct sk_buff *skb,
4335773235f4SHeiner Kallweit netdev_features_t features)
4336773235f4SHeiner Kallweit {
4337773235f4SHeiner Kallweit /* IPv4 header has options field */
4338773235f4SHeiner Kallweit if (vlan_get_protocol(skb) == htons(ETH_P_IP) &&
4339773235f4SHeiner Kallweit ip_hdrlen(skb) > sizeof(struct iphdr))
4340773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO;
4341773235f4SHeiner Kallweit
4342773235f4SHeiner Kallweit /* IPv4 TCP header has options field */
4343773235f4SHeiner Kallweit else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 &&
4344773235f4SHeiner Kallweit tcp_hdrlen(skb) > sizeof(struct tcphdr))
4345773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO;
4346773235f4SHeiner Kallweit
4347773235f4SHeiner Kallweit else if (rtl_last_frag_len(skb) <= 6)
4348773235f4SHeiner Kallweit features &= ~NETIF_F_ALL_TSO;
4349773235f4SHeiner Kallweit
4350773235f4SHeiner Kallweit return features;
4351773235f4SHeiner Kallweit }
4352773235f4SHeiner Kallweit
rtl8169_features_check(struct sk_buff * skb,struct net_device * dev,netdev_features_t features)4353e64e0c89SHeiner Kallweit static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
4354e64e0c89SHeiner Kallweit struct net_device *dev,
4355e64e0c89SHeiner Kallweit netdev_features_t features)
4356e64e0c89SHeiner Kallweit {
4357e64e0c89SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
4358e64e0c89SHeiner Kallweit
4359e64e0c89SHeiner Kallweit if (skb_is_gso(skb)) {
4360773235f4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_34)
4361773235f4SHeiner Kallweit features = rtl8168evl_fix_tso(skb, features);
4362773235f4SHeiner Kallweit
4363faa4e04eSHeiner Kallweit if (skb_transport_offset(skb) > GTTCPHO_MAX &&
4364e64e0c89SHeiner Kallweit rtl_chip_supports_csum_v2(tp))
4365e64e0c89SHeiner Kallweit features &= ~NETIF_F_ALL_TSO;
4366e64e0c89SHeiner Kallweit } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
4367847f0a2bSHeiner Kallweit /* work around hw bug on some chip versions */
4368847f0a2bSHeiner Kallweit if (skb->len < ETH_ZLEN)
4369e64e0c89SHeiner Kallweit features &= ~NETIF_F_CSUM_MASK;
4370e64e0c89SHeiner Kallweit
43718d520b4dSHeiner Kallweit if (rtl_quirk_packet_padto(tp, skb))
43728d520b4dSHeiner Kallweit features &= ~NETIF_F_CSUM_MASK;
43738d520b4dSHeiner Kallweit
4374faa4e04eSHeiner Kallweit if (skb_transport_offset(skb) > TCPHO_MAX &&
4375e64e0c89SHeiner Kallweit rtl_chip_supports_csum_v2(tp))
4376e64e0c89SHeiner Kallweit features &= ~NETIF_F_CSUM_MASK;
4377e64e0c89SHeiner Kallweit }
4378e64e0c89SHeiner Kallweit
4379e64e0c89SHeiner Kallweit return vlan_features_check(skb, features);
4380e64e0c89SHeiner Kallweit }
4381e64e0c89SHeiner Kallweit
rtl8169_pcierr_interrupt(struct net_device * dev)438225e992a4SHeiner Kallweit static void rtl8169_pcierr_interrupt(struct net_device *dev)
438325e992a4SHeiner Kallweit {
438425e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
438525e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev;
43862864a883SHeiner Kallweit int pci_status_errs;
43872864a883SHeiner Kallweit u16 pci_cmd;
438825e992a4SHeiner Kallweit
438925e992a4SHeiner Kallweit pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
439025e992a4SHeiner Kallweit
43912864a883SHeiner Kallweit pci_status_errs = pci_status_get_and_clear_errors(pdev);
43922864a883SHeiner Kallweit
439393882c6fSHeiner Kallweit if (net_ratelimit())
439493882c6fSHeiner Kallweit netdev_err(dev, "PCI error (cmd = 0x%04x, status_errs = 0x%04x)\n",
43952864a883SHeiner Kallweit pci_cmd, pci_status_errs);
439625e992a4SHeiner Kallweit
439725e992a4SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
439825e992a4SHeiner Kallweit }
439925e992a4SHeiner Kallweit
rtl_tx(struct net_device * dev,struct rtl8169_private * tp,int budget)440025e992a4SHeiner Kallweit static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
440125e992a4SHeiner Kallweit int budget)
440225e992a4SHeiner Kallweit {
4403ca1ab89cSHeiner Kallweit unsigned int dirty_tx, bytes_compl = 0, pkts_compl = 0;
440494d8a98eSHeiner Kallweit struct sk_buff *skb;
440525e992a4SHeiner Kallweit
440625e992a4SHeiner Kallweit dirty_tx = tp->dirty_tx;
440725e992a4SHeiner Kallweit
4408ca1ab89cSHeiner Kallweit while (READ_ONCE(tp->cur_tx) != dirty_tx) {
440925e992a4SHeiner Kallweit unsigned int entry = dirty_tx % NUM_TX_DESC;
441025e992a4SHeiner Kallweit u32 status;
441125e992a4SHeiner Kallweit
4412dcf75a0fSMirsad Goran Todorovac status = le32_to_cpu(READ_ONCE(tp->TxDescArray[entry].opts1));
441325e992a4SHeiner Kallweit if (status & DescOwn)
441425e992a4SHeiner Kallweit break;
441525e992a4SHeiner Kallweit
441694d8a98eSHeiner Kallweit skb = tp->tx_skb[entry].skb;
441722d352c5SHeiner Kallweit rtl8169_unmap_tx_skb(tp, entry);
441822d352c5SHeiner Kallweit
44196a41f2b2SHeiner Kallweit if (skb) {
442025e992a4SHeiner Kallweit pkts_compl++;
44216a41f2b2SHeiner Kallweit bytes_compl += skb->len;
44226a41f2b2SHeiner Kallweit napi_consume_skb(skb, budget);
442325e992a4SHeiner Kallweit }
442425e992a4SHeiner Kallweit dirty_tx++;
442525e992a4SHeiner Kallweit }
442625e992a4SHeiner Kallweit
442725e992a4SHeiner Kallweit if (tp->dirty_tx != dirty_tx) {
44285e4cb480SHeiner Kallweit dev_sw_netstats_tx_add(dev, pkts_compl, bytes_compl);
44291a31ae00SHeiner Kallweit WRITE_ONCE(tp->dirty_tx, dirty_tx);
443025e992a4SHeiner Kallweit
44311a31ae00SHeiner Kallweit netif_subqueue_completed_wake(dev, 0, pkts_compl, bytes_compl,
44321a31ae00SHeiner Kallweit rtl_tx_slots_avail(tp),
44331a31ae00SHeiner Kallweit R8169_TX_START_THRS);
443425e992a4SHeiner Kallweit /*
443525e992a4SHeiner Kallweit * 8168 hack: TxPoll requests are lost when the Tx packets are
443625e992a4SHeiner Kallweit * too close. Let's kick an extra TxPoll request when a burst
443725e992a4SHeiner Kallweit * of start_xmit activity is detected (if it is not detected,
443825e992a4SHeiner Kallweit * it is slow enough). -- FR
443994d8a98eSHeiner Kallweit * If skb is NULL then we come here again once a tx irq is
444094d8a98eSHeiner Kallweit * triggered after the last fragment is marked transmitted.
444125e992a4SHeiner Kallweit */
4442c1c0ce31SMirsad Goran Todorovac if (READ_ONCE(tp->cur_tx) != dirty_tx && skb)
4443f1bce4adSHeiner Kallweit rtl8169_doorbell(tp);
444425e992a4SHeiner Kallweit }
444525e992a4SHeiner Kallweit }
444625e992a4SHeiner Kallweit
rtl8169_fragmented_frame(u32 status)444725e992a4SHeiner Kallweit static inline int rtl8169_fragmented_frame(u32 status)
444825e992a4SHeiner Kallweit {
444925e992a4SHeiner Kallweit return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
445025e992a4SHeiner Kallweit }
445125e992a4SHeiner Kallweit
rtl8169_rx_csum(struct sk_buff * skb,u32 opts1)445225e992a4SHeiner Kallweit static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1)
445325e992a4SHeiner Kallweit {
4454206a75e0SHeiner Kallweit u32 status = opts1 & (RxProtoMask | RxCSFailMask);
445525e992a4SHeiner Kallweit
4456206a75e0SHeiner Kallweit if (status == RxProtoTCP || status == RxProtoUDP)
445725e992a4SHeiner Kallweit skb->ip_summed = CHECKSUM_UNNECESSARY;
445825e992a4SHeiner Kallweit else
445925e992a4SHeiner Kallweit skb_checksum_none_assert(skb);
446025e992a4SHeiner Kallweit }
446125e992a4SHeiner Kallweit
rtl_rx(struct net_device * dev,struct rtl8169_private * tp,int budget)44622f53e9d7SHeiner Kallweit static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget)
446325e992a4SHeiner Kallweit {
4464588c7e5cSHeiner Kallweit struct device *d = tp_to_dev(tp);
44652f53e9d7SHeiner Kallweit int count;
446625e992a4SHeiner Kallweit
44672f53e9d7SHeiner Kallweit for (count = 0; count < budget; count++, tp->cur_rx++) {
44682f53e9d7SHeiner Kallweit unsigned int pkt_size, entry = tp->cur_rx % NUM_RX_DESC;
446925e992a4SHeiner Kallweit struct RxDesc *desc = tp->RxDescArray + entry;
4470588c7e5cSHeiner Kallweit struct sk_buff *skb;
4471588c7e5cSHeiner Kallweit const void *rx_buf;
4472588c7e5cSHeiner Kallweit dma_addr_t addr;
447325e992a4SHeiner Kallweit u32 status;
447425e992a4SHeiner Kallweit
4475f97eee48SMirsad Goran Todorovac status = le32_to_cpu(READ_ONCE(desc->opts1));
447625e992a4SHeiner Kallweit if (status & DescOwn)
447725e992a4SHeiner Kallweit break;
447825e992a4SHeiner Kallweit
447925e992a4SHeiner Kallweit /* This barrier is needed to keep us from reading
448025e992a4SHeiner Kallweit * any other fields out of the Rx descriptor until
448125e992a4SHeiner Kallweit * we know the status of DescOwn
448225e992a4SHeiner Kallweit */
448325e992a4SHeiner Kallweit dma_rmb();
448425e992a4SHeiner Kallweit
448525e992a4SHeiner Kallweit if (unlikely(status & RxRES)) {
448693882c6fSHeiner Kallweit if (net_ratelimit())
448793882c6fSHeiner Kallweit netdev_warn(dev, "Rx ERROR. status = %08x\n",
448825e992a4SHeiner Kallweit status);
448925e992a4SHeiner Kallweit dev->stats.rx_errors++;
449025e992a4SHeiner Kallweit if (status & (RxRWT | RxRUNT))
449125e992a4SHeiner Kallweit dev->stats.rx_length_errors++;
449225e992a4SHeiner Kallweit if (status & RxCRC)
449325e992a4SHeiner Kallweit dev->stats.rx_crc_errors++;
449425e992a4SHeiner Kallweit
4495588c7e5cSHeiner Kallweit if (!(dev->features & NETIF_F_RXALL))
4496588c7e5cSHeiner Kallweit goto release_descriptor;
4497588c7e5cSHeiner Kallweit else if (status & RxRWT || !(status & (RxRUNT | RxCRC)))
4498588c7e5cSHeiner Kallweit goto release_descriptor;
4499588c7e5cSHeiner Kallweit }
4500588c7e5cSHeiner Kallweit
4501fcd4e608SHeiner Kallweit pkt_size = status & GENMASK(13, 0);
450225e992a4SHeiner Kallweit if (likely(!(dev->features & NETIF_F_RXFCS)))
4503fcd4e608SHeiner Kallweit pkt_size -= ETH_FCS_LEN;
4504588c7e5cSHeiner Kallweit
4505588c7e5cSHeiner Kallweit /* The driver does not support incoming fragmented frames.
4506588c7e5cSHeiner Kallweit * They are seen as a symptom of over-mtu sized frames.
450725e992a4SHeiner Kallweit */
450825e992a4SHeiner Kallweit if (unlikely(rtl8169_fragmented_frame(status))) {
450925e992a4SHeiner Kallweit dev->stats.rx_dropped++;
451025e992a4SHeiner Kallweit dev->stats.rx_length_errors++;
451125e992a4SHeiner Kallweit goto release_descriptor;
451225e992a4SHeiner Kallweit }
451325e992a4SHeiner Kallweit
4514fcd4e608SHeiner Kallweit skb = napi_alloc_skb(&tp->napi, pkt_size);
4515fcd4e608SHeiner Kallweit if (unlikely(!skb)) {
451625e992a4SHeiner Kallweit dev->stats.rx_dropped++;
451725e992a4SHeiner Kallweit goto release_descriptor;
451825e992a4SHeiner Kallweit }
451925e992a4SHeiner Kallweit
4520588c7e5cSHeiner Kallweit addr = le64_to_cpu(desc->addr);
4521588c7e5cSHeiner Kallweit rx_buf = page_address(tp->Rx_databuff[entry]);
4522588c7e5cSHeiner Kallweit
4523588c7e5cSHeiner Kallweit dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
452432879f00SHeiner Kallweit prefetch(rx_buf);
452532879f00SHeiner Kallweit skb_copy_to_linear_data(skb, rx_buf, pkt_size);
4526fcd4e608SHeiner Kallweit skb->tail += pkt_size;
4527fcd4e608SHeiner Kallweit skb->len = pkt_size;
4528588c7e5cSHeiner Kallweit dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
4529d4ed7463SHeiner Kallweit
453025e992a4SHeiner Kallweit rtl8169_rx_csum(skb, status);
453125e992a4SHeiner Kallweit skb->protocol = eth_type_trans(skb, dev);
453225e992a4SHeiner Kallweit
453325e992a4SHeiner Kallweit rtl8169_rx_vlan_tag(desc, skb);
453425e992a4SHeiner Kallweit
453525e992a4SHeiner Kallweit if (skb->pkt_type == PACKET_MULTICAST)
453625e992a4SHeiner Kallweit dev->stats.multicast++;
453725e992a4SHeiner Kallweit
453825e992a4SHeiner Kallweit napi_gro_receive(&tp->napi, skb);
453925e992a4SHeiner Kallweit
45405e4cb480SHeiner Kallweit dev_sw_netstats_rx_add(dev, pkt_size);
454125e992a4SHeiner Kallweit release_descriptor:
454225e992a4SHeiner Kallweit rtl8169_mark_to_asic(desc);
454325e992a4SHeiner Kallweit }
454425e992a4SHeiner Kallweit
454525e992a4SHeiner Kallweit return count;
454625e992a4SHeiner Kallweit }
454725e992a4SHeiner Kallweit
rtl8169_interrupt(int irq,void * dev_instance)454825e992a4SHeiner Kallweit static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
454925e992a4SHeiner Kallweit {
455025e992a4SHeiner Kallweit struct rtl8169_private *tp = dev_instance;
4551c1d532d2SHeiner Kallweit u32 status = rtl_get_events(tp);
455225e992a4SHeiner Kallweit
45539e89d719SHeiner Kallweit if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask))
455425e992a4SHeiner Kallweit return IRQ_NONE;
455525e992a4SHeiner Kallweit
455625e992a4SHeiner Kallweit if (unlikely(status & SYSErr)) {
455725e992a4SHeiner Kallweit rtl8169_pcierr_interrupt(tp->dev);
455825e992a4SHeiner Kallweit goto out;
455925e992a4SHeiner Kallweit }
456025e992a4SHeiner Kallweit
456125e992a4SHeiner Kallweit if (status & LinkChg)
456225e992a4SHeiner Kallweit phy_mac_interrupt(tp->phydev);
456325e992a4SHeiner Kallweit
456425e992a4SHeiner Kallweit if (unlikely(status & RxFIFOOver &&
456525e992a4SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_11)) {
456625e992a4SHeiner Kallweit netif_stop_queue(tp->dev);
45676b02e407SHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
456825e992a4SHeiner Kallweit }
456925e992a4SHeiner Kallweit
457025e992a4SHeiner Kallweit rtl_irq_disable(tp);
4571766e3bacSHeiner Kallweit napi_schedule(&tp->napi);
457225e992a4SHeiner Kallweit out:
457325e992a4SHeiner Kallweit rtl_ack_events(tp, status);
457425e992a4SHeiner Kallweit
457525e992a4SHeiner Kallweit return IRQ_HANDLED;
457625e992a4SHeiner Kallweit }
457725e992a4SHeiner Kallweit
rtl_task(struct work_struct * work)457825e992a4SHeiner Kallweit static void rtl_task(struct work_struct *work)
457925e992a4SHeiner Kallweit {
458025e992a4SHeiner Kallweit struct rtl8169_private *tp =
458125e992a4SHeiner Kallweit container_of(work, struct rtl8169_private, wk.work);
458280c0576eSHeiner Kallweit int ret;
458325e992a4SHeiner Kallweit
4584abe5fc42SHeiner Kallweit rtnl_lock();
458525e992a4SHeiner Kallweit
4586e18958c6SHeiner Kallweit if (!netif_running(tp->dev) ||
458725e992a4SHeiner Kallweit !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
458825e992a4SHeiner Kallweit goto out_unlock;
458925e992a4SHeiner Kallweit
459080c0576eSHeiner Kallweit if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
4591ce870af3SHeiner Kallweit /* if chip isn't accessible, reset bus to revive it */
4592ce870af3SHeiner Kallweit if (RTL_R32(tp, TxConfig) == ~0) {
4593ce870af3SHeiner Kallweit ret = pci_reset_bus(tp->pci_dev);
4594ce870af3SHeiner Kallweit if (ret < 0) {
4595ce870af3SHeiner Kallweit netdev_err(tp->dev, "Can't reset secondary PCI bus, detach NIC\n");
4596ce870af3SHeiner Kallweit netif_device_detach(tp->dev);
4597ce870af3SHeiner Kallweit goto out_unlock;
4598ce870af3SHeiner Kallweit }
4599ce870af3SHeiner Kallweit }
4600ce870af3SHeiner Kallweit
460180c0576eSHeiner Kallweit /* ASPM compatibility issues are a typical reason for tx timeouts */
460280c0576eSHeiner Kallweit ret = pci_disable_link_state(tp->pci_dev, PCIE_LINK_STATE_L1 |
460380c0576eSHeiner Kallweit PCIE_LINK_STATE_L0S);
460480c0576eSHeiner Kallweit if (!ret)
460580c0576eSHeiner Kallweit netdev_warn_once(tp->dev, "ASPM disabled on Tx timeout\n");
460680c0576eSHeiner Kallweit goto reset;
460780c0576eSHeiner Kallweit }
460880c0576eSHeiner Kallweit
4609476c4f5dSHeiner Kallweit if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) {
461080c0576eSHeiner Kallweit reset:
4611e18958c6SHeiner Kallweit rtl_reset_work(tp);
4612476c4f5dSHeiner Kallweit netif_wake_queue(tp->dev);
4613fbe43b7fSHeiner Kallweit } else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) {
4614fbe43b7fSHeiner Kallweit rtl_reset_work(tp);
4615476c4f5dSHeiner Kallweit }
461625e992a4SHeiner Kallweit out_unlock:
4617abe5fc42SHeiner Kallweit rtnl_unlock();
461825e992a4SHeiner Kallweit }
461925e992a4SHeiner Kallweit
rtl8169_poll(struct napi_struct * napi,int budget)462025e992a4SHeiner Kallweit static int rtl8169_poll(struct napi_struct *napi, int budget)
462125e992a4SHeiner Kallweit {
462225e992a4SHeiner Kallweit struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
462325e992a4SHeiner Kallweit struct net_device *dev = tp->dev;
462425e992a4SHeiner Kallweit int work_done;
462525e992a4SHeiner Kallweit
462625e992a4SHeiner Kallweit rtl_tx(dev, tp, budget);
462725e992a4SHeiner Kallweit
46289fbb4a7aSHeiner Kallweit work_done = rtl_rx(dev, tp, budget);
46299fbb4a7aSHeiner Kallweit
4630e31a9fedSHeiner Kallweit if (work_done < budget && napi_complete_done(napi, work_done))
463125e992a4SHeiner Kallweit rtl_irq_enable(tp);
463225e992a4SHeiner Kallweit
463325e992a4SHeiner Kallweit return work_done;
463425e992a4SHeiner Kallweit }
463525e992a4SHeiner Kallweit
r8169_phylink_handler(struct net_device * ndev)463625e992a4SHeiner Kallweit static void r8169_phylink_handler(struct net_device *ndev)
463725e992a4SHeiner Kallweit {
463825e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(ndev);
46394b6c6065SJuhee Kang struct device *d = tp_to_dev(tp);
464025e992a4SHeiner Kallweit
464125e992a4SHeiner Kallweit if (netif_carrier_ok(ndev)) {
464225e992a4SHeiner Kallweit rtl_link_chg_patch(tp);
46434b6c6065SJuhee Kang pm_request_resume(d);
46440fbeb803SHeiner Kallweit netif_wake_queue(tp->dev);
464525e992a4SHeiner Kallweit } else {
46460fbeb803SHeiner Kallweit /* In few cases rx is broken after link-down otherwise */
46470fbeb803SHeiner Kallweit if (rtl_is_8125(tp))
4648fbe43b7fSHeiner Kallweit rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE);
46494b6c6065SJuhee Kang pm_runtime_idle(d);
465025e992a4SHeiner Kallweit }
465125e992a4SHeiner Kallweit
465225e992a4SHeiner Kallweit phy_print_status(tp->phydev);
465325e992a4SHeiner Kallweit }
465425e992a4SHeiner Kallweit
r8169_phy_connect(struct rtl8169_private * tp)465525e992a4SHeiner Kallweit static int r8169_phy_connect(struct rtl8169_private *tp)
465625e992a4SHeiner Kallweit {
465725e992a4SHeiner Kallweit struct phy_device *phydev = tp->phydev;
465825e992a4SHeiner Kallweit phy_interface_t phy_mode;
465925e992a4SHeiner Kallweit int ret;
466025e992a4SHeiner Kallweit
466125e992a4SHeiner Kallweit phy_mode = tp->supports_gmii ? PHY_INTERFACE_MODE_GMII :
466225e992a4SHeiner Kallweit PHY_INTERFACE_MODE_MII;
466325e992a4SHeiner Kallweit
466425e992a4SHeiner Kallweit ret = phy_connect_direct(tp->dev, phydev, r8169_phylink_handler,
466525e992a4SHeiner Kallweit phy_mode);
466625e992a4SHeiner Kallweit if (ret)
466725e992a4SHeiner Kallweit return ret;
466825e992a4SHeiner Kallweit
466966058b1cSHeiner Kallweit if (!tp->supports_gmii)
467025e992a4SHeiner Kallweit phy_set_max_speed(phydev, SPEED_100);
467125e992a4SHeiner Kallweit
467225e992a4SHeiner Kallweit phy_attached_info(phydev);
467325e992a4SHeiner Kallweit
467425e992a4SHeiner Kallweit return 0;
467525e992a4SHeiner Kallweit }
467625e992a4SHeiner Kallweit
rtl8169_down(struct rtl8169_private * tp)46778ac8e8c6SHeiner Kallweit static void rtl8169_down(struct rtl8169_private *tp)
467825e992a4SHeiner Kallweit {
46798ac8e8c6SHeiner Kallweit /* Clear all task flags */
46808ac8e8c6SHeiner Kallweit bitmap_zero(tp->wk.flags, RTL_FLAG_MAX);
468125e992a4SHeiner Kallweit
468225e992a4SHeiner Kallweit phy_stop(tp->phydev);
468325e992a4SHeiner Kallweit
4684a2ee8472SHeiner Kallweit rtl8169_update_counters(tp);
4685a2ee8472SHeiner Kallweit
4686f658b909SHeiner Kallweit pci_clear_master(tp->pci_dev);
4687f658b909SHeiner Kallweit rtl_pci_commit(tp);
4688f658b909SHeiner Kallweit
4689bb41c13cSChunhao Lin rtl8169_cleanup(tp);
4690d192181cSHeiner Kallweit rtl_disable_exit_l1(tp);
46917257c977SHeiner Kallweit rtl_prepare_power_down(tp);
4692a5126096SChunHao Lin
4693a5126096SChunHao Lin if (tp->dash_type != RTL_DASH_NONE)
4694a5126096SChunHao Lin rtl8168_driver_stop(tp);
469525e992a4SHeiner Kallweit }
469625e992a4SHeiner Kallweit
rtl8169_up(struct rtl8169_private * tp)4697567ca57fSHeiner Kallweit static void rtl8169_up(struct rtl8169_private *tp)
4698567ca57fSHeiner Kallweit {
4699a5126096SChunHao Lin if (tp->dash_type != RTL_DASH_NONE)
4700a5126096SChunHao Lin rtl8168_driver_start(tp);
4701a5126096SChunHao Lin
4702f658b909SHeiner Kallweit pci_set_master(tp->pci_dev);
47035c2280fcSHeiner Kallweit phy_init_hw(tp->phydev);
47047257c977SHeiner Kallweit phy_resume(tp->phydev);
4705567ca57fSHeiner Kallweit rtl8169_init_phy(tp);
4706567ca57fSHeiner Kallweit napi_enable(&tp->napi);
4707567ca57fSHeiner Kallweit set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
4708567ca57fSHeiner Kallweit rtl_reset_work(tp);
4709567ca57fSHeiner Kallweit
4710567ca57fSHeiner Kallweit phy_start(tp->phydev);
4711567ca57fSHeiner Kallweit }
4712567ca57fSHeiner Kallweit
rtl8169_close(struct net_device * dev)471325e992a4SHeiner Kallweit static int rtl8169_close(struct net_device *dev)
471425e992a4SHeiner Kallweit {
471525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
471625e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev;
471725e992a4SHeiner Kallweit
471825e992a4SHeiner Kallweit pm_runtime_get_sync(&pdev->dev);
471925e992a4SHeiner Kallweit
47208ac8e8c6SHeiner Kallweit netif_stop_queue(dev);
47218ac8e8c6SHeiner Kallweit rtl8169_down(tp);
47228ac8e8c6SHeiner Kallweit rtl8169_rx_clear(tp);
472325e992a4SHeiner Kallweit
4724a9ef8976SHeiner Kallweit cancel_work(&tp->wk.work);
472525e992a4SHeiner Kallweit
47261bd32771SThomas Gleixner free_irq(tp->irq, tp);
472725e992a4SHeiner Kallweit
4728cc9f07a8SHeiner Kallweit phy_disconnect(tp->phydev);
4729cc9f07a8SHeiner Kallweit
473025e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
473125e992a4SHeiner Kallweit tp->RxPhyAddr);
473225e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
473325e992a4SHeiner Kallweit tp->TxPhyAddr);
473425e992a4SHeiner Kallweit tp->TxDescArray = NULL;
473525e992a4SHeiner Kallweit tp->RxDescArray = NULL;
473625e992a4SHeiner Kallweit
473725e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev);
473825e992a4SHeiner Kallweit
473925e992a4SHeiner Kallweit return 0;
474025e992a4SHeiner Kallweit }
474125e992a4SHeiner Kallweit
474225e992a4SHeiner Kallweit #ifdef CONFIG_NET_POLL_CONTROLLER
rtl8169_netpoll(struct net_device * dev)474325e992a4SHeiner Kallweit static void rtl8169_netpoll(struct net_device *dev)
474425e992a4SHeiner Kallweit {
474525e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
474625e992a4SHeiner Kallweit
47471bd32771SThomas Gleixner rtl8169_interrupt(tp->irq, tp);
474825e992a4SHeiner Kallweit }
474925e992a4SHeiner Kallweit #endif
475025e992a4SHeiner Kallweit
rtl_open(struct net_device * dev)475125e992a4SHeiner Kallweit static int rtl_open(struct net_device *dev)
475225e992a4SHeiner Kallweit {
475325e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
475425e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev;
4755870f531eSHeiner Kallweit unsigned long irqflags;
475625e992a4SHeiner Kallweit int retval = -ENOMEM;
475725e992a4SHeiner Kallweit
475825e992a4SHeiner Kallweit pm_runtime_get_sync(&pdev->dev);
475925e992a4SHeiner Kallweit
476025e992a4SHeiner Kallweit /*
476125e992a4SHeiner Kallweit * Rx and Tx descriptors needs 256 bytes alignment.
476225e992a4SHeiner Kallweit * dma_alloc_coherent provides more.
476325e992a4SHeiner Kallweit */
476425e992a4SHeiner Kallweit tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES,
476525e992a4SHeiner Kallweit &tp->TxPhyAddr, GFP_KERNEL);
476625e992a4SHeiner Kallweit if (!tp->TxDescArray)
47671c470b53SHeiner Kallweit goto out;
476825e992a4SHeiner Kallweit
476925e992a4SHeiner Kallweit tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES,
477025e992a4SHeiner Kallweit &tp->RxPhyAddr, GFP_KERNEL);
477125e992a4SHeiner Kallweit if (!tp->RxDescArray)
477225e992a4SHeiner Kallweit goto err_free_tx_0;
477325e992a4SHeiner Kallweit
477425e992a4SHeiner Kallweit retval = rtl8169_init_ring(tp);
477525e992a4SHeiner Kallweit if (retval < 0)
477625e992a4SHeiner Kallweit goto err_free_rx_1;
477725e992a4SHeiner Kallweit
477825e992a4SHeiner Kallweit rtl_request_firmware(tp);
477925e992a4SHeiner Kallweit
4780870f531eSHeiner Kallweit irqflags = pci_dev_msi_enabled(pdev) ? IRQF_NO_THREAD : IRQF_SHARED;
47811bd32771SThomas Gleixner retval = request_irq(tp->irq, rtl8169_interrupt, irqflags, dev->name, tp);
478225e992a4SHeiner Kallweit if (retval < 0)
478325e992a4SHeiner Kallweit goto err_release_fw_2;
478425e992a4SHeiner Kallweit
478525e992a4SHeiner Kallweit retval = r8169_phy_connect(tp);
478625e992a4SHeiner Kallweit if (retval)
478725e992a4SHeiner Kallweit goto err_free_irq;
478825e992a4SHeiner Kallweit
4789567ca57fSHeiner Kallweit rtl8169_up(tp);
4790d56f58ceSHeiner Kallweit rtl8169_init_counter_offsets(tp);
479125e992a4SHeiner Kallweit netif_start_queue(dev);
479225e992a4SHeiner Kallweit out:
47931c470b53SHeiner Kallweit pm_runtime_put_sync(&pdev->dev);
47941c470b53SHeiner Kallweit
479525e992a4SHeiner Kallweit return retval;
479625e992a4SHeiner Kallweit
479725e992a4SHeiner Kallweit err_free_irq:
47981bd32771SThomas Gleixner free_irq(tp->irq, tp);
479925e992a4SHeiner Kallweit err_release_fw_2:
480025e992a4SHeiner Kallweit rtl_release_firmware(tp);
480125e992a4SHeiner Kallweit rtl8169_rx_clear(tp);
480225e992a4SHeiner Kallweit err_free_rx_1:
480325e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
480425e992a4SHeiner Kallweit tp->RxPhyAddr);
480525e992a4SHeiner Kallweit tp->RxDescArray = NULL;
480625e992a4SHeiner Kallweit err_free_tx_0:
480725e992a4SHeiner Kallweit dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
480825e992a4SHeiner Kallweit tp->TxPhyAddr);
480925e992a4SHeiner Kallweit tp->TxDescArray = NULL;
481025e992a4SHeiner Kallweit goto out;
481125e992a4SHeiner Kallweit }
481225e992a4SHeiner Kallweit
481325e992a4SHeiner Kallweit static void
rtl8169_get_stats64(struct net_device * dev,struct rtnl_link_stats64 * stats)481425e992a4SHeiner Kallweit rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
481525e992a4SHeiner Kallweit {
481625e992a4SHeiner Kallweit struct rtl8169_private *tp = netdev_priv(dev);
481725e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev;
481825e992a4SHeiner Kallweit struct rtl8169_counters *counters = tp->counters;
481925e992a4SHeiner Kallweit
482025e992a4SHeiner Kallweit pm_runtime_get_noresume(&pdev->dev);
482125e992a4SHeiner Kallweit
4822314a9cbbSHeiner Kallweit netdev_stats_to_stats64(stats, &dev->stats);
48235e4cb480SHeiner Kallweit dev_fetch_sw_netstats(stats, dev->tstats);
482425e992a4SHeiner Kallweit
482525e992a4SHeiner Kallweit /*
4826ed72a9bbSCorentin Musard * Fetch additional counter values missing in stats collected by driver
482725e992a4SHeiner Kallweit * from tally counters.
482825e992a4SHeiner Kallweit */
482925e992a4SHeiner Kallweit if (pm_runtime_active(&pdev->dev))
483025e992a4SHeiner Kallweit rtl8169_update_counters(tp);
483125e992a4SHeiner Kallweit
483225e992a4SHeiner Kallweit /*
483325e992a4SHeiner Kallweit * Subtract values fetched during initalization.
483425e992a4SHeiner Kallweit * See rtl8169_init_counter_offsets for a description why we do that.
483525e992a4SHeiner Kallweit */
483625e992a4SHeiner Kallweit stats->tx_errors = le64_to_cpu(counters->tx_errors) -
483725e992a4SHeiner Kallweit le64_to_cpu(tp->tc_offset.tx_errors);
483825e992a4SHeiner Kallweit stats->collisions = le32_to_cpu(counters->tx_multi_collision) -
483925e992a4SHeiner Kallweit le32_to_cpu(tp->tc_offset.tx_multi_collision);
484025e992a4SHeiner Kallweit stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) -
484125e992a4SHeiner Kallweit le16_to_cpu(tp->tc_offset.tx_aborted);
48420da3359aSHeiner Kallweit stats->rx_missed_errors = le16_to_cpu(counters->rx_missed) -
48430da3359aSHeiner Kallweit le16_to_cpu(tp->tc_offset.rx_missed);
484425e992a4SHeiner Kallweit
484525e992a4SHeiner Kallweit pm_runtime_put_noidle(&pdev->dev);
484625e992a4SHeiner Kallweit }
484725e992a4SHeiner Kallweit
rtl8169_net_suspend(struct rtl8169_private * tp)484827dc36aeSHeiner Kallweit static void rtl8169_net_suspend(struct rtl8169_private *tp)
484925e992a4SHeiner Kallweit {
485027dc36aeSHeiner Kallweit netif_device_detach(tp->dev);
4851476c4f5dSHeiner Kallweit
4852476c4f5dSHeiner Kallweit if (netif_running(tp->dev))
48538ac8e8c6SHeiner Kallweit rtl8169_down(tp);
485425e992a4SHeiner Kallweit }
485525e992a4SHeiner Kallweit
rtl8169_runtime_resume(struct device * dev)485606e56697SHeiner Kallweit static int rtl8169_runtime_resume(struct device *dev)
485725e992a4SHeiner Kallweit {
485806e56697SHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(dev);
485906e56697SHeiner Kallweit
486027dc36aeSHeiner Kallweit rtl_rar_set(tp, tp->dev->dev_addr);
486106e56697SHeiner Kallweit __rtl8169_set_wol(tp, tp->saved_wolopts);
486225e992a4SHeiner Kallweit
4863288302daSHeiner Kallweit if (tp->TxDescArray)
4864567ca57fSHeiner Kallweit rtl8169_up(tp);
486525e992a4SHeiner Kallweit
4866476c4f5dSHeiner Kallweit netif_device_attach(tp->dev);
4867476c4f5dSHeiner Kallweit
486825e992a4SHeiner Kallweit return 0;
486925e992a4SHeiner Kallweit }
487025e992a4SHeiner Kallweit
rtl8169_suspend(struct device * device)48718fe6e670SHeiner Kallweit static int rtl8169_suspend(struct device *device)
4872bb13a800SHeiner Kallweit {
4873bb13a800SHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device);
4874bb13a800SHeiner Kallweit
4875bb13a800SHeiner Kallweit rtnl_lock();
4876bb13a800SHeiner Kallweit rtl8169_net_suspend(tp);
4877bb13a800SHeiner Kallweit if (!device_may_wakeup(tp_to_dev(tp)))
4878bb13a800SHeiner Kallweit clk_disable_unprepare(tp->clk);
4879bb13a800SHeiner Kallweit rtnl_unlock();
4880bb13a800SHeiner Kallweit
4881bb13a800SHeiner Kallweit return 0;
4882bb13a800SHeiner Kallweit }
4883bb13a800SHeiner Kallweit
rtl8169_resume(struct device * device)48848fe6e670SHeiner Kallweit static int rtl8169_resume(struct device *device)
4885bb13a800SHeiner Kallweit {
4886bb13a800SHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device);
4887bb13a800SHeiner Kallweit
4888bb13a800SHeiner Kallweit if (!device_may_wakeup(tp_to_dev(tp)))
4889bb13a800SHeiner Kallweit clk_prepare_enable(tp->clk);
4890bb13a800SHeiner Kallweit
4891ef9da46dSHeiner Kallweit /* Reportedly at least Asus X453MA truncates packets otherwise */
4892ef9da46dSHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_37)
4893ef9da46dSHeiner Kallweit rtl_init_rxcfg(tp);
4894ef9da46dSHeiner Kallweit
489506e56697SHeiner Kallweit return rtl8169_runtime_resume(device);
4896bb13a800SHeiner Kallweit }
4897bb13a800SHeiner Kallweit
rtl8169_runtime_suspend(struct device * device)489825e992a4SHeiner Kallweit static int rtl8169_runtime_suspend(struct device *device)
489925e992a4SHeiner Kallweit {
490027dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device);
490125e992a4SHeiner Kallweit
4902476c4f5dSHeiner Kallweit if (!tp->TxDescArray) {
4903476c4f5dSHeiner Kallweit netif_device_detach(tp->dev);
490425e992a4SHeiner Kallweit return 0;
4905476c4f5dSHeiner Kallweit }
490625e992a4SHeiner Kallweit
4907abe5fc42SHeiner Kallweit rtnl_lock();
490801bd753dSHeiner Kallweit __rtl8169_set_wol(tp, WAKE_PHY);
490927dc36aeSHeiner Kallweit rtl8169_net_suspend(tp);
4910abe5fc42SHeiner Kallweit rtnl_unlock();
491125e992a4SHeiner Kallweit
491225e992a4SHeiner Kallweit return 0;
491325e992a4SHeiner Kallweit }
491425e992a4SHeiner Kallweit
rtl8169_runtime_idle(struct device * device)491525e992a4SHeiner Kallweit static int rtl8169_runtime_idle(struct device *device)
491625e992a4SHeiner Kallweit {
491727dc36aeSHeiner Kallweit struct rtl8169_private *tp = dev_get_drvdata(device);
491825e992a4SHeiner Kallweit
4919c61d525fSChunHao Lin if (tp->dash_enabled)
492054744510SHeiner Kallweit return -EBUSY;
492154744510SHeiner Kallweit
492227dc36aeSHeiner Kallweit if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev))
492325e992a4SHeiner Kallweit pm_schedule_suspend(device, 10000);
492425e992a4SHeiner Kallweit
492525e992a4SHeiner Kallweit return -EBUSY;
492625e992a4SHeiner Kallweit }
492725e992a4SHeiner Kallweit
492825e992a4SHeiner Kallweit static const struct dev_pm_ops rtl8169_pm_ops = {
49298fe6e670SHeiner Kallweit SYSTEM_SLEEP_PM_OPS(rtl8169_suspend, rtl8169_resume)
49308fe6e670SHeiner Kallweit RUNTIME_PM_OPS(rtl8169_runtime_suspend, rtl8169_runtime_resume,
493167ee63efSHeiner Kallweit rtl8169_runtime_idle)
493225e992a4SHeiner Kallweit };
493325e992a4SHeiner Kallweit
rtl_shutdown(struct pci_dev * pdev)493425e992a4SHeiner Kallweit static void rtl_shutdown(struct pci_dev *pdev)
493525e992a4SHeiner Kallweit {
493627dc36aeSHeiner Kallweit struct rtl8169_private *tp = pci_get_drvdata(pdev);
493725e992a4SHeiner Kallweit
4938abe5fc42SHeiner Kallweit rtnl_lock();
493927dc36aeSHeiner Kallweit rtl8169_net_suspend(tp);
4940abe5fc42SHeiner Kallweit rtnl_unlock();
494125e992a4SHeiner Kallweit
494225e992a4SHeiner Kallweit /* Restore original MAC address */
494327dc36aeSHeiner Kallweit rtl_rar_set(tp, tp->dev->perm_addr);
494425e992a4SHeiner Kallweit
4945c61d525fSChunHao Lin if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) {
4946bb703e57SHeiner Kallweit pci_wake_from_d3(pdev, tp->saved_wolopts);
494725e992a4SHeiner Kallweit pci_set_power_state(pdev, PCI_D3hot);
494825e992a4SHeiner Kallweit }
494925e992a4SHeiner Kallweit }
495025e992a4SHeiner Kallweit
rtl_remove_one(struct pci_dev * pdev)495125e992a4SHeiner Kallweit static void rtl_remove_one(struct pci_dev *pdev)
495225e992a4SHeiner Kallweit {
495327dc36aeSHeiner Kallweit struct rtl8169_private *tp = pci_get_drvdata(pdev);
495425e992a4SHeiner Kallweit
495512b1bc75SHeiner Kallweit if (pci_dev_run_wake(pdev))
495612b1bc75SHeiner Kallweit pm_runtime_get_noresume(&pdev->dev);
495725e992a4SHeiner Kallweit
4958a9ef8976SHeiner Kallweit cancel_work_sync(&tp->wk.work);
4959a9ef8976SHeiner Kallweit
496027dc36aeSHeiner Kallweit unregister_netdev(tp->dev);
496125e992a4SHeiner Kallweit
4962e0d38b58SHeiner Kallweit if (tp->dash_type != RTL_DASH_NONE)
496312b1bc75SHeiner Kallweit rtl8168_driver_stop(tp);
496425e992a4SHeiner Kallweit
496512b1bc75SHeiner Kallweit rtl_release_firmware(tp);
496625e992a4SHeiner Kallweit
496725e992a4SHeiner Kallweit /* restore original MAC address */
496827dc36aeSHeiner Kallweit rtl_rar_set(tp, tp->dev->perm_addr);
496925e992a4SHeiner Kallweit }
497025e992a4SHeiner Kallweit
497125e992a4SHeiner Kallweit static const struct net_device_ops rtl_netdev_ops = {
497225e992a4SHeiner Kallweit .ndo_open = rtl_open,
497325e992a4SHeiner Kallweit .ndo_stop = rtl8169_close,
497425e992a4SHeiner Kallweit .ndo_get_stats64 = rtl8169_get_stats64,
497525e992a4SHeiner Kallweit .ndo_start_xmit = rtl8169_start_xmit,
4976e64e0c89SHeiner Kallweit .ndo_features_check = rtl8169_features_check,
497725e992a4SHeiner Kallweit .ndo_tx_timeout = rtl8169_tx_timeout,
497825e992a4SHeiner Kallweit .ndo_validate_addr = eth_validate_addr,
497925e992a4SHeiner Kallweit .ndo_change_mtu = rtl8169_change_mtu,
498025e992a4SHeiner Kallweit .ndo_fix_features = rtl8169_fix_features,
498125e992a4SHeiner Kallweit .ndo_set_features = rtl8169_set_features,
498225e992a4SHeiner Kallweit .ndo_set_mac_address = rtl_set_mac_address,
4983a7605370SArnd Bergmann .ndo_eth_ioctl = phy_do_ioctl_running,
498425e992a4SHeiner Kallweit .ndo_set_rx_mode = rtl_set_rx_mode,
498525e992a4SHeiner Kallweit #ifdef CONFIG_NET_POLL_CONTROLLER
498625e992a4SHeiner Kallweit .ndo_poll_controller = rtl8169_netpoll,
498725e992a4SHeiner Kallweit #endif
498825e992a4SHeiner Kallweit
498925e992a4SHeiner Kallweit };
499025e992a4SHeiner Kallweit
rtl_set_irq_mask(struct rtl8169_private * tp)4991ec9a4088SHeiner Kallweit static void rtl_set_irq_mask(struct rtl8169_private *tp)
4992ec9a4088SHeiner Kallweit {
49932045e158SHeiner Kallweit tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg;
4994ec9a4088SHeiner Kallweit
4995ec9a4088SHeiner Kallweit if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
4996ec9a4088SHeiner Kallweit tp->irq_mask |= SYSErr | RxOverflow | RxFIFOOver;
4997ec9a4088SHeiner Kallweit else if (tp->mac_version == RTL_GIGA_MAC_VER_11)
4998ec9a4088SHeiner Kallweit /* special workaround needed */
4999ec9a4088SHeiner Kallweit tp->irq_mask |= RxFIFOOver;
5000ec9a4088SHeiner Kallweit else
5001ec9a4088SHeiner Kallweit tp->irq_mask |= RxOverflow;
5002ec9a4088SHeiner Kallweit }
5003ec9a4088SHeiner Kallweit
rtl_alloc_irq(struct rtl8169_private * tp)500425e992a4SHeiner Kallweit static int rtl_alloc_irq(struct rtl8169_private *tp)
500525e992a4SHeiner Kallweit {
500625e992a4SHeiner Kallweit unsigned int flags;
500725e992a4SHeiner Kallweit
5008003bd5b4SHeiner Kallweit switch (tp->mac_version) {
5009003bd5b4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
501025e992a4SHeiner Kallweit rtl_unlock_config_regs(tp);
501125e992a4SHeiner Kallweit RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable);
501225e992a4SHeiner Kallweit rtl_lock_config_regs(tp);
5013df561f66SGustavo A. R. Silva fallthrough;
5014f13bc681SHeiner Kallweit case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_17:
501525e992a4SHeiner Kallweit flags = PCI_IRQ_LEGACY;
5016003bd5b4SHeiner Kallweit break;
5017003bd5b4SHeiner Kallweit default:
501825e992a4SHeiner Kallweit flags = PCI_IRQ_ALL_TYPES;
5019003bd5b4SHeiner Kallweit break;
502025e992a4SHeiner Kallweit }
502125e992a4SHeiner Kallweit
502225e992a4SHeiner Kallweit return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags);
502325e992a4SHeiner Kallweit }
502425e992a4SHeiner Kallweit
rtl_read_mac_address(struct rtl8169_private * tp,u8 mac_addr[ETH_ALEN])502525e992a4SHeiner Kallweit static void rtl_read_mac_address(struct rtl8169_private *tp,
502625e992a4SHeiner Kallweit u8 mac_addr[ETH_ALEN])
502725e992a4SHeiner Kallweit {
502825e992a4SHeiner Kallweit /* Get MAC address */
50299e9f33baSHeiner Kallweit if (rtl_is_8168evl_up(tp) && tp->mac_version != RTL_GIGA_MAC_VER_34) {
5030ae1e82c6SHeiner Kallweit u32 value;
50319e9f33baSHeiner Kallweit
5032ae1e82c6SHeiner Kallweit value = rtl_eri_read(tp, 0xe0);
5033ae1e82c6SHeiner Kallweit put_unaligned_le32(value, mac_addr);
503425e992a4SHeiner Kallweit value = rtl_eri_read(tp, 0xe4);
5035ae1e82c6SHeiner Kallweit put_unaligned_le16(value, mac_addr + 4);
5036f1bce4adSHeiner Kallweit } else if (rtl_is_8125(tp)) {
5037f1bce4adSHeiner Kallweit rtl_read_mac_from_reg(tp, mac_addr, MAC0_BKP);
503825e992a4SHeiner Kallweit }
503925e992a4SHeiner Kallweit }
504025e992a4SHeiner Kallweit
DECLARE_RTL_COND(rtl_link_list_ready_cond)504125e992a4SHeiner Kallweit DECLARE_RTL_COND(rtl_link_list_ready_cond)
504225e992a4SHeiner Kallweit {
504325e992a4SHeiner Kallweit return RTL_R8(tp, MCU) & LINK_LIST_RDY;
504425e992a4SHeiner Kallweit }
504525e992a4SHeiner Kallweit
r8168g_wait_ll_share_fifo_ready(struct rtl8169_private * tp)5046e031ce80SHeiner Kallweit static void r8168g_wait_ll_share_fifo_ready(struct rtl8169_private *tp)
5047e031ce80SHeiner Kallweit {
5048e031ce80SHeiner Kallweit rtl_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42);
5049e031ce80SHeiner Kallweit }
5050e031ce80SHeiner Kallweit
r8169_mdio_read_reg(struct mii_bus * mii_bus,int phyaddr,int phyreg)505125e992a4SHeiner Kallweit static int r8169_mdio_read_reg(struct mii_bus *mii_bus, int phyaddr, int phyreg)
505225e992a4SHeiner Kallweit {
505325e992a4SHeiner Kallweit struct rtl8169_private *tp = mii_bus->priv;
505425e992a4SHeiner Kallweit
505525e992a4SHeiner Kallweit if (phyaddr > 0)
505625e992a4SHeiner Kallweit return -ENODEV;
505725e992a4SHeiner Kallweit
505825e992a4SHeiner Kallweit return rtl_readphy(tp, phyreg);
505925e992a4SHeiner Kallweit }
506025e992a4SHeiner Kallweit
r8169_mdio_write_reg(struct mii_bus * mii_bus,int phyaddr,int phyreg,u16 val)506125e992a4SHeiner Kallweit static int r8169_mdio_write_reg(struct mii_bus *mii_bus, int phyaddr,
506225e992a4SHeiner Kallweit int phyreg, u16 val)
506325e992a4SHeiner Kallweit {
506425e992a4SHeiner Kallweit struct rtl8169_private *tp = mii_bus->priv;
506525e992a4SHeiner Kallweit
506625e992a4SHeiner Kallweit if (phyaddr > 0)
506725e992a4SHeiner Kallweit return -ENODEV;
506825e992a4SHeiner Kallweit
506925e992a4SHeiner Kallweit rtl_writephy(tp, phyreg, val);
507025e992a4SHeiner Kallweit
507125e992a4SHeiner Kallweit return 0;
507225e992a4SHeiner Kallweit }
507325e992a4SHeiner Kallweit
r8169_mdio_register(struct rtl8169_private * tp)507425e992a4SHeiner Kallweit static int r8169_mdio_register(struct rtl8169_private *tp)
507525e992a4SHeiner Kallweit {
507625e992a4SHeiner Kallweit struct pci_dev *pdev = tp->pci_dev;
507725e992a4SHeiner Kallweit struct mii_bus *new_bus;
507825e992a4SHeiner Kallweit int ret;
507925e992a4SHeiner Kallweit
5080b9906101SHeiner Kallweit /* On some boards with this chip version the BIOS is buggy and misses
5081b9906101SHeiner Kallweit * to reset the PHY page selector. This results in the PHY ID read
5082b9906101SHeiner Kallweit * accessing registers on a different page, returning a more or
5083b9906101SHeiner Kallweit * less random value. Fix this by resetting the page selector first.
5084b9906101SHeiner Kallweit */
5085b9906101SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_25 ||
5086b9906101SHeiner Kallweit tp->mac_version == RTL_GIGA_MAC_VER_26)
5087b9906101SHeiner Kallweit r8169_mdio_write(tp, 0x1f, 0);
5088b9906101SHeiner Kallweit
508925e992a4SHeiner Kallweit new_bus = devm_mdiobus_alloc(&pdev->dev);
509025e992a4SHeiner Kallweit if (!new_bus)
509125e992a4SHeiner Kallweit return -ENOMEM;
509225e992a4SHeiner Kallweit
509325e992a4SHeiner Kallweit new_bus->name = "r8169";
509425e992a4SHeiner Kallweit new_bus->priv = tp;
509525e992a4SHeiner Kallweit new_bus->parent = &pdev->dev;
509693e8990cSHeiner Kallweit new_bus->irq[0] = PHY_MAC_INTERRUPT;
5097e9a72f87SSayanta Pattanayak snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x-%x",
5098e9a72f87SSayanta Pattanayak pci_domain_nr(pdev->bus), pci_dev_id(pdev));
509925e992a4SHeiner Kallweit
510025e992a4SHeiner Kallweit new_bus->read = r8169_mdio_read_reg;
510125e992a4SHeiner Kallweit new_bus->write = r8169_mdio_write_reg;
510225e992a4SHeiner Kallweit
5103ac3a68d5SBartosz Golaszewski ret = devm_mdiobus_register(&pdev->dev, new_bus);
510425e992a4SHeiner Kallweit if (ret)
510525e992a4SHeiner Kallweit return ret;
510625e992a4SHeiner Kallweit
510725e992a4SHeiner Kallweit tp->phydev = mdiobus_get_phy(new_bus, 0);
510825e992a4SHeiner Kallweit if (!tp->phydev) {
510925e992a4SHeiner Kallweit return -ENODEV;
51102e8c339bSHeiner Kallweit } else if (!tp->phydev->drv) {
51112e8c339bSHeiner Kallweit /* Most chip versions fail with the genphy driver.
51122e8c339bSHeiner Kallweit * Therefore ensure that the dedicated PHY driver is loaded.
51132e8c339bSHeiner Kallweit */
51140c2006b2SHeiner Kallweit dev_err(&pdev->dev, "no dedicated PHY driver found for PHY ID 0x%08x, maybe realtek.ko needs to be added to initramfs?\n",
51150c2006b2SHeiner Kallweit tp->phydev->phy_id);
51162e8c339bSHeiner Kallweit return -EUNATCH;
511725e992a4SHeiner Kallweit }
511825e992a4SHeiner Kallweit
5119eca485d2SDenis Kirjanov tp->phydev->mac_managed_pm = true;
51205c2280fcSHeiner Kallweit
512111ac4e66SHeiner Kallweit phy_support_asym_pause(tp->phydev);
512211ac4e66SHeiner Kallweit
512325e992a4SHeiner Kallweit /* PHY will be woken up in rtl_open() */
512425e992a4SHeiner Kallweit phy_suspend(tp->phydev);
512525e992a4SHeiner Kallweit
512625e992a4SHeiner Kallweit return 0;
512725e992a4SHeiner Kallweit }
512825e992a4SHeiner Kallweit
rtl_hw_init_8168g(struct rtl8169_private * tp)512925e992a4SHeiner Kallweit static void rtl_hw_init_8168g(struct rtl8169_private *tp)
513025e992a4SHeiner Kallweit {
51319617886fSHeiner Kallweit rtl_enable_rxdvgate(tp);
513225e992a4SHeiner Kallweit
513325e992a4SHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) & ~(CmdTxEnb | CmdRxEnb));
513425e992a4SHeiner Kallweit msleep(1);
513525e992a4SHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
513625e992a4SHeiner Kallweit
5137ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, BIT(14), 0);
5138e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp);
513925e992a4SHeiner Kallweit
5140ef712edeSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, 0, BIT(15));
5141e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp);
514225e992a4SHeiner Kallweit }
514325e992a4SHeiner Kallweit
rtl_hw_init_8125(struct rtl8169_private * tp)5144f1bce4adSHeiner Kallweit static void rtl_hw_init_8125(struct rtl8169_private *tp)
5145f1bce4adSHeiner Kallweit {
51469617886fSHeiner Kallweit rtl_enable_rxdvgate(tp);
5147f1bce4adSHeiner Kallweit
5148f1bce4adSHeiner Kallweit RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) & ~(CmdTxEnb | CmdRxEnb));
5149f1bce4adSHeiner Kallweit msleep(1);
5150f1bce4adSHeiner Kallweit RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
5151f1bce4adSHeiner Kallweit
5152f1bce4adSHeiner Kallweit r8168_mac_ocp_modify(tp, 0xe8de, BIT(14), 0);
5153e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp);
5154f1bce4adSHeiner Kallweit
5155f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc0aa, 0x07d0);
5156f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc0a6, 0x0150);
5157f1bce4adSHeiner Kallweit r8168_mac_ocp_write(tp, 0xc01e, 0x5555);
5158e031ce80SHeiner Kallweit r8168g_wait_ll_share_fifo_ready(tp);
5159f1bce4adSHeiner Kallweit }
5160f1bce4adSHeiner Kallweit
rtl_hw_initialize(struct rtl8169_private * tp)516125e992a4SHeiner Kallweit static void rtl_hw_initialize(struct rtl8169_private *tp)
516225e992a4SHeiner Kallweit {
516325e992a4SHeiner Kallweit switch (tp->mac_version) {
5164133706a9SHeiner Kallweit case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
516525e992a4SHeiner Kallweit rtl8168ep_stop_cmac(tp);
5166df561f66SGustavo A. R. Silva fallthrough;
516725e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
516825e992a4SHeiner Kallweit rtl_hw_init_8168g(tp);
516925e992a4SHeiner Kallweit break;
5170efc37109SHeiner Kallweit case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
5171f1bce4adSHeiner Kallweit rtl_hw_init_8125(tp);
5172f1bce4adSHeiner Kallweit break;
517325e992a4SHeiner Kallweit default:
517425e992a4SHeiner Kallweit break;
517525e992a4SHeiner Kallweit }
517625e992a4SHeiner Kallweit }
517725e992a4SHeiner Kallweit
rtl_jumbo_max(struct rtl8169_private * tp)517825e992a4SHeiner Kallweit static int rtl_jumbo_max(struct rtl8169_private *tp)
517925e992a4SHeiner Kallweit {
518025e992a4SHeiner Kallweit /* Non-GBit versions don't support jumbo frames */
518125e992a4SHeiner Kallweit if (!tp->supports_gmii)
5182a8ec173aSHeiner Kallweit return 0;
518325e992a4SHeiner Kallweit
518425e992a4SHeiner Kallweit switch (tp->mac_version) {
518525e992a4SHeiner Kallweit /* RTL8169 */
518625e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
518725e992a4SHeiner Kallweit return JUMBO_7K;
518825e992a4SHeiner Kallweit /* RTL8168b */
518925e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_11:
519025e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_17:
519125e992a4SHeiner Kallweit return JUMBO_4K;
519225e992a4SHeiner Kallweit /* RTL8168c */
519325e992a4SHeiner Kallweit case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24:
519425e992a4SHeiner Kallweit return JUMBO_6K;
519525e992a4SHeiner Kallweit default:
519625e992a4SHeiner Kallweit return JUMBO_9K;
519725e992a4SHeiner Kallweit }
519825e992a4SHeiner Kallweit }
519925e992a4SHeiner Kallweit
rtl_init_mac_address(struct rtl8169_private * tp)5200c782e204SHeiner Kallweit static void rtl_init_mac_address(struct rtl8169_private *tp)
5201c782e204SHeiner Kallweit {
5202c75a9ad4SHeiner Kallweit u8 mac_addr[ETH_ALEN] __aligned(2) = {};
5203c782e204SHeiner Kallweit struct net_device *dev = tp->dev;
5204ce37115eSHeiner Kallweit int rc;
5205c782e204SHeiner Kallweit
5206c782e204SHeiner Kallweit rc = eth_platform_get_mac_address(tp_to_dev(tp), mac_addr);
5207c782e204SHeiner Kallweit if (!rc)
5208c782e204SHeiner Kallweit goto done;
5209c782e204SHeiner Kallweit
5210c782e204SHeiner Kallweit rtl_read_mac_address(tp, mac_addr);
5211c782e204SHeiner Kallweit if (is_valid_ether_addr(mac_addr))
5212c782e204SHeiner Kallweit goto done;
5213c782e204SHeiner Kallweit
5214ce37115eSHeiner Kallweit rtl_read_mac_from_reg(tp, mac_addr, MAC0);
5215c782e204SHeiner Kallweit if (is_valid_ether_addr(mac_addr))
5216c782e204SHeiner Kallweit goto done;
5217c782e204SHeiner Kallweit
5218c75a9ad4SHeiner Kallweit eth_random_addr(mac_addr);
5219c75a9ad4SHeiner Kallweit dev->addr_assign_type = NET_ADDR_RANDOM;
5220c782e204SHeiner Kallweit dev_warn(tp_to_dev(tp), "can't read MAC address, setting random one\n");
5221c782e204SHeiner Kallweit done:
52221c5d09d5SJakub Kicinski eth_hw_addr_set(dev, mac_addr);
5223c782e204SHeiner Kallweit rtl_rar_set(tp, mac_addr);
5224c782e204SHeiner Kallweit }
5225c782e204SHeiner Kallweit
5226cf2ffdeaSHeiner Kallweit /* register is set if system vendor successfully tested ASPM 1.2 */
rtl_aspm_is_safe(struct rtl8169_private * tp)5227cf2ffdeaSHeiner Kallweit static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
5228cf2ffdeaSHeiner Kallweit {
5229cf2ffdeaSHeiner Kallweit if (tp->mac_version >= RTL_GIGA_MAC_VER_61 &&
5230cf2ffdeaSHeiner Kallweit r8168_mac_ocp_read(tp, 0xc0b2) & 0xf)
5231cf2ffdeaSHeiner Kallweit return true;
5232cf2ffdeaSHeiner Kallweit
5233cf2ffdeaSHeiner Kallweit return false;
5234cf2ffdeaSHeiner Kallweit }
5235cf2ffdeaSHeiner Kallweit
rtl_init_one(struct pci_dev * pdev,const struct pci_device_id * ent)523625e992a4SHeiner Kallweit static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
523725e992a4SHeiner Kallweit {
523825e992a4SHeiner Kallweit struct rtl8169_private *tp;
5239f1f9ca28SHeiner Kallweit int jumbo_max, region, rc;
5240f1f9ca28SHeiner Kallweit enum mac_version chipset;
524125e992a4SHeiner Kallweit struct net_device *dev;
5242bc590b47SHeiner Kallweit u32 txconfig;
5243f1f9ca28SHeiner Kallweit u16 xid;
524425e992a4SHeiner Kallweit
524525e992a4SHeiner Kallweit dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
524625e992a4SHeiner Kallweit if (!dev)
524725e992a4SHeiner Kallweit return -ENOMEM;
524825e992a4SHeiner Kallweit
524925e992a4SHeiner Kallweit SET_NETDEV_DEV(dev, &pdev->dev);
525025e992a4SHeiner Kallweit dev->netdev_ops = &rtl_netdev_ops;
525125e992a4SHeiner Kallweit tp = netdev_priv(dev);
525225e992a4SHeiner Kallweit tp->dev = dev;
525325e992a4SHeiner Kallweit tp->pci_dev = pdev;
5254145a40e8SHeiner Kallweit tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
52557ec3f872SHeiner Kallweit tp->eee_adv = -1;
52560360c046SHeiner Kallweit tp->ocp_base = OCP_STD_PHY_BASE;
525725e992a4SHeiner Kallweit
5258d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_init(&tp->cfg9346_usage_lock);
5259d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_init(&tp->config25_lock);
5260d6c36cbcSSebastian Andrzej Siewior raw_spin_lock_init(&tp->mac_ocp_lock);
526191c86435SHeiner Kallweit
52625e4cb480SHeiner Kallweit dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
52635e4cb480SHeiner Kallweit struct pcpu_sw_netstats);
52645e4cb480SHeiner Kallweit if (!dev->tstats)
52655e4cb480SHeiner Kallweit return -ENOMEM;
52665e4cb480SHeiner Kallweit
526725e992a4SHeiner Kallweit /* Get the *optional* external "ether_clk" used on some boards */
5268599566c1SHeiner Kallweit tp->clk = devm_clk_get_optional_enabled(&pdev->dev, "ether_clk");
5269599566c1SHeiner Kallweit if (IS_ERR(tp->clk))
5270599566c1SHeiner Kallweit return dev_err_probe(&pdev->dev, PTR_ERR(tp->clk), "failed to get ether_clk\n");
527125e992a4SHeiner Kallweit
527225e992a4SHeiner Kallweit /* enable device (incl. PCI PM wakeup and hotplug setup) */
527325e992a4SHeiner Kallweit rc = pcim_enable_device(pdev);
5274733b3e27SHeiner Kallweit if (rc < 0)
5275733b3e27SHeiner Kallweit return dev_err_probe(&pdev->dev, rc, "enable failure\n");
527625e992a4SHeiner Kallweit
527725e992a4SHeiner Kallweit if (pcim_set_mwi(pdev) < 0)
527825e992a4SHeiner Kallweit dev_info(&pdev->dev, "Mem-Wr-Inval unavailable\n");
527925e992a4SHeiner Kallweit
528025e992a4SHeiner Kallweit /* use first MMIO region */
528125e992a4SHeiner Kallweit region = ffs(pci_select_bars(pdev, IORESOURCE_MEM)) - 1;
5282733b3e27SHeiner Kallweit if (region < 0)
5283733b3e27SHeiner Kallweit return dev_err_probe(&pdev->dev, -ENODEV, "no MMIO resource found\n");
528425e992a4SHeiner Kallweit
52857cb7541aSHeiner Kallweit rc = pcim_iomap_regions(pdev, BIT(region), KBUILD_MODNAME);
5286733b3e27SHeiner Kallweit if (rc < 0)
5287733b3e27SHeiner Kallweit return dev_err_probe(&pdev->dev, rc, "cannot remap MMIO, aborting\n");
528825e992a4SHeiner Kallweit
528925e992a4SHeiner Kallweit tp->mmio_addr = pcim_iomap_table(pdev)[region];
529025e992a4SHeiner Kallweit
5291bc590b47SHeiner Kallweit txconfig = RTL_R32(tp, TxConfig);
5292733b3e27SHeiner Kallweit if (txconfig == ~0U)
5293733b3e27SHeiner Kallweit return dev_err_probe(&pdev->dev, -EIO, "PCI read failed\n");
5294bc590b47SHeiner Kallweit
5295bc590b47SHeiner Kallweit xid = (txconfig >> 20) & 0xfcf;
5296f1f9ca28SHeiner Kallweit
529725e992a4SHeiner Kallweit /* Identify chip attached to board */
5298f1f9ca28SHeiner Kallweit chipset = rtl8169_get_mac_version(xid, tp->supports_gmii);
5299733b3e27SHeiner Kallweit if (chipset == RTL_GIGA_MAC_NONE)
5300733b3e27SHeiner Kallweit return dev_err_probe(&pdev->dev, -ENODEV,
5301733b3e27SHeiner Kallweit "unknown chip XID %03x, contact r8169 maintainers (see MAINTAINERS file)\n",
5302733b3e27SHeiner Kallweit xid);
5303f1f9ca28SHeiner Kallweit tp->mac_version = chipset;
530425e992a4SHeiner Kallweit
5305cf2ffdeaSHeiner Kallweit /* Disable ASPM L1 as that cause random device stop working
5306cf2ffdeaSHeiner Kallweit * problems as well as full system hangs for some PCIe devices users.
5307cf2ffdeaSHeiner Kallweit */
5308cf2ffdeaSHeiner Kallweit if (rtl_aspm_is_safe(tp))
5309cf2ffdeaSHeiner Kallweit rc = 0;
5310cf2ffdeaSHeiner Kallweit else
5311cf2ffdeaSHeiner Kallweit rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1);
5312cf2ffdeaSHeiner Kallweit tp->aspm_manageable = !rc;
5313cf2ffdeaSHeiner Kallweit
5314c61d525fSChunHao Lin tp->dash_type = rtl_get_dash_type(tp);
5315c61d525fSChunHao Lin tp->dash_enabled = rtl_dash_is_enabled(tp);
5316e0d38b58SHeiner Kallweit
5317975e8505SHeiner Kallweit tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK;
531825e992a4SHeiner Kallweit
531925e992a4SHeiner Kallweit if (sizeof(dma_addr_t) > 4 && tp->mac_version >= RTL_GIGA_MAC_VER_18 &&
53203c18cbe3SHeiner Kallweit !dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)))
532125e992a4SHeiner Kallweit dev->features |= NETIF_F_HIGHDMA;
532225e992a4SHeiner Kallweit
532325e992a4SHeiner Kallweit rtl_init_rxcfg(tp);
532425e992a4SHeiner Kallweit
532525e992a4SHeiner Kallweit rtl8169_irq_mask_and_ack(tp);
532625e992a4SHeiner Kallweit
532725e992a4SHeiner Kallweit rtl_hw_initialize(tp);
532825e992a4SHeiner Kallweit
532925e992a4SHeiner Kallweit rtl_hw_reset(tp);
533025e992a4SHeiner Kallweit
533125e992a4SHeiner Kallweit rc = rtl_alloc_irq(tp);
5332733b3e27SHeiner Kallweit if (rc < 0)
5333733b3e27SHeiner Kallweit return dev_err_probe(&pdev->dev, rc, "Can't allocate interrupt\n");
5334733b3e27SHeiner Kallweit
53351bd32771SThomas Gleixner tp->irq = pci_irq_vector(pdev, 0);
533625e992a4SHeiner Kallweit
533725e992a4SHeiner Kallweit INIT_WORK(&tp->wk.work, rtl_task);
533825e992a4SHeiner Kallweit
5339c782e204SHeiner Kallweit rtl_init_mac_address(tp);
534025e992a4SHeiner Kallweit
534125e992a4SHeiner Kallweit dev->ethtool_ops = &rtl8169_ethtool_ops;
534225e992a4SHeiner Kallweit
5343b48b89f9SJakub Kicinski netif_napi_add(dev, &tp->napi, rtl8169_poll);
534425e992a4SHeiner Kallweit
534595099c56SHeiner Kallweit dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
534695099c56SHeiner Kallweit NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
5347a9b3d568SHeiner Kallweit dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
534825e992a4SHeiner Kallweit dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
534925e992a4SHeiner Kallweit
535025e992a4SHeiner Kallweit /*
535125e992a4SHeiner Kallweit * Pretend we are using VLANs; This bypasses a nasty bug where
535225e992a4SHeiner Kallweit * Interrupts stop flowing on high load on 8110SCd controllers.
535325e992a4SHeiner Kallweit */
535425e992a4SHeiner Kallweit if (tp->mac_version == RTL_GIGA_MAC_VER_05)
535525e992a4SHeiner Kallweit /* Disallow toggling */
535625e992a4SHeiner Kallweit dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
535725e992a4SHeiner Kallweit
535895099c56SHeiner Kallweit if (rtl_chip_supports_csum_v2(tp))
535995099c56SHeiner Kallweit dev->hw_features |= NETIF_F_IPV6_CSUM;
536095099c56SHeiner Kallweit
536195099c56SHeiner Kallweit dev->features |= dev->hw_features;
536295099c56SHeiner Kallweit
536395099c56SHeiner Kallweit /* There has been a number of reports that using SG/TSO results in
536495099c56SHeiner Kallweit * tx timeouts. However for a lot of people SG/TSO works fine.
536595099c56SHeiner Kallweit * Therefore disable both features by default, but allow users to
536695099c56SHeiner Kallweit * enable them. Use at own risk!
536795099c56SHeiner Kallweit */
53680170d594SHeiner Kallweit if (rtl_chip_supports_csum_v2(tp)) {
536995099c56SHeiner Kallweit dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6;
5370ee8b7a11SJakub Kicinski netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V2);
5371ee8b7a11SJakub Kicinski netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V2);
53720170d594SHeiner Kallweit } else {
537395099c56SHeiner Kallweit dev->hw_features |= NETIF_F_SG | NETIF_F_TSO;
5374ee8b7a11SJakub Kicinski netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V1);
5375ee8b7a11SJakub Kicinski netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V1);
53760170d594SHeiner Kallweit }
537725e992a4SHeiner Kallweit
537825e992a4SHeiner Kallweit dev->hw_features |= NETIF_F_RXALL;
537925e992a4SHeiner Kallweit dev->hw_features |= NETIF_F_RXFCS;
538025e992a4SHeiner Kallweit
538142f66a44SHeiner Kallweit netdev_sw_irq_coalesce_default_on(dev);
538242f66a44SHeiner Kallweit
5383145192f8SHeiner Kallweit /* configure chip for default features */
5384145192f8SHeiner Kallweit rtl8169_set_features(dev, dev->features);
5385145192f8SHeiner Kallweit
5386c61d525fSChunHao Lin if (!tp->dash_enabled) {
5387128735a1SHeiner Kallweit rtl_set_d3_pll_down(tp, true);
538854744510SHeiner Kallweit } else {
538954744510SHeiner Kallweit rtl_set_d3_pll_down(tp, false);
539054744510SHeiner Kallweit dev->wol_enabled = 1;
539154744510SHeiner Kallweit }
5392128735a1SHeiner Kallweit
539325e992a4SHeiner Kallweit jumbo_max = rtl_jumbo_max(tp);
5394a8ec173aSHeiner Kallweit if (jumbo_max)
539525e992a4SHeiner Kallweit dev->max_mtu = jumbo_max;
539625e992a4SHeiner Kallweit
5397ec9a4088SHeiner Kallweit rtl_set_irq_mask(tp);
53989fa0a8e1SHeiner Kallweit
539925e992a4SHeiner Kallweit tp->fw_name = rtl_chip_infos[chipset].fw_name;
540025e992a4SHeiner Kallweit
540125e992a4SHeiner Kallweit tp->counters = dmam_alloc_coherent (&pdev->dev, sizeof(*tp->counters),
540225e992a4SHeiner Kallweit &tp->counters_phys_addr,
540325e992a4SHeiner Kallweit GFP_KERNEL);
540425e992a4SHeiner Kallweit if (!tp->counters)
540525e992a4SHeiner Kallweit return -ENOMEM;
540625e992a4SHeiner Kallweit
540727dc36aeSHeiner Kallweit pci_set_drvdata(pdev, tp);
540825e992a4SHeiner Kallweit
540925e992a4SHeiner Kallweit rc = r8169_mdio_register(tp);
541025e992a4SHeiner Kallweit if (rc)
541125e992a4SHeiner Kallweit return rc;
541225e992a4SHeiner Kallweit
541325e992a4SHeiner Kallweit rc = register_netdev(dev);
541425e992a4SHeiner Kallweit if (rc)
54150785dad4SHeiner Kallweit return rc;
541625e992a4SHeiner Kallweit
541793882c6fSHeiner Kallweit netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
54181bd32771SThomas Gleixner rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
541925e992a4SHeiner Kallweit
5420a8ec173aSHeiner Kallweit if (jumbo_max)
542193882c6fSHeiner Kallweit netdev_info(dev, "jumbo features [frames: %d bytes, tx checksumming: %s]\n",
542225e992a4SHeiner Kallweit jumbo_max, tp->mac_version <= RTL_GIGA_MAC_VER_06 ?
542325e992a4SHeiner Kallweit "ok" : "ko");
542425e992a4SHeiner Kallweit
5425e0d38b58SHeiner Kallweit if (tp->dash_type != RTL_DASH_NONE) {
5426c61d525fSChunHao Lin netdev_info(dev, "DASH %s\n",
5427c61d525fSChunHao Lin tp->dash_enabled ? "enabled" : "disabled");
542825e992a4SHeiner Kallweit rtl8168_driver_start(tp);
5429a38b7fbfSHeiner Kallweit }
543025e992a4SHeiner Kallweit
543125e992a4SHeiner Kallweit if (pci_dev_run_wake(pdev))
543225e992a4SHeiner Kallweit pm_runtime_put_sync(&pdev->dev);
543325e992a4SHeiner Kallweit
543425e992a4SHeiner Kallweit return 0;
543525e992a4SHeiner Kallweit }
543625e992a4SHeiner Kallweit
543725e992a4SHeiner Kallweit static struct pci_driver rtl8169_pci_driver = {
54387cb7541aSHeiner Kallweit .name = KBUILD_MODNAME,
543925e992a4SHeiner Kallweit .id_table = rtl8169_pci_tbl,
544025e992a4SHeiner Kallweit .probe = rtl_init_one,
544125e992a4SHeiner Kallweit .remove = rtl_remove_one,
544225e992a4SHeiner Kallweit .shutdown = rtl_shutdown,
54438fe6e670SHeiner Kallweit .driver.pm = pm_ptr(&rtl8169_pm_ops),
544425e992a4SHeiner Kallweit };
544525e992a4SHeiner Kallweit
544625e992a4SHeiner Kallweit module_pci_driver(rtl8169_pci_driver);
5447