diff options
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 1615 |
1 files changed, 1130 insertions, 485 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 493b0de3848..7d9c650f395 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -22,10 +22,12 @@ #include <linux/ip.h> #include <linux/tcp.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/dma-mapping.h> #include <linux/pm_runtime.h> #include <linux/firmware.h> #include <linux/pci-aspm.h> +#include <linux/prefetch.h> #include <asm/system.h> #include <asm/io.h> @@ -37,6 +39,9 @@ #define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw" #define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw" +#define FIRMWARE_8168E_1 "rtl_nic/rtl8168e-1.fw" +#define FIRMWARE_8168E_2 "rtl_nic/rtl8168e-2.fw" +#define FIRMWARE_8168E_3 "rtl_nic/rtl8168e-3.fw" #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" #ifdef RTL8169_DEBUG @@ -66,8 +71,6 @@ static const int multicast_filter_limit = 32; #define MAC_ADDR_LEN 6 #define MAX_READ_REQUEST_SHIFT 12 -#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ -#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ @@ -96,77 +99,126 @@ static const int multicast_filter_limit = 32; #define RTL_R32(reg) readl (ioaddr + (reg)) enum mac_version { - RTL_GIGA_MAC_NONE = 0x00, - RTL_GIGA_MAC_VER_01 = 0x01, // 8169 - RTL_GIGA_MAC_VER_02 = 0x02, // 8169S - RTL_GIGA_MAC_VER_03 = 0x03, // 8110S - RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB - RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd - RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe - RTL_GIGA_MAC_VER_07 = 0x07, // 8102e - RTL_GIGA_MAC_VER_08 = 0x08, // 8102e - RTL_GIGA_MAC_VER_09 = 0x09, // 8102e - RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e - RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb - RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be - RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb - RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ? - RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ? - RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec - RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf - RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP - RTL_GIGA_MAC_VER_19 = 0x13, // 8168C - RTL_GIGA_MAC_VER_20 = 0x14, // 8168C - RTL_GIGA_MAC_VER_21 = 0x15, // 8168C - RTL_GIGA_MAC_VER_22 = 0x16, // 8168C - RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP - RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP - RTL_GIGA_MAC_VER_25 = 0x19, // 8168D - RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D - RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP - RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP - RTL_GIGA_MAC_VER_29 = 0x1d, // 8105E - RTL_GIGA_MAC_VER_30 = 0x1e, // 8105E + RTL_GIGA_MAC_VER_01 = 0, + RTL_GIGA_MAC_VER_02, + RTL_GIGA_MAC_VER_03, + RTL_GIGA_MAC_VER_04, + RTL_GIGA_MAC_VER_05, + RTL_GIGA_MAC_VER_06, + RTL_GIGA_MAC_VER_07, + RTL_GIGA_MAC_VER_08, + RTL_GIGA_MAC_VER_09, + RTL_GIGA_MAC_VER_10, + RTL_GIGA_MAC_VER_11, + RTL_GIGA_MAC_VER_12, + RTL_GIGA_MAC_VER_13, + RTL_GIGA_MAC_VER_14, + RTL_GIGA_MAC_VER_15, + RTL_GIGA_MAC_VER_16, + RTL_GIGA_MAC_VER_17, + RTL_GIGA_MAC_VER_18, + RTL_GIGA_MAC_VER_19, + RTL_GIGA_MAC_VER_20, + RTL_GIGA_MAC_VER_21, + RTL_GIGA_MAC_VER_22, + RTL_GIGA_MAC_VER_23, + RTL_GIGA_MAC_VER_24, + RTL_GIGA_MAC_VER_25, + RTL_GIGA_MAC_VER_26, + RTL_GIGA_MAC_VER_27, + RTL_GIGA_MAC_VER_28, + RTL_GIGA_MAC_VER_29, + RTL_GIGA_MAC_VER_30, + RTL_GIGA_MAC_VER_31, + RTL_GIGA_MAC_VER_32, + RTL_GIGA_MAC_VER_33, + RTL_GIGA_MAC_VER_34, + RTL_GIGA_MAC_NONE = 0xff, }; -#define _R(NAME,MAC,MASK) \ - { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } +enum rtl_tx_desc_version { + RTL_TD_0 = 0, + RTL_TD_1 = 1, +}; + +#define _R(NAME,TD,FW) \ + { .name = NAME, .txd_version = TD, .fw_name = FW } static const struct { const char *name; - u8 mac_version; - u32 RxConfigMask; /* Clears the bits supported by this chip */ -} rtl_chip_info[] = { - _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169 - _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S - _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S - _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB - _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd - _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe - _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E - _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E - _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E - _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E - _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E - _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E - _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 - _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 - _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139 - _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E - _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E - _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E - _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E - _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880), // PCI-E - _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, 0xff7e1880), // PCI-E - _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E - _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E - _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E - _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E - _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E - _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E - _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880), // PCI-E - _R("RTL8105e", RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E - _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880) // PCI-E + enum rtl_tx_desc_version txd_version; + const char *fw_name; +} rtl_chip_infos[] = { + /* PCI devices. */ + [RTL_GIGA_MAC_VER_01] = + _R("RTL8169", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_02] = + _R("RTL8169s", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_03] = + _R("RTL8110s", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_04] = + _R("RTL8169sb/8110sb", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_05] = + _R("RTL8169sc/8110sc", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_06] = + _R("RTL8169sc/8110sc", RTL_TD_0, NULL), + /* PCI-E devices. */ + [RTL_GIGA_MAC_VER_07] = + _R("RTL8102e", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_08] = + _R("RTL8102e", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_09] = + _R("RTL8102e", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_10] = + _R("RTL8101e", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_11] = + _R("RTL8168b/8111b", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_12] = + _R("RTL8168b/8111b", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_13] = + _R("RTL8101e", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_14] = + _R("RTL8100e", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_15] = + _R("RTL8100e", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_16] = + _R("RTL8101e", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_17] = + _R("RTL8168b/8111b", RTL_TD_0, NULL), + [RTL_GIGA_MAC_VER_18] = + _R("RTL8168cp/8111cp", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_19] = + _R("RTL8168c/8111c", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_20] = + _R("RTL8168c/8111c", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_21] = + _R("RTL8168c/8111c", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_22] = + _R("RTL8168c/8111c", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_23] = + _R("RTL8168cp/8111cp", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_24] = + _R("RTL8168cp/8111cp", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_25] = + _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1), + [RTL_GIGA_MAC_VER_26] = + _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2), + [RTL_GIGA_MAC_VER_27] = + _R("RTL8168dp/8111dp", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_28] = + _R("RTL8168dp/8111dp", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_29] = + _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1), + [RTL_GIGA_MAC_VER_30] = + _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1), + [RTL_GIGA_MAC_VER_31] = + _R("RTL8168dp/8111dp", RTL_TD_1, NULL), + [RTL_GIGA_MAC_VER_32] = + _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1), + [RTL_GIGA_MAC_VER_33] = + _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2), + [RTL_GIGA_MAC_VER_34] = + _R("RTL8168evl/8111evl",RTL_TD_1, FIRMWARE_8168E_3) }; #undef _R @@ -220,8 +272,21 @@ enum rtl_registers { TxPoll = 0x38, IntrMask = 0x3c, IntrStatus = 0x3e, + TxConfig = 0x40, +#define TXCFG_AUTO_FIFO (1 << 7) /* 8111e-vl */ +#define TXCFG_EMPTY (1 << 11) /* 8111e-vl */ + RxConfig = 0x44, +#define RX128_INT_EN (1 << 15) /* 8111c and later */ +#define RX_MULTI_EN (1 << 14) /* 8111c only */ +#define RXCFG_FIFO_SHIFT 13 + /* No threshold before first PCI xfer */ +#define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) +#define RXCFG_DMA_SHIFT 8 + /* Unlimited maximum PCI burst. */ +#define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) + RxMissed = 0x4c, Cfg9346 = 0x50, Config0 = 0x51, @@ -274,12 +339,13 @@ enum rtl8168_8101_registers { #define EPHYAR_REG_SHIFT 16 #define EPHYAR_DATA_MASK 0xffff DLLPR = 0xd0, -#define PM_SWITCH (1 << 6) +#define PFM_EN (1 << 6) DBG_REG = 0xd1, #define FIX_NAK_1 (1 << 4) #define FIX_NAK_2 (1 << 3) TWSI = 0xd2, MCU = 0xd3, +#define NOW_IS_OOB (1 << 7) #define EN_NDP (1 << 3) #define EN_OOB_RESET (1 << 2) EFUSEAR = 0xdc, @@ -292,18 +358,22 @@ enum rtl8168_8101_registers { }; enum rtl8168_registers { + LED_FREQ = 0x1a, + EEE_LED = 0x1b, ERIDR = 0x70, ERIAR = 0x74, #define ERIAR_FLAG 0x80000000 #define ERIAR_WRITE_CMD 0x80000000 #define ERIAR_READ_CMD 0x00000000 #define ERIAR_ADDR_BYTE_ALIGN 4 -#define ERIAR_EXGMAC 0 -#define ERIAR_MSIX 1 -#define ERIAR_ASF 2 #define ERIAR_TYPE_SHIFT 16 -#define ERIAR_BYTEEN 0x0f -#define ERIAR_BYTEEN_SHIFT 12 +#define ERIAR_EXGMAC (0x00 << ERIAR_TYPE_SHIFT) +#define ERIAR_MSIX (0x01 << ERIAR_TYPE_SHIFT) +#define ERIAR_ASF (0x02 << ERIAR_TYPE_SHIFT) +#define ERIAR_MASK_SHIFT 12 +#define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) +#define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) +#define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) EPHY_RXER_NUM = 0x7c, OCPDR = 0xb0, /* OCP GPHY access */ #define OCPDR_WRITE_CMD 0x80000000 @@ -315,7 +385,10 @@ enum rtl8168_registers { #define OCPAR_FLAG 0x80000000 #define OCPAR_GPHY_WRITE_CMD 0x8000f060 #define OCPAR_GPHY_READ_CMD 0x0000f060 - RDSAR1 = 0xd0 /* 8168c only. Undocumented on 8168dp */ + RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ + MISC = 0xf0, /* 8168e only. */ +#define TXPLA_RST (1 << 29) +#define PWM_EN (1 << 22) }; enum rtl_register_content { @@ -340,6 +413,7 @@ enum rtl_register_content { RxCRC = (1 << 19), /* ChipCmdBits */ + StopReq = 0x80, CmdReset = 0x10, CmdRxEnb = 0x08, CmdTxEnb = 0x04, @@ -361,10 +435,7 @@ enum rtl_register_content { AcceptMulticast = 0x04, AcceptMyPhys = 0x02, AcceptAllPhys = 0x01, - - /* RxConfigBits */ - RxCfgFIFOShift = 13, - RxCfgDMAShift = 8, +#define RX_CONFIG_ACCEPT_MASK 0x3f /* TxConfigBits */ TxInterFrameGapShift = 24, @@ -393,6 +464,7 @@ enum rtl_register_content { BWF = (1 << 6), /* Accept Broadcast wakeup frame */ MWF = (1 << 5), /* Accept Multicast wakeup frame */ UWF = (1 << 4), /* Accept Unicast wakeup frame */ + Spi_en = (1 << 3), LanWake = (1 << 1), /* LanWake enable/disable */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ @@ -441,21 +513,69 @@ enum rtl_register_content { CounterDump = 0x8, }; -enum desc_status_bit { +enum rtl_desc_bit { + /* First doubleword. */ DescOwn = (1 << 31), /* Descriptor is owned by NIC */ RingEnd = (1 << 30), /* End of descriptor ring */ FirstFrag = (1 << 29), /* First segment of a packet */ LastFrag = (1 << 28), /* Final segment of a packet */ +}; + +/* Generic case. */ +enum rtl_tx_desc_bit { + /* First doubleword. */ + TD_LSO = (1 << 27), /* Large Send Offload */ +#define TD_MSS_MAX 0x07ffu /* MSS value */ + + /* Second doubleword. */ + TxVlanTag = (1 << 17), /* Add VLAN tag */ +}; - /* Tx private */ - LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ - MSSShift = 16, /* MSS value position */ - MSSMask = 0xfff, /* MSS value + LargeSend bit: 12 bits */ - IPCS = (1 << 18), /* Calculate IP checksum */ - UDPCS = (1 << 17), /* Calculate UDP/IP checksum */ - TCPCS = (1 << 16), /* Calculate TCP/IP checksum */ - TxVlanTag = (1 << 17), /* Add VLAN tag */ +/* 8169, 8168b and 810x except 8102e. */ +enum rtl_tx_desc_bit_0 { + /* First doubleword. */ +#define TD0_MSS_SHIFT 16 /* MSS position (11 bits) */ + TD0_TCP_CS = (1 << 16), /* Calculate TCP/IP checksum */ + TD0_UDP_CS = (1 << 17), /* Calculate UDP/IP checksum */ + TD0_IP_CS = (1 << 18), /* Calculate IP checksum */ +}; +/* 8102e, 8168c and beyond. */ +enum rtl_tx_desc_bit_1 { + /* Second doubleword. */ +#define TD1_MSS_SHIFT 18 /* MSS position (11 bits) */ + TD1_IP_CS = (1 << 29), /* Calculate IP checksum */ + TD1_TCP_CS = (1 << 30), /* Calculate TCP/IP checksum */ + TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */ +}; + +static const struct rtl_tx_desc_info { + struct { + u32 udp; + u32 tcp; + } checksum; + u16 mss_shift; + u16 opts_offset; +} tx_desc_info [] = { + [RTL_TD_0] = { + .checksum = { + .udp = TD0_IP_CS | TD0_UDP_CS, + .tcp = TD0_IP_CS | TD0_TCP_CS + }, + .mss_shift = TD0_MSS_SHIFT, + .opts_offset = 0 + }, + [RTL_TD_1] = { + .checksum = { + .udp = TD1_IP_CS | TD1_UDP_CS, + .tcp = TD1_IP_CS | TD1_TCP_CS + }, + .mss_shift = TD1_MSS_SHIFT, + .opts_offset = 1 + } +}; + +enum rtl_rx_desc_bit { /* Rx private */ PID1 = (1 << 18), /* Protocol ID bit 1/2 */ PID0 = (1 << 17), /* Protocol ID bit 2/2 */ @@ -515,13 +635,13 @@ struct rtl8169_counters { struct rtl8169_private { void __iomem *mmio_addr; /* memory map physical address */ - struct pci_dev *pci_dev; /* Index of PCI device */ + struct pci_dev *pci_dev; struct net_device *dev; struct napi_struct napi; - spinlock_t lock; /* spin lock flag */ + spinlock_t lock; u32 msg_enable; - int chipset; - int mac_version; + u16 txd_version; + u16 mac_version; u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ u32 dirty_rx; @@ -537,7 +657,6 @@ struct rtl8169_private { u16 intr_event; u16 napi_event; u16 intr_mask; - int phy_1000_ctrl_reg; struct mdio_ops { void (*write)(void __iomem *, int, int); @@ -556,7 +675,6 @@ struct rtl8169_private { unsigned int (*phy_reset_pending)(struct rtl8169_private *tp); unsigned int (*link_ok)(void __iomem *); int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); - int pcie_cap; struct delayed_work task; unsigned features; @@ -564,7 +682,19 @@ struct rtl8169_private { struct rtl8169_counters counters; u32 saved_wolopts; - const struct firmware *fw; + struct rtl_fw { + const struct firmware *fw; + +#define RTL_VER_SIZE 32 + + char version[RTL_VER_SIZE]; + + struct rtl_fw_phy_action { + __le32 *code; + size_t size; + } phy_action; + } *rtl_fw; +#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN) }; MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); @@ -577,6 +707,8 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(RTL8169_VERSION); MODULE_FIRMWARE(FIRMWARE_8168D_1); MODULE_FIRMWARE(FIRMWARE_8168D_2); +MODULE_FIRMWARE(FIRMWARE_8168E_1); +MODULE_FIRMWARE(FIRMWARE_8168E_2); MODULE_FIRMWARE(FIRMWARE_8105E_1); static int rtl8169_open(struct net_device *dev); @@ -596,9 +728,6 @@ static void rtl8169_down(struct net_device *dev); static void rtl8169_rx_clear(struct rtl8169_private *tp); static int rtl8169_poll(struct napi_struct *napi, int budget); -static const unsigned int rtl8169_rx_config = - (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); - static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) { void __iomem *ioaddr = tp->mmio_addr; @@ -637,7 +766,7 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd) msleep(2); for (i = 0; i < 5; i++) { udelay(100); - if (!(RTL_R32(ERIDR) & ERIAR_FLAG)) + if (!(RTL_R32(ERIAR) & ERIAR_FLAG)) break; } @@ -648,32 +777,49 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd) #define OOB_CMD_DRIVER_START 0x05 #define OOB_CMD_DRIVER_STOP 0x06 +static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp) +{ + return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10; +} + static void rtl8168_driver_start(struct rtl8169_private *tp) { + u16 reg; int i; rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START); + reg = rtl8168_get_ocp_reg(tp); + for (i = 0; i < 10; i++) { msleep(10); - if (ocp_read(tp, 0x0f, 0x0010) & 0x00000800) + if (ocp_read(tp, 0x0f, reg) & 0x00000800) break; } } static void rtl8168_driver_stop(struct rtl8169_private *tp) { + u16 reg; int i; rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP); + reg = rtl8168_get_ocp_reg(tp); + for (i = 0; i < 10; i++) { msleep(10); - if ((ocp_read(tp, 0x0f, 0x0010) & 0x00000800) == 0) + if ((ocp_read(tp, 0x0f, reg) & 0x00000800) == 0) break; } } +static int r8168dp_check_dash(struct rtl8169_private *tp) +{ + u16 reg = rtl8168_get_ocp_reg(tp); + + return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; +} static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) { @@ -902,6 +1048,49 @@ static u32 rtl_csi_read(void __iomem *ioaddr, int addr) return value; } +static +void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type) +{ + unsigned int i; + + BUG_ON((addr & 3) || (mask == 0)); + RTL_W32(ERIDR, val); + RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr); + + for (i = 0; i < 100; i++) { + if (!(RTL_R32(ERIAR) & ERIAR_FLAG)) + break; + udelay(100); + } +} + +static u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type) +{ + u32 value = ~0x00; + unsigned int i; + + RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr); + + for (i = 0; i < 100; i++) { + if (RTL_R32(ERIAR) & ERIAR_FLAG) { + value = RTL_R32(ERIDR); + break; + } + udelay(100); + } + + return value; +} + +static void +rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type) +{ + u32 val; + + val = rtl_eri_read(ioaddr, addr, type); + rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type); +} + static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) { u8 value = 0xff; @@ -927,13 +1116,6 @@ static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) RTL_W16(IntrStatus, 0xffff); } -static void rtl8169_asic_down(void __iomem *ioaddr) -{ - RTL_W8(ChipCmd, 0x00); - rtl8169_irq_mask_and_ack(ioaddr); - RTL_R16(CPlusCmd); -} - static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -971,15 +1153,48 @@ static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp) rtl_writephy(tp, MII_BMCR, val & 0xffff); } +static void rtl_link_chg_patch(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + struct net_device *dev = tp->dev; + + if (!netif_running(dev)) + return; + + if (tp->mac_version == RTL_GIGA_MAC_VER_34) { + if (RTL_R8(PHYstatus) & _1000bpsF) { + rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, + 0x00000011, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, + 0x00000005, ERIAR_EXGMAC); + } else if (RTL_R8(PHYstatus) & _100bps) { + rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, + 0x0000001f, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, + 0x00000005, ERIAR_EXGMAC); + } else { + rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, + 0x0000001f, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, + 0x0000003f, ERIAR_EXGMAC); + } + /* Reset packet filter */ + rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, + ERIAR_EXGMAC); + rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, + ERIAR_EXGMAC); + } +} + static void __rtl8169_check_link_status(struct net_device *dev, - struct rtl8169_private *tp, - void __iomem *ioaddr, - bool pm) + struct rtl8169_private *tp, + void __iomem *ioaddr, bool pm) { unsigned long flags; spin_lock_irqsave(&tp->lock, flags); if (tp->link_ok(ioaddr)) { + rtl_link_chg_patch(tp); /* This is to cancel a scheduled suspend if there's one. */ if (pm) pm_request_resume(&tp->pci_dev->dev); @@ -1091,14 +1306,23 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) return 0; } +static const char *rtl_lookup_firmware_name(struct rtl8169_private *tp) +{ + return rtl_chip_infos[tp->mac_version].fw_name; +} + static void rtl8169_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct rtl8169_private *tp = netdev_priv(dev); + struct rtl_fw *rtl_fw = tp->rtl_fw; strcpy(info->driver, MODULENAME); strcpy(info->version, RTL8169_VERSION); strcpy(info->bus_info, pci_name(tp->pci_dev)); + BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); + strcpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" : + rtl_fw->version); } static int rtl8169_get_regs_len(struct net_device *dev) @@ -1160,16 +1384,7 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); /* The 8100e/8101e/8102e do Fast Ethernet only. */ - if ((tp->mac_version != RTL_GIGA_MAC_VER_07) && - (tp->mac_version != RTL_GIGA_MAC_VER_08) && - (tp->mac_version != RTL_GIGA_MAC_VER_09) && - (tp->mac_version != RTL_GIGA_MAC_VER_10) && - (tp->mac_version != RTL_GIGA_MAC_VER_13) && - (tp->mac_version != RTL_GIGA_MAC_VER_14) && - (tp->mac_version != RTL_GIGA_MAC_VER_15) && - (tp->mac_version != RTL_GIGA_MAC_VER_16) && - (tp->mac_version != RTL_GIGA_MAC_VER_29) && - (tp->mac_version != RTL_GIGA_MAC_VER_30)) { + if (tp->mii.supports_gmii) { if (adv & ADVERTISED_1000baseT_Half) giga_ctrl |= ADVERTISE_1000HALF; if (adv & ADVERTISED_1000baseT_Full) @@ -1199,12 +1414,10 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, bmcr |= BMCR_FULLDPLX; } - tp->phy_1000_ctrl_reg = giga_ctrl; - rtl_writephy(tp, MII_BMCR, bmcr); - if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || - (tp->mac_version == RTL_GIGA_MAC_VER_03)) { + if (tp->mac_version == RTL_GIGA_MAC_VER_02 || + tp->mac_version == RTL_GIGA_MAC_VER_03) { if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) { rtl_writephy(tp, 0x17, 0x2138); rtl_writephy(tp, 0x0e, 0x0260); @@ -1226,10 +1439,14 @@ static int rtl8169_set_speed(struct net_device *dev, int ret; ret = tp->set_speed(dev, autoneg, speed, duplex, advertising); + if (ret < 0) + goto out; - if (netif_running(dev) && (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)) + if (netif_running(dev) && (autoneg == AUTONEG_ENABLE) && + (advertising & ADVERTISED_1000baseT_Full)) { mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT); - + } +out: return ret; } @@ -1239,22 +1456,25 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) unsigned long flags; int ret; + del_timer_sync(&tp->timer); + spin_lock_irqsave(&tp->lock, flags); - ret = rtl8169_set_speed(dev, - cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising); + ret = rtl8169_set_speed(dev, cmd->autoneg, ethtool_cmd_speed(cmd), + cmd->duplex, cmd->advertising); spin_unlock_irqrestore(&tp->lock, flags); return ret; } -static u32 rtl8169_get_rx_csum(struct net_device *dev) +static u32 rtl8169_fix_features(struct net_device *dev, u32 features) { - struct rtl8169_private *tp = netdev_priv(dev); + if (dev->mtu > TD_MSS_MAX) + features &= ~NETIF_F_ALL_TSO; - return tp->cp_cmd & RxChkSum; + return features; } -static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) +static int rtl8169_set_features(struct net_device *dev, u32 features) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; @@ -1262,11 +1482,16 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) spin_lock_irqsave(&tp->lock, flags); - if (data) + if (features & NETIF_F_RXCSUM) tp->cp_cmd |= RxChkSum; else tp->cp_cmd &= ~RxChkSum; + if (dev->features & NETIF_F_HW_VLAN_RX) + tp->cp_cmd |= RxVlan; + else + tp->cp_cmd &= ~RxVlan; + RTL_W16(CPlusCmd, tp->cp_cmd); RTL_R16(CPlusCmd); @@ -1282,27 +1507,6 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; } -#define NETIF_F_HW_VLAN_TX_RX (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX) - -static void rtl8169_vlan_mode(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; - - spin_lock_irqsave(&tp->lock, flags); - if (dev->features & NETIF_F_HW_VLAN_RX) - tp->cp_cmd |= RxVlan; - else - tp->cp_cmd &= ~RxVlan; - RTL_W16(CPlusCmd, tp->cp_cmd); - /* PCI commit */ - RTL_R16(CPlusCmd); - spin_unlock_irqrestore(&tp->lock, flags); - - dev->vlan_features = dev->features &~ NETIF_F_HW_VLAN_TX_RX; -} - static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) { u32 opts2 = le32_to_cpu(desc->opts2); @@ -1328,7 +1532,7 @@ static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) cmd->advertising = (status & TBINwEnable) ? ADVERTISED_Autoneg : 0; cmd->autoneg = !!(status & TBINwEnable); - cmd->speed = SPEED_1000; + ethtool_cmd_speed_set(cmd, SPEED_1000); cmd->duplex = DUPLEX_FULL; /* Always set */ return 0; @@ -1413,11 +1617,11 @@ static void rtl8169_update_counters(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; + struct device *d = &tp->pci_dev->dev; struct rtl8169_counters *counters; dma_addr_t paddr; u32 cmd; int wait = 1000; - struct device *d = &tp->pci_dev->dev; /* * Some chips are unable to dump tally counters when the receiver @@ -1437,7 +1641,6 @@ static void rtl8169_update_counters(struct net_device *dev) while (wait--) { if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) { - /* copy updated counters */ memcpy(&tp->counters, counters, sizeof(*counters)); break; } @@ -1483,28 +1686,6 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) } } -static int rtl8169_set_flags(struct net_device *dev, u32 data) -{ - struct rtl8169_private *tp = netdev_priv(dev); - unsigned long old_feat = dev->features; - int rc; - - if ((tp->mac_version == RTL_GIGA_MAC_VER_05) && - !(data & ETH_FLAG_RXVLAN)) { - netif_info(tp, drv, dev, "8110SCd requires hardware Rx VLAN\n"); - return -EINVAL; - } - - rc = ethtool_op_set_flags(dev, data, ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN); - if (rc) - return rc; - - if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) - rtl8169_vlan_mode(dev); - - return 0; -} - static const struct ethtool_ops rtl8169_ethtool_ops = { .get_drvinfo = rtl8169_get_drvinfo, .get_regs_len = rtl8169_get_regs_len, @@ -1513,24 +1694,18 @@ static const struct ethtool_ops rtl8169_ethtool_ops = { .set_settings = rtl8169_set_settings, .get_msglevel = rtl8169_get_msglevel, .set_msglevel = rtl8169_set_msglevel, - .get_rx_csum = rtl8169_get_rx_csum, - .set_rx_csum = rtl8169_set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = ethtool_op_set_tso, .get_regs = rtl8169_get_regs, .get_wol = rtl8169_get_wol, .set_wol = rtl8169_set_wol, .get_strings = rtl8169_get_strings, .get_sset_count = rtl8169_get_sset_count, .get_ethtool_stats = rtl8169_get_ethtool_stats, - .set_flags = rtl8169_set_flags, - .get_flags = ethtool_op_get_flags, }; static void rtl8169_get_mac_version(struct rtl8169_private *tp, - void __iomem *ioaddr) + struct net_device *dev, u8 default_version) { + void __iomem *ioaddr = tp->mmio_addr; /* * The driver currently handles the 8168Bf and the 8168Be identically * but they can be identified more specifically through the test below @@ -1542,11 +1717,17 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, * * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec */ - static const struct { + static const struct rtl_mac_info { u32 mask; u32 val; int mac_version; } mac_info[] = { + /* 8168E family. */ + { 0x7c800000, 0x2c800000, RTL_GIGA_MAC_VER_34 }, + { 0x7cf00000, 0x2c200000, RTL_GIGA_MAC_VER_33 }, + { 0x7cf00000, 0x2c100000, RTL_GIGA_MAC_VER_32 }, + { 0x7c800000, 0x2c000000, RTL_GIGA_MAC_VER_33 }, + /* 8168D family. */ { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 }, { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 }, @@ -1555,6 +1736,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, /* 8168DP family. */ { 0x7cf00000, 0x28800000, RTL_GIGA_MAC_VER_27 }, { 0x7cf00000, 0x28a00000, RTL_GIGA_MAC_VER_28 }, + { 0x7cf00000, 0x28b00000, RTL_GIGA_MAC_VER_31 }, /* 8168C family. */ { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 }, @@ -1574,6 +1756,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, /* 8101 family. */ + { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x40900000, RTL_GIGA_MAC_VER_29 }, { 0x7c800000, 0x40800000, RTL_GIGA_MAC_VER_30 }, @@ -1603,13 +1786,20 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, /* Catch-all */ { 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE } - }, *p = mac_info; + }; + const struct rtl_mac_info *p = mac_info; u32 reg; reg = RTL_R32(TxConfig); while ((reg & p->mask) != p->val) p++; tp->mac_version = p->mac_version; + + if (tp->mac_version == RTL_GIGA_MAC_NONE) { + netif_notice(tp, probe, dev, + "unknown MAC, using family default\n"); + tp->mac_version = default_version; + } } static void rtl8169_print_mac_version(struct rtl8169_private *tp) @@ -1648,21 +1838,75 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_DELAY_MS 0xe0000000 #define PHY_WRITE_ERI_WORD 0xf0000000 -static void -rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) +struct fw_info { + u32 magic; + char version[RTL_VER_SIZE]; + __le32 fw_start; + __le32 fw_len; + u8 chksum; +} __packed; + +#define FW_OPCODE_SIZE sizeof(typeof(*((struct rtl_fw_phy_action *)0)->code)) + +static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) { - __le32 *phytable = (__le32 *)fw->data; - struct net_device *dev = tp->dev; - size_t index, fw_size = fw->size / sizeof(*phytable); - u32 predata, count; + const struct firmware *fw = rtl_fw->fw; + struct fw_info *fw_info = (struct fw_info *)fw->data; + struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; + char *version = rtl_fw->version; + bool rc = false; - if (fw->size % sizeof(*phytable)) { - netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size); - return; + if (fw->size < FW_OPCODE_SIZE) + goto out; + + if (!fw_info->magic) { + size_t i, size, start; + u8 checksum = 0; + + if (fw->size < sizeof(*fw_info)) + goto out; + + for (i = 0; i < fw->size; i++) + checksum += fw->data[i]; + if (checksum != 0) + goto out; + + start = le32_to_cpu(fw_info->fw_start); + if (start > fw->size) + goto out; + + size = le32_to_cpu(fw_info->fw_len); + if (size > (fw->size - start) / FW_OPCODE_SIZE) + goto out; + + memcpy(version, fw_info->version, RTL_VER_SIZE); + + pa->code = (__le32 *)(fw->data + start); + pa->size = size; + } else { + if (fw->size % FW_OPCODE_SIZE) + goto out; + + strlcpy(version, rtl_lookup_firmware_name(tp), RTL_VER_SIZE); + + pa->code = (__le32 *)fw->data; + pa->size = fw->size / FW_OPCODE_SIZE; } + version[RTL_VER_SIZE - 1] = 0; - for (index = 0; index < fw_size; index++) { - u32 action = le32_to_cpu(phytable[index]); + rc = true; +out: + return rc; +} + +static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, + struct rtl_fw_phy_action *pa) +{ + bool rc = false; + size_t index; + + for (index = 0; index < pa->size; index++) { + u32 action = le32_to_cpu(pa->code[index]); u32 regno = (action & 0x0fff0000) >> 16; switch(action & 0xf0000000) { @@ -1678,25 +1922,25 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) case PHY_BJMPN: if (regno > index) { - netif_err(tp, probe, tp->dev, - "Out of range of firmware\n"); - return; + netif_err(tp, ifup, tp->dev, + "Out of range of firmware\n"); + goto out; } break; case PHY_READCOUNT_EQ_SKIP: - if (index + 2 >= fw_size) { - netif_err(tp, probe, tp->dev, - "Out of range of firmware\n"); - return; + if (index + 2 >= pa->size) { + netif_err(tp, ifup, tp->dev, + "Out of range of firmware\n"); + goto out; } break; case PHY_COMP_EQ_SKIPN: case PHY_COMP_NEQ_SKIPN: case PHY_SKIPN: - if (index + 1 + regno >= fw_size) { - netif_err(tp, probe, tp->dev, - "Out of range of firmware\n"); - return; + if (index + 1 + regno >= pa->size) { + netif_err(tp, ifup, tp->dev, + "Out of range of firmware\n"); + goto out; } break; @@ -1704,17 +1948,42 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) case PHY_WRITE_MAC_BYTE: case PHY_WRITE_ERI_WORD: default: - netif_err(tp, probe, tp->dev, + netif_err(tp, ifup, tp->dev, "Invalid action 0x%08x\n", action); - return; + goto out; } } + rc = true; +out: + return rc; +} - predata = 0; - count = 0; +static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +{ + struct net_device *dev = tp->dev; + int rc = -EINVAL; + + if (!rtl_fw_format_ok(tp, rtl_fw)) { + netif_err(tp, ifup, dev, "invalid firwmare\n"); + goto out; + } - for (index = 0; index < fw_size; ) { - u32 action = le32_to_cpu(phytable[index]); + if (rtl_fw_data_ok(tp, dev, &rtl_fw->phy_action)) + rc = 0; +out: + return rc; +} + +static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +{ + struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; + u32 predata, count; + size_t index; + + predata = count = 0; + + for (index = 0; index < pa->size; ) { + u32 action = le32_to_cpu(pa->code[index]); u32 data = action & 0x0000ffff; u32 regno = (action & 0x0fff0000) >> 16; @@ -1751,10 +2020,7 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) index++; break; case PHY_READCOUNT_EQ_SKIP: - if (count == data) - index += 2; - else - index += 1; + index += (count == data) ? 2 : 1; break; case PHY_COMP_EQ_SKIPN: if (predata == data) @@ -1789,25 +2055,28 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) static void rtl_release_firmware(struct rtl8169_private *tp) { - release_firmware(tp->fw); - tp->fw = NULL; + if (!IS_ERR_OR_NULL(tp->rtl_fw)) { + release_firmware(tp->rtl_fw->fw); + kfree(tp->rtl_fw); + } + tp->rtl_fw = RTL_FIRMWARE_UNKNOWN; } -static int rtl_apply_firmware(struct rtl8169_private *tp, const char *fw_name) +static void rtl_apply_firmware(struct rtl8169_private *tp) { - const struct firmware **fw = &tp->fw; - int rc = !*fw; - - if (rc) { - rc = request_firmware(fw, fw_name, &tp->pci_dev->dev); - if (rc < 0) - goto out; - } + struct rtl_fw *rtl_fw = tp->rtl_fw; /* TODO: release firmware once rtl_phy_write_fw signals failures. */ - rtl_phy_write_fw(tp, *fw); -out: - return rc; + if (!IS_ERR_OR_NULL(rtl_fw)) + rtl_phy_write_fw(tp, rtl_fw); +} + +static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) +{ + if (rtl_readphy(tp, reg) != val) + netif_warn(tp, hw, tp->dev, "chipset not ready for firmware\n"); + else + rtl_apply_firmware(tp); } static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) @@ -1891,12 +2160,9 @@ static void rtl8169sb_hw_phy_config(struct rtl8169_private *tp) static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp) { struct pci_dev *pdev = tp->pci_dev; - u16 vendor_id, device_id; - pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &vendor_id); - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &device_id); - - if ((vendor_id != PCI_VENDOR_ID_GIGABYTE) || (device_id != 0xe000)) + if ((pdev->subsystem_vendor != PCI_VENDOR_ID_GIGABYTE) || + (pdev->subsystem_device != 0xe000)) return; rtl_writephy(tp, 0x1f, 0x0001); @@ -2164,7 +2430,7 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) /* * Tx Error Issue - * enhance line driver power + * Enhance line driver power */ { 0x1f, 0x0002 }, { 0x06, 0x5561 }, @@ -2246,10 +2512,8 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0005); rtl_writephy(tp, 0x05, 0x001b); - if ((rtl_readphy(tp, 0x06) != 0xbf00) || - (rtl_apply_firmware(tp, FIRMWARE_8168D_1) < 0)) { - netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); - } + + rtl_apply_firmware_cond(tp, MII_EXPANSION, 0xbf00); rtl_writephy(tp, 0x1f, 0x0000); } @@ -2278,7 +2542,7 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) /* * Tx Error Issue - * enhance line driver power + * Enhance line driver power */ { 0x1f, 0x0002 }, { 0x06, 0x5561 }, @@ -2351,10 +2615,8 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0005); rtl_writephy(tp, 0x05, 0x001b); - if ((rtl_readphy(tp, 0x06) != 0xb300) || - (rtl_apply_firmware(tp, FIRMWARE_8168D_2) < 0)) { - netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); - } + + rtl_apply_firmware_cond(tp, MII_EXPANSION, 0xb300); rtl_writephy(tp, 0x1f, 0x0000); } @@ -2436,6 +2698,164 @@ static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp) rtl_patchphy(tp, 0x0d, 1 << 5); } +static void rtl8168e_1_hw_phy_config(struct rtl8169_private *tp) +{ + static const struct phy_reg phy_reg_init[] = { + /* Enable Delay cap */ + { 0x1f, 0x0005 }, + { 0x05, 0x8b80 }, + { 0x06, 0xc896 }, + { 0x1f, 0x0000 }, + + /* Channel estimation fine tune */ + { 0x1f, 0x0001 }, + { 0x0b, 0x6c20 }, + { 0x07, 0x2872 }, + { 0x1c, 0xefff }, + { 0x1f, 0x0003 }, + { 0x14, 0x6420 }, + { 0x1f, 0x0000 }, + + /* Update PFM & 10M TX idle timer */ + { 0x1f, 0x0007 }, + { 0x1e, 0x002f }, + { 0x15, 0x1919 }, + { 0x1f, 0x0000 }, + + { 0x1f, 0x0007 }, + { 0x1e, 0x00ac }, + { 0x18, 0x0006 }, + { 0x1f, 0x0000 } + }; + + rtl_apply_firmware(tp); + + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + /* DCO enable for 10M IDLE Power */ + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x0023); + rtl_w1w0_phy(tp, 0x17, 0x0006, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + /* For impedance matching */ + rtl_writephy(tp, 0x1f, 0x0002); + rtl_w1w0_phy(tp, 0x08, 0x8000, 0x7f00); + rtl_writephy(tp, 0x1f, 0x0000); + + /* PHY auto speed down */ + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x002d); + rtl_w1w0_phy(tp, 0x18, 0x0050, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_w1w0_phy(tp, 0x14, 0x8000, 0x0000); + + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b86); + rtl_w1w0_phy(tp, 0x06, 0x0001, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b85); + rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000); + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x0020); + rtl_w1w0_phy(tp, 0x15, 0x0000, 0x1100); + rtl_writephy(tp, 0x1f, 0x0006); + rtl_writephy(tp, 0x00, 0x5a00); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x0d, 0x0007); + rtl_writephy(tp, 0x0e, 0x003c); + rtl_writephy(tp, 0x0d, 0x4007); + rtl_writephy(tp, 0x0e, 0x0000); + rtl_writephy(tp, 0x0d, 0x0000); +} + +static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) +{ + static const struct phy_reg phy_reg_init[] = { + /* Enable Delay cap */ + { 0x1f, 0x0004 }, + { 0x1f, 0x0007 }, + { 0x1e, 0x00ac }, + { 0x18, 0x0006 }, + { 0x1f, 0x0002 }, + { 0x1f, 0x0000 }, + { 0x1f, 0x0000 }, + + /* Channel estimation fine tune */ + { 0x1f, 0x0003 }, + { 0x09, 0xa20f }, + { 0x1f, 0x0000 }, + { 0x1f, 0x0000 }, + + /* Green Setting */ + { 0x1f, 0x0005 }, + { 0x05, 0x8b5b }, + { 0x06, 0x9222 }, + { 0x05, 0x8b6d }, + { 0x06, 0x8000 }, + { 0x05, 0x8b76 }, + { 0x06, 0x8000 }, + { 0x1f, 0x0000 } + }; + + rtl_apply_firmware(tp); + + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + /* For 4-corner performance improve */ + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b80); + rtl_w1w0_phy(tp, 0x17, 0x0006, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + /* PHY auto speed down */ + rtl_writephy(tp, 0x1f, 0x0004); + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x002d); + rtl_w1w0_phy(tp, 0x18, 0x0010, 0x0000); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_w1w0_phy(tp, 0x14, 0x8000, 0x0000); + + /* improve 10M EEE waveform */ + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b86); + rtl_w1w0_phy(tp, 0x06, 0x0001, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + /* Improve 2-pair detection performance */ + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b85); + rtl_w1w0_phy(tp, 0x06, 0x4000, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + /* EEE setting */ + rtl_w1w0_eri(tp->mmio_addr, 0x1b0, ERIAR_MASK_1111, 0x0000, 0x0003, + ERIAR_EXGMAC); + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b85); + rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000); + rtl_writephy(tp, 0x1f, 0x0004); + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x0020); + rtl_w1w0_phy(tp, 0x06, 0x0000, 0x0100); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x0d, 0x0007); + rtl_writephy(tp, 0x0e, 0x003c); + rtl_writephy(tp, 0x0d, 0x4007); + rtl_writephy(tp, 0x0e, 0x0000); + rtl_writephy(tp, 0x0d, 0x0000); + + /* Green feature */ + rtl_writephy(tp, 0x1f, 0x0003); + rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001); + rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400); + rtl_writephy(tp, 0x1f, 0x0000); +} + static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -2474,8 +2894,7 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x18, 0x0310); msleep(100); - if (rtl_apply_firmware(tp, FIRMWARE_8105E_1) < 0) - netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); + rtl_apply_firmware(tp); rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } @@ -2551,6 +2970,16 @@ static void rtl_hw_phy_config(struct net_device *dev) case RTL_GIGA_MAC_VER_30: rtl8105e_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_31: + /* None. */ + break; + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: + rtl8168e_1_hw_phy_config(tp); + break; + case RTL_GIGA_MAC_VER_34: + rtl8168e_2_hw_phy_config(tp); + break; default: break; @@ -2567,9 +2996,6 @@ static void rtl8169_phy_timer(unsigned long __opaque) assert(tp->mac_version > RTL_GIGA_MAC_VER_01); - if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)) - return; - spin_lock_irq(&tp->lock); if (tp->phy_reset_pending(tp)) { @@ -2594,28 +3020,6 @@ out_unlock: spin_unlock_irq(&tp->lock); } -static inline void rtl8169_delete_timer(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct timer_list *timer = &tp->timer; - - if (tp->mac_version <= RTL_GIGA_MAC_VER_01) - return; - - del_timer_sync(timer); -} - -static inline void rtl8169_request_timer(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct timer_list *timer = &tp->timer; - - if (tp->mac_version <= RTL_GIGA_MAC_VER_01) - return; - - mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT); -} - #ifdef CONFIG_NET_POLL_CONTROLLER /* * Polling 'interrupt' - used by things like netconsole to send skbs @@ -2683,11 +3087,11 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) rtl8169_phy_reset(dev, tp); rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL, - ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | - (tp->mii.supports_gmii ? - ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full : 0)); + ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | + (tp->mii.supports_gmii ? + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full : 0)); if (RTL_R8(PHYstatus) & TBI_Enable) netif_info(tp, link, dev, "TBI auto-negotiating\n"); @@ -2740,7 +3144,8 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return netif_running(dev) ? tp->do_ioctl(tp, data, cmd) : -ENODEV; } -static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd) +static int rtl_xmii_ioctl(struct rtl8169_private *tp, + struct mii_ioctl_data *data, int cmd) { switch (cmd) { case SIOCGMIIPHY: @@ -2840,6 +3245,8 @@ static const struct net_device_ops rtl8169_netdev_ops = { .ndo_tx_timeout = rtl8169_tx_timeout, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = rtl8169_change_mtu, + .ndo_fix_features = rtl8169_fix_features, + .ndo_set_features = rtl8169_set_features, .ndo_set_mac_address = rtl_set_mac_address, .ndo_do_ioctl = rtl8169_ioctl, .ndo_set_multicast_list = rtl_set_rx_mode, @@ -2859,6 +3266,7 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) ops->read = r8168dp_1_mdio_read; break; case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: ops->write = r8168dp_2_mdio_write; ops->read = r8168dp_2_mdio_read; break; @@ -2900,39 +3308,90 @@ static void r810x_pll_power_up(struct rtl8169_private *tp) static void r8168_phy_power_up(struct rtl8169_private *tp) { rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, 0x0e, 0x0000); + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_17: + case RTL_GIGA_MAC_VER_18: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_25: + case RTL_GIGA_MAC_VER_26: + case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + rtl_writephy(tp, 0x0e, 0x0000); + break; + default: + break; + } rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE); } static void r8168_phy_power_down(struct rtl8169_private *tp) { rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, 0x0e, 0x0200); - rtl_writephy(tp, MII_BMCR, BMCR_PDOWN); + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: + rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN); + break; + + case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_17: + case RTL_GIGA_MAC_VER_18: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_25: + case RTL_GIGA_MAC_VER_26: + case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + rtl_writephy(tp, 0x0e, 0x0200); + default: + rtl_writephy(tp, MII_BMCR, BMCR_PDOWN); + break; + } } static void r8168_pll_power_down(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - if (((tp->mac_version == RTL_GIGA_MAC_VER_27) || - (tp->mac_version == RTL_GIGA_MAC_VER_28)) && - (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) { + if ((tp->mac_version == RTL_GIGA_MAC_VER_27 || + tp->mac_version == RTL_GIGA_MAC_VER_28 || + tp->mac_version == RTL_GIGA_MAC_VER_31) && + r8168dp_check_dash(tp)) { return; } - if (((tp->mac_version == RTL_GIGA_MAC_VER_23) || - (tp->mac_version == RTL_GIGA_MAC_VER_24)) && + if ((tp->mac_version == RTL_GIGA_MAC_VER_23 || + tp->mac_version == RTL_GIGA_MAC_VER_24) && (RTL_R16(CPlusCmd) & ASF)) { return; } + if (tp->mac_version == RTL_GIGA_MAC_VER_32 || + tp->mac_version == RTL_GIGA_MAC_VER_33) + rtl_ephy_write(ioaddr, 0x19, 0xff64); + if (__rtl8169_get_wol(tp) & WAKE_ANY) { rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, MII_BMCR, 0x0000); - RTL_W32(RxConfig, RTL_R32(RxConfig) | - AcceptBroadcast | AcceptMulticast | AcceptMyPhys); + if (tp->mac_version == RTL_GIGA_MAC_VER_32 || + tp->mac_version == RTL_GIGA_MAC_VER_33) + RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | + AcceptMulticast | AcceptMyPhys); return; } @@ -2943,6 +3402,9 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); break; } @@ -2952,9 +3414,10 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - if (((tp->mac_version == RTL_GIGA_MAC_VER_27) || - (tp->mac_version == RTL_GIGA_MAC_VER_28)) && - (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) { + if ((tp->mac_version == RTL_GIGA_MAC_VER_27 || + tp->mac_version == RTL_GIGA_MAC_VER_28 || + tp->mac_version == RTL_GIGA_MAC_VER_31) && + r8168dp_check_dash(tp)) { return; } @@ -2963,6 +3426,9 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); break; } @@ -3017,6 +3483,10 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_34: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -3028,6 +3498,65 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) } } +static void rtl_init_rxcfg(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_01: + case RTL_GIGA_MAC_VER_02: + case RTL_GIGA_MAC_VER_03: + case RTL_GIGA_MAC_VER_04: + case RTL_GIGA_MAC_VER_05: + case RTL_GIGA_MAC_VER_06: + case RTL_GIGA_MAC_VER_10: + case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_13: + case RTL_GIGA_MAC_VER_14: + case RTL_GIGA_MAC_VER_15: + case RTL_GIGA_MAC_VER_16: + case RTL_GIGA_MAC_VER_17: + RTL_W32(RxConfig, RX_FIFO_THRESH | RX_DMA_BURST); + break; + case RTL_GIGA_MAC_VER_18: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); + break; + default: + RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST); + break; + } +} + +static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) +{ + tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; +} + +static void rtl_hw_reset(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + int i; + + /* Soft reset the chip. */ + RTL_W8(ChipCmd, CmdReset); + + /* Check that the chip has finished the reset. */ + for (i = 0; i < 100; i++) { + if ((RTL_R8(ChipCmd) & CmdReset) == 0) + break; + udelay(100); + } + + rtl8169_init_ring_indexes(tp); +} + static int __devinit rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -3037,7 +3566,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct mii_if_info *mii; struct net_device *dev; void __iomem *ioaddr; - unsigned int i; + int chipset, i; int rc; if (netif_msg_drv(&debug)) { @@ -3127,30 +3656,24 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rc = -EIO; goto err_out_free_res_3; } + tp->mmio_addr = ioaddr; - tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (!tp->pcie_cap) - netif_info(tp, probe, dev, "no PCI Express capability\n"); + if (!pci_is_pcie(pdev)) + netif_info(tp, probe, dev, "not PCI Express\n"); - RTL_W16(IntrMask, 0x0000); + /* Identify chip attached to board */ + rtl8169_get_mac_version(tp, dev, cfg->default_ver); - /* Soft reset the chip. */ - RTL_W8(ChipCmd, CmdReset); + rtl_init_rxcfg(tp); - /* Check that the chip has finished the reset. */ - for (i = 0; i < 100; i++) { - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; - msleep_interruptible(1); - } + RTL_W16(IntrMask, 0x0000); + + rtl_hw_reset(tp); RTL_W16(IntrStatus, 0xffff); pci_set_master(pdev); - /* Identify chip attached to board */ - rtl8169_get_mac_version(tp, ioaddr); - /* * Pretend we are using VLANs; This bypasses a nasty bug where * Interrupts stop flowing on high load on 8110SCd controllers. @@ -3161,25 +3684,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl_init_mdio_ops(tp); rtl_init_pll_power_ops(tp); - /* Use appropriate default if unknown */ - if (tp->mac_version == RTL_GIGA_MAC_NONE) { - netif_notice(tp, probe, dev, - "unknown MAC, using family default\n"); - tp->mac_version = cfg->default_ver; - } - rtl8169_print_mac_version(tp); - for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) { - if (tp->mac_version == rtl_chip_info[i].mac_version) - break; - } - if (i == ARRAY_SIZE(rtl_chip_info)) { - dev_err(&pdev->dev, - "driver bug, MAC version not found in rtl_chip_info\n"); - goto err_out_msi_4; - } - tp->chipset = i; + chipset = tp->mac_version; + tp->txd_version = rtl_chip_infos[chipset].txd_version; RTL_W8(Cfg9346, Cfg9346_Unlock); RTL_W8(Config1, RTL_R8(Config1) | PMEnable); @@ -3199,8 +3707,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->phy_reset_pending = rtl8169_tbi_reset_pending; tp->link_ok = rtl8169_tbi_link_ok; tp->do_ioctl = rtl_tbi_ioctl; - - tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */ } else { tp->set_speed = rtl8169_set_speed_xmii; tp->get_settings = rtl8169_gset_xmii; @@ -3212,8 +3718,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&tp->lock); - tp->mmio_addr = ioaddr; - /* Get MAC address */ for (i = 0; i < MAC_ADDR_LEN; i++) dev->dev_addr[i] = RTL_R8(MAC0 + i); @@ -3226,7 +3730,19 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT); - dev->features |= NETIF_F_HW_VLAN_TX_RX | NETIF_F_GRO; + /* don't enable SG, IP_CSUM and TSO by default - it might not work + * properly for all devices */ + dev->features |= NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_HIGHDMA; + + if (tp->mac_version == RTL_GIGA_MAC_VER_05) + /* 8110SCd requires hardware Rx VLAN - disallow toggling */ + dev->hw_features &= ~NETIF_F_HW_VLAN_RX; tp->intr_mask = 0xffff; tp->hw_start = cfg->hw_start; @@ -3237,6 +3753,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->timer.data = (unsigned long) dev; tp->timer.function = rtl8169_phy_timer; + tp->rtl_fw = RTL_FIRMWARE_UNKNOWN; + rc = register_netdev(dev); if (rc < 0) goto err_out_msi_4; @@ -3244,12 +3762,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n", - rtl_chip_info[tp->chipset].name, - dev->base_addr, dev->dev_addr, + rtl_chip_infos[chipset].name, dev->base_addr, dev->dev_addr, (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); - if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || - (tp->mac_version == RTL_GIGA_MAC_VER_28)) { + if (tp->mac_version == RTL_GIGA_MAC_VER_27 || + tp->mac_version == RTL_GIGA_MAC_VER_28 || + tp->mac_version == RTL_GIGA_MAC_VER_31) { rtl8168_driver_start(tp); } @@ -3281,17 +3799,18 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || - (tp->mac_version == RTL_GIGA_MAC_VER_28)) { + if (tp->mac_version == RTL_GIGA_MAC_VER_27 || + tp->mac_version == RTL_GIGA_MAC_VER_28 || + tp->mac_version == RTL_GIGA_MAC_VER_31) { rtl8168_driver_stop(tp); } cancel_delayed_work_sync(&tp->task); - rtl_release_firmware(tp); - unregister_netdev(dev); + rtl_release_firmware(tp); + if (pci_dev_run_wake(pdev)) pm_runtime_get_noresume(&pdev->dev); @@ -3303,6 +3822,50 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +static void rtl_request_uncached_firmware(struct rtl8169_private *tp) +{ + struct rtl_fw *rtl_fw; + const char *name; + int rc = -ENOMEM; + + name = rtl_lookup_firmware_name(tp); + if (!name) + goto out_no_firmware; + + rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL); + if (!rtl_fw) + goto err_warn; + + rc = request_firmware(&rtl_fw->fw, name, &tp->pci_dev->dev); + if (rc < 0) + goto err_free; + + rc = rtl_check_firmware(tp, rtl_fw); + if (rc < 0) + goto err_release_firmware; + + tp->rtl_fw = rtl_fw; +out: + return; + +err_release_firmware: + release_firmware(rtl_fw->fw); +err_free: + kfree(rtl_fw); +err_warn: + netif_warn(tp, ifup, tp->dev, "unable to load firmware patch %s (%d)\n", + name, rc); +out_no_firmware: + tp->rtl_fw = NULL; + goto out; +} + +static void rtl_request_firmware(struct rtl8169_private *tp) +{ + if (IS_ERR(tp->rtl_fw)) + rtl_request_uncached_firmware(tp); +} + static int rtl8169_open(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3334,24 +3897,24 @@ static int rtl8169_open(struct net_device *dev) smp_mb(); + rtl_request_firmware(tp); + retval = request_irq(dev->irq, rtl8169_interrupt, (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED, dev->name, dev); if (retval < 0) - goto err_release_ring_2; + goto err_release_fw_2; napi_enable(&tp->napi); rtl8169_init_phy(dev, tp); - rtl8169_vlan_mode(dev); + rtl8169_set_features(dev, dev->features); rtl_pll_power_up(tp); rtl_hw_start(dev); - rtl8169_request_timer(dev); - tp->saved_wolopts = 0; pm_runtime_put_noidle(&pdev->dev); @@ -3359,7 +3922,8 @@ static int rtl8169_open(struct net_device *dev) out: return retval; -err_release_ring_2: +err_release_fw_2: + rtl_release_firmware(tp); rtl8169_rx_clear(tp); err_free_rx_1: dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, @@ -3374,6 +3938,13 @@ err_pm_runtime_put: goto out; } +static void rtl_rx_close(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + RTL_W32(RxConfig, RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK); +} + static void rtl8169_hw_reset(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3381,27 +3952,27 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) /* Disable interrupts */ rtl8169_irq_mask_and_ack(ioaddr); + rtl_rx_close(tp); + if (tp->mac_version == RTL_GIGA_MAC_VER_27 || - tp->mac_version == RTL_GIGA_MAC_VER_28) { + tp->mac_version == RTL_GIGA_MAC_VER_28 || + tp->mac_version == RTL_GIGA_MAC_VER_31) { while (RTL_R8(TxPoll) & NPQ) udelay(20); - + } else if (tp->mac_version == RTL_GIGA_MAC_VER_34) { + while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) + udelay(100); + } else { + RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); + udelay(100); } - /* Reset the chipset */ - RTL_W8(ChipCmd, CmdReset); - - /* PCI commit */ - RTL_R8(ChipCmd); + rtl_hw_reset(tp); } static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - u32 cfg = rtl8169_rx_config; - - cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); - RTL_W32(RxConfig, cfg); /* Set DMA burst size and Interframe Gap Time */ RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | @@ -3411,25 +3982,12 @@ static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) static void rtl_hw_start(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned int i; - - /* Soft reset the chip. */ - RTL_W8(ChipCmd, CmdReset); - - /* Check that the chip has finished the reset. */ - for (i = 0; i < 100; i++) { - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; - msleep_interruptible(1); - } tp->hw_start(dev); netif_start_queue(dev); } - static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp, void __iomem *ioaddr) { @@ -3461,7 +4019,7 @@ static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz) static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) { - static const struct { + static const struct rtl_cfg2_info { u32 mac_version; u32 clk; u32 val; @@ -3470,7 +4028,8 @@ static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } - }, *p = cfg2_info; + }; + const struct rtl_cfg2_info *p = cfg2_info; unsigned int i; u32 clk; @@ -3495,26 +4054,28 @@ static void rtl_hw_start_8169(struct net_device *dev) } RTL_W8(Cfg9346, Cfg9346_Unlock); - if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || - (tp->mac_version == RTL_GIGA_MAC_VER_02) || - (tp->mac_version == RTL_GIGA_MAC_VER_03) || - (tp->mac_version == RTL_GIGA_MAC_VER_04)) + if (tp->mac_version == RTL_GIGA_MAC_VER_01 || + tp->mac_version == RTL_GIGA_MAC_VER_02 || + tp->mac_version == RTL_GIGA_MAC_VER_03 || + tp->mac_version == RTL_GIGA_MAC_VER_04) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + rtl_init_rxcfg(tp); + RTL_W8(EarlyTxThres, NoEarlyTx); rtl_set_rx_max_size(ioaddr, rx_buf_sz); - if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || - (tp->mac_version == RTL_GIGA_MAC_VER_02) || - (tp->mac_version == RTL_GIGA_MAC_VER_03) || - (tp->mac_version == RTL_GIGA_MAC_VER_04)) + if (tp->mac_version == RTL_GIGA_MAC_VER_01 || + tp->mac_version == RTL_GIGA_MAC_VER_02 || + tp->mac_version == RTL_GIGA_MAC_VER_03 || + tp->mac_version == RTL_GIGA_MAC_VER_04) rtl_set_rx_tx_config_registers(tp); tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; - if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || - (tp->mac_version == RTL_GIGA_MAC_VER_03)) { + if (tp->mac_version == RTL_GIGA_MAC_VER_02 || + tp->mac_version == RTL_GIGA_MAC_VER_03) { dprintk("Set MAC Reg C+CR Offset 0xE0. " "Bit-3 and bit-14 MUST be 1\n"); tp->cp_cmd |= (1 << 14); @@ -3532,10 +4093,10 @@ static void rtl_hw_start_8169(struct net_device *dev) rtl_set_rx_tx_desc_registers(tp, ioaddr); - if ((tp->mac_version != RTL_GIGA_MAC_VER_01) && - (tp->mac_version != RTL_GIGA_MAC_VER_02) && - (tp->mac_version != RTL_GIGA_MAC_VER_03) && - (tp->mac_version != RTL_GIGA_MAC_VER_04)) { + if (tp->mac_version != RTL_GIGA_MAC_VER_01 && + tp->mac_version != RTL_GIGA_MAC_VER_02 && + tp->mac_version != RTL_GIGA_MAC_VER_03 && + tp->mac_version != RTL_GIGA_MAC_VER_04) { RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); rtl_set_rx_tx_config_registers(tp); } @@ -3558,9 +4119,7 @@ static void rtl_hw_start_8169(struct net_device *dev) static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) { - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - int cap = tp->pcie_cap; + int cap = pci_pcie_cap(pdev); if (cap) { u16 ctl; @@ -3608,9 +4167,7 @@ static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int l static void rtl_disable_clock_request(struct pci_dev *pdev) { - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - int cap = tp->pcie_cap; + int cap = pci_pcie_cap(pdev); if (cap) { u16 ctl; @@ -3623,9 +4180,7 @@ static void rtl_disable_clock_request(struct pci_dev *pdev) static void rtl_enable_clock_request(struct pci_dev *pdev) { - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - int cap = tp->pcie_cap; + int cap = pci_pcie_cap(pdev); if (cap) { u16 ctl; @@ -3779,6 +4334,17 @@ static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev) RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } +static void rtl_hw_start_8168dp(void __iomem *ioaddr, struct pci_dev *pdev) +{ + rtl_csi_access_enable_1(ioaddr); + + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + + RTL_W8(MaxTxPacketSize, TxPacketMax); + + rtl_disable_clock_request(pdev); +} + static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev) { static const struct ephy_info e_info_8168d_4[] = { @@ -3805,6 +4371,79 @@ static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev) rtl_enable_clock_request(pdev); } +static void rtl_hw_start_8168e_1(void __iomem *ioaddr, struct pci_dev *pdev) +{ + static const struct ephy_info e_info_8168e_1[] = { + { 0x00, 0x0200, 0x0100 }, + { 0x00, 0x0000, 0x0004 }, + { 0x06, 0x0002, 0x0001 }, + { 0x06, 0x0000, 0x0030 }, + { 0x07, 0x0000, 0x2000 }, + { 0x00, 0x0000, 0x0020 }, + { 0x03, 0x5800, 0x2000 }, + { 0x03, 0x0000, 0x0001 }, + { 0x01, 0x0800, 0x1000 }, + { 0x07, 0x0000, 0x4000 }, + { 0x1e, 0x0000, 0x2000 }, + { 0x19, 0xffff, 0xfe6c }, + { 0x0a, 0x0000, 0x0040 } + }; + + rtl_csi_access_enable_2(ioaddr); + + rtl_ephy_init(ioaddr, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1)); + + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + + RTL_W8(MaxTxPacketSize, TxPacketMax); + + rtl_disable_clock_request(pdev); + + /* Reset tx FIFO pointer */ + RTL_W32(MISC, RTL_R32(MISC) | TXPLA_RST); + RTL_W32(MISC, RTL_R32(MISC) & ~TXPLA_RST); + + RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); +} + +static void rtl_hw_start_8168e_2(void __iomem *ioaddr, struct pci_dev *pdev) +{ + static const struct ephy_info e_info_8168e_2[] = { + { 0x09, 0x0000, 0x0080 }, + { 0x19, 0x0000, 0x0224 } + }; + + rtl_csi_access_enable_1(ioaddr); + + rtl_ephy_init(ioaddr, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2)); + + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + + rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC); + rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); + rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, + ERIAR_EXGMAC); + + RTL_W8(MaxTxPacketSize, 0x27); + + rtl_disable_clock_request(pdev); + + RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); + RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); + + /* Adjust EEE LED frequency */ + RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); + + RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); + RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); + RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); +} + static void rtl_hw_start_8168(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3842,55 +4481,67 @@ static void rtl_hw_start_8168(struct net_device *dev) switch (tp->mac_version) { case RTL_GIGA_MAC_VER_11: rtl_hw_start_8168bb(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_12: case RTL_GIGA_MAC_VER_17: rtl_hw_start_8168bef(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_18: rtl_hw_start_8168cp_1(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_19: rtl_hw_start_8168c_1(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_20: rtl_hw_start_8168c_2(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_21: rtl_hw_start_8168c_3(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_22: rtl_hw_start_8168c_4(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_23: rtl_hw_start_8168cp_2(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_24: rtl_hw_start_8168cp_3(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_25: case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: rtl_hw_start_8168d(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_28: rtl_hw_start_8168d_4(ioaddr, pdev); - break; + break; + + case RTL_GIGA_MAC_VER_31: + rtl_hw_start_8168dp(ioaddr, pdev); + break; + + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: + rtl_hw_start_8168e_1(ioaddr, pdev); + break; + case RTL_GIGA_MAC_VER_34: + rtl_hw_start_8168e_2(ioaddr, pdev); + break; default: printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", dev->name, tp->mac_version); - break; + break; } RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); @@ -3974,14 +4625,14 @@ static void rtl_hw_start_8105e_1(void __iomem *ioaddr, struct pci_dev *pdev) { 0x0a, 0, 0x0020 } }; - /* Force LAN exit from ASPM if Rx/Tx are not idel */ + /* Force LAN exit from ASPM if Rx/Tx are not idle */ RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); - /* disable Early Tally Counter */ + /* Disable Early Tally Counter */ RTL_W32(FuncEvent, RTL_R32(FuncEvent) & ~0x010000); RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); - RTL_W8(DLLPR, RTL_R8(DLLPR) | PM_SWITCH); + RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); rtl_ephy_init(ioaddr, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); } @@ -3998,9 +4649,9 @@ static void rtl_hw_start_8101(struct net_device *dev) void __iomem *ioaddr = tp->mmio_addr; struct pci_dev *pdev = tp->pci_dev; - if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || - (tp->mac_version == RTL_GIGA_MAC_VER_16)) { - int cap = tp->pcie_cap; + if (tp->mac_version == RTL_GIGA_MAC_VER_13 || + tp->mac_version == RTL_GIGA_MAC_VER_16) { + int cap = pci_pcie_cap(pdev); if (cap) { pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, @@ -4062,6 +4713,8 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; dev->mtu = new_mtu; + netdev_update_features(dev); + return 0; } @@ -4181,11 +4834,6 @@ err_out: return -ENOMEM; } -static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) -{ - tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; -} - static int rtl8169_init_ring(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -4299,6 +4947,7 @@ static void rtl8169_reset_task(struct work_struct *work) struct rtl8169_private *tp = container_of(work, struct rtl8169_private, task.work); struct net_device *dev = tp->dev; + int i; rtnl_lock(); @@ -4307,19 +4956,15 @@ static void rtl8169_reset_task(struct work_struct *work) rtl8169_wait_for_quiescence(dev); - rtl8169_rx_interrupt(dev, tp, tp->mmio_addr, ~(u32)0); + for (i = 0; i < NUM_RX_DESC; i++) + rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); + rtl8169_tx_clear(tp); - if (tp->dirty_rx == tp->cur_rx) { - rtl8169_init_ring_indexes(tp); - rtl_hw_start(dev); - netif_wake_queue(dev); - rtl8169_check_link_status(dev, tp, tp->mmio_addr); - } else { - if (net_ratelimit()) - netif_emerg(tp, intr, dev, "Rx buffers shortage\n"); - rtl8169_schedule_work(dev, rtl8169_reset_task); - } + rtl8169_hw_reset(tp); + rtl_hw_start(dev); + netif_wake_queue(dev); + rtl8169_check_link_status(dev, tp, tp->mmio_addr); out_unlock: rtnl_unlock(); @@ -4336,7 +4981,7 @@ static void rtl8169_tx_timeout(struct net_device *dev) } static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, - u32 opts1) + u32 *opts) { struct skb_shared_info *info = skb_shinfo(skb); unsigned int cur_frag, entry; @@ -4363,10 +5008,12 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, goto err_out; } - /* anti gcc 2.95.3 bugware (sic) */ - status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); + /* Anti gcc 2.95.3 bugware (sic) */ + status = opts[0] | len | + (RingEnd * !((entry + 1) % NUM_TX_DESC)); txd->opts1 = cpu_to_le32(status); + txd->opts2 = cpu_to_le32(opts[1]); txd->addr = cpu_to_le64(mapping); tp->tx_skb[entry].len = len; @@ -4384,24 +5031,26 @@ err_out: return -EIO; } -static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) +static inline void rtl8169_tso_csum(struct rtl8169_private *tp, + struct sk_buff *skb, u32 *opts) { - if (dev->features & NETIF_F_TSO) { - u32 mss = skb_shinfo(skb)->gso_size; + const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; + u32 mss = skb_shinfo(skb)->gso_size; + int offset = info->opts_offset; - if (mss) - return LargeSend | ((mss & MSSMask) << MSSShift); - } - if (skb->ip_summed == CHECKSUM_PARTIAL) { + if (mss) { + opts[0] |= TD_LSO; + opts[offset] |= min(mss, TD_MSS_MAX) << info->mss_shift; + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { const struct iphdr *ip = ip_hdr(skb); if (ip->protocol == IPPROTO_TCP) - return IPCS | TCPCS; + opts[offset] |= info->checksum.tcp; else if (ip->protocol == IPPROTO_UDP) - return IPCS | UDPCS; - WARN_ON(1); /* we need a WARN() */ + opts[offset] |= info->checksum.udp; + else + WARN_ON_ONCE(1); } - return 0; } static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, @@ -4414,7 +5063,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, struct device *d = &tp->pci_dev->dev; dma_addr_t mapping; u32 status, len; - u32 opts1; + u32 opts[2]; int frags; if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { @@ -4435,31 +5084,35 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, tp->tx_skb[entry].len = len; txd->addr = cpu_to_le64(mapping); - txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); - opts1 = DescOwn | rtl8169_tso_csum(skb, dev); + opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); + opts[0] = DescOwn; - frags = rtl8169_xmit_frags(tp, skb, opts1); + rtl8169_tso_csum(tp, skb, opts); + + frags = rtl8169_xmit_frags(tp, skb, opts); if (frags < 0) goto err_dma_1; else if (frags) - opts1 |= FirstFrag; + opts[0] |= FirstFrag; else { - opts1 |= FirstFrag | LastFrag; + opts[0] |= FirstFrag | LastFrag; tp->tx_skb[entry].skb = skb; } + txd->opts2 = cpu_to_le32(opts[1]); + wmb(); - /* anti gcc 2.95.3 bugware (sic) */ - status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); + /* Anti gcc 2.95.3 bugware (sic) */ + status = opts[0] | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); txd->opts1 = cpu_to_le32(status); tp->cur_tx += frags + 1; wmb(); - RTL_W8(TxPoll, NPQ); /* set polling bit */ + RTL_W8(TxPoll, NPQ); if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { netif_stop_queue(dev); @@ -4616,20 +5269,12 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data, return skb; } -/* - * Warning : rtl8169_rx_interrupt() might be called : - * 1) from NAPI (softirq) context - * (polling = 1 : we should call netif_receive_skb()) - * 2) from process context (rtl8169_reset_task()) - * (polling = 0 : we must call netif_rx() instead) - */ static int rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, void __iomem *ioaddr, u32 budget) { unsigned int cur_rx, rx_left; unsigned int count; - int polling = (budget != ~(u32)0) ? 1 : 0; cur_rx = tp->cur_rx; rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; @@ -4689,10 +5334,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, rtl8169_rx_vlan_tag(desc, skb); - if (likely(polling)) - napi_gro_receive(&tp->napi, skb); - else - netif_rx(skb); + napi_gro_receive(&tp->napi, skb); dev->stats.rx_bytes += pkt_size; dev->stats.rx_packets++; @@ -4733,7 +5375,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) * the chip, so just exit the loop. */ if (unlikely(!netif_running(dev))) { - rtl8169_asic_down(ioaddr); + rtl8169_hw_reset(tp); break; } @@ -4755,6 +5397,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) case RTL_GIGA_MAC_VER_24: case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: /* Experimental science. Pktgen proof. */ case RTL_GIGA_MAC_VER_12: case RTL_GIGA_MAC_VER_25: @@ -4847,7 +5490,7 @@ static void rtl8169_down(struct net_device *dev) struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - rtl8169_delete_timer(dev); + del_timer_sync(&tp->timer); netif_stop_queue(dev); @@ -4855,7 +5498,7 @@ static void rtl8169_down(struct net_device *dev) spin_lock_irq(&tp->lock); - rtl8169_asic_down(ioaddr); + rtl8169_hw_reset(tp); /* * At this point device interrupts can not be enabled in any function, * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, @@ -4884,7 +5527,7 @@ static int rtl8169_close(struct net_device *dev) pm_runtime_get_sync(&pdev->dev); - /* update counters before going down */ + /* Update counters before going down */ rtl8169_update_counters(dev); rtl8169_down(dev); @@ -4938,8 +5581,7 @@ static void rtl_set_rx_mode(struct net_device *dev) spin_lock_irqsave(&tp->lock, flags); - tmp = rtl8169_rx_config | rx_mode | - (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); + tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; if (tp->mac_version > RTL_GIGA_MAC_VER_06) { u32 data = mc_filter[0]; @@ -5077,15 +5719,15 @@ static int rtl8169_runtime_idle(struct device *device) } static const struct dev_pm_ops rtl8169_pm_ops = { - .suspend = rtl8169_suspend, - .resume = rtl8169_resume, - .freeze = rtl8169_suspend, - .thaw = rtl8169_resume, - .poweroff = rtl8169_suspend, - .restore = rtl8169_resume, - .runtime_suspend = rtl8169_runtime_suspend, - .runtime_resume = rtl8169_runtime_resume, - .runtime_idle = rtl8169_runtime_idle, + .suspend = rtl8169_suspend, + .resume = rtl8169_resume, + .freeze = rtl8169_suspend, + .thaw = rtl8169_resume, + .poweroff = rtl8169_suspend, + .restore = rtl8169_resume, + .runtime_suspend = rtl8169_runtime_suspend, + .runtime_resume = rtl8169_runtime_resume, + .runtime_idle = rtl8169_runtime_idle, }; #define RTL8169_PM_OPS (&rtl8169_pm_ops) @@ -5104,18 +5746,21 @@ static void rtl_shutdown(struct pci_dev *pdev) rtl8169_net_suspend(dev); - /* restore original MAC address */ + /* Restore original MAC address */ rtl_rar_set(tp, dev->perm_addr); spin_lock_irq(&tp->lock); - rtl8169_asic_down(ioaddr); + rtl8169_hw_reset(tp); spin_unlock_irq(&tp->lock); if (system_state == SYSTEM_POWER_OFF) { - /* WoL fails with some 8168 when the receiver is disabled. */ - if (tp->features & RTL_FEATURE_WOL) { + /* WoL fails with 8168b when the receiver is disabled. */ + if ((tp->mac_version == RTL_GIGA_MAC_VER_11 || + tp->mac_version == RTL_GIGA_MAC_VER_12 || + tp->mac_version == RTL_GIGA_MAC_VER_17) && + (tp->features & RTL_FEATURE_WOL)) { pci_clear_master(pdev); RTL_W8(ChipCmd, CmdRxEnb); |