diff options
Diffstat (limited to 'drivers/net/r8169.c')
| -rw-r--r-- | drivers/net/r8169.c | 1046 | 
1 files changed, 659 insertions, 387 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 493b0de3848..ef1ce2ebeb4 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -26,6 +26,7 @@  #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 +38,8 @@  #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_8105E_1	"rtl_nic/rtl8105e-1.fw"  #ifdef RTL8169_DEBUG @@ -96,77 +99,123 @@ 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_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)  };  #undef _R @@ -222,6 +271,9 @@ enum rtl_registers {  	IntrStatus	= 0x3e,  	TxConfig	= 0x40,  	RxConfig	= 0x44, + +#define RTL_RX_CONFIG_MASK		0xff7e1880u +  	RxMissed	= 0x4c,  	Cfg9346		= 0x50,  	Config0		= 0x51, @@ -315,7 +367,9 @@ 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)  };  enum rtl_register_content { @@ -393,6 +447,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 +496,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 */ +}; + +/* 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 */ +}; -	/* 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 */ +/* 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 +618,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 +640,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); @@ -565,6 +667,7 @@ struct rtl8169_private {  	u32 saved_wolopts;  	const struct firmware *fw; +#define RTL_FIRMWARE_UNKNOWN	ERR_PTR(-EAGAIN);  };  MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); @@ -577,6 +680,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); @@ -648,32 +753,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)  { @@ -972,9 +1094,8 @@ static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp)  }  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; @@ -1091,6 +1212,11 @@ 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)  { @@ -1099,6 +1225,8 @@ static void rtl8169_get_drvinfo(struct net_device *dev,  	strcpy(info->driver, MODULENAME);  	strcpy(info->version, RTL8169_VERSION);  	strcpy(info->bus_info, pci_name(tp->pci_dev)); +	strncpy(info->fw_version, IS_ERR_OR_NULL(tp->fw) ? "N/A" : +		rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1);  }  static int rtl8169_get_regs_len(struct net_device *dev) @@ -1160,16 +1288,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 +1318,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 +1343,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 +1360,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 +1386,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 +1411,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 +1436,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 +1521,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 +1545,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 +1590,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 +1598,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 @@ -1547,6 +1626,11 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,  		u32 val;  		int mac_version;  	} mac_info[] = { +		/* 8168E family. */ +		{ 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 +1639,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 +1659,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 }, @@ -1610,6 +1696,12 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,  	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) @@ -1679,14 +1771,14 @@ 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"); +					  "Out of range of firmware\n");  				return;  			}  			break;  		case PHY_READCOUNT_EQ_SKIP:  			if (index + 2 >= fw_size) {  				netif_err(tp, probe, tp->dev, -					"Out of range of firmware\n"); +					  "Out of range of firmware\n");  				return;  			}  			break; @@ -1695,7 +1787,7 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)  		case PHY_SKIPN:  			if (index + 1 + regno >= fw_size) {  				netif_err(tp, probe, tp->dev, -					"Out of range of firmware\n"); +					  "Out of range of firmware\n");  				return;  			}  			break; @@ -1751,10 +1843,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 +1878,26 @@ 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->fw)) +		release_firmware(tp->fw); +	tp->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; -	} +	const struct firmware *fw = tp->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(fw)) +		rtl_phy_write_fw(tp, 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) @@ -2164,7 +2254,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 +2336,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 +2366,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 +2439,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 +2522,79 @@ static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp)  	rtl_patchphy(tp, 0x0d, 1 << 5);  } +static void rtl8168e_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 rtl8102e_hw_phy_config(struct rtl8169_private *tp)  {  	static const struct phy_reg phy_reg_init[] = { @@ -2474,8 +2633,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 +2709,13 @@ 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_hw_phy_config(tp); +		break;  	default:  		break; @@ -2567,9 +2732,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 +2756,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 +2823,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 +2880,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 +2981,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 +3002,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,33 +3044,82 @@ 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); @@ -2943,6 +3136,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 +3148,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 +3160,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 +3217,9 @@ 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:  		ops->down	= r8168_pll_power_down;  		ops->up		= r8168_pll_power_up;  		break; @@ -3028,6 +3231,22 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)  	}  } +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; +		msleep_interruptible(1); +	} +} +  static int __devinit  rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  { @@ -3037,7 +3256,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,6 +3346,7 @@ 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) @@ -3134,22 +3354,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  	RTL_W16(IntrMask, 0x0000); -	/* 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); -	} +	rtl_hw_reset(tp);  	RTL_W16(IntrStatus, 0xffff);  	pci_set_master(pdev);  	/* Identify chip attached to board */ -	rtl8169_get_mac_version(tp, ioaddr); +	rtl8169_get_mac_version(tp, dev, cfg->default_ver);  	/*  	 * Pretend we are using VLANs; This bypasses a nasty bug where @@ -3161,25 +3373,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 +3396,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 +3407,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 +3419,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 +3442,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->fw = RTL_FIRMWARE_UNKNOWN; +  	rc = register_netdev(dev);  	if (rc < 0)  		goto err_out_msi_4; @@ -3244,12 +3451,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 +3488,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 +3511,27 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)  	pci_set_drvdata(pdev, NULL);  } +static void rtl_request_firmware(struct rtl8169_private *tp) +{ +	/* Return early if the firmware is already loaded / cached. */ +	if (IS_ERR(tp->fw)) { +		const char *name; + +		name = rtl_lookup_firmware_name(tp); +		if (name) { +			int rc; + +			rc = request_firmware(&tp->fw, name, &tp->pci_dev->dev); +			if (rc >= 0) +				return; + +			netif_warn(tp, ifup, tp->dev, "unable to load " +				"firmware patch %s (%d)\n", name, rc); +		} +		tp->fw = NULL; +	} +} +  static int rtl8169_open(struct net_device *dev)  {  	struct rtl8169_private *tp = netdev_priv(dev); @@ -3334,24 +3563,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 +3588,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, @@ -3382,7 +3612,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)  	rtl8169_irq_mask_and_ack(ioaddr);  	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); @@ -3400,7 +3631,7 @@ 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); +	cfg |= (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK);  	RTL_W32(RxConfig, cfg);  	/* Set DMA burst size and Interframe Gap Time */ @@ -3411,25 +3642,14 @@ 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); -	} +	rtl_hw_reset(tp);  	tp->hw_start(dev);  	netif_start_queue(dev);  } -  static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,  					 void __iomem *ioaddr)  { @@ -3495,26 +3715,26 @@ 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_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 +3752,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);  	} @@ -3779,6 +3999,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 +4036,41 @@ 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(void __iomem *ioaddr, struct pci_dev *pdev) +{ +	static const struct ephy_info e_info_8168e[] = { +		{ 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, ARRAY_SIZE(e_info_8168e)); + +	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_8168(struct net_device *dev)  {  	struct rtl8169_private *tp = netdev_priv(dev); @@ -3842,55 +4108,64 @@ 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(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,10 +4249,10 @@ 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); @@ -3998,8 +4273,8 @@ 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)) { +	if (tp->mac_version == RTL_GIGA_MAC_VER_13 || +	    tp->mac_version == RTL_GIGA_MAC_VER_16) {  		int cap = tp->pcie_cap;  		if (cap) { @@ -4062,6 +4337,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;  } @@ -4299,6 +4576,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 +4585,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_init_ring_indexes(tp); +	rtl_hw_start(dev); +	netif_wake_queue(dev); +	rtl8169_check_link_status(dev, tp, tp->mmio_addr);  out_unlock:  	rtnl_unlock(); @@ -4336,7 +4610,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 +4637,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 +4660,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 +4692,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 +4713,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; + +	rtl8169_tso_csum(tp, skb, opts); -	frags = rtl8169_xmit_frags(tp, skb, opts1); +	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 +4898,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 +4963,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++; @@ -4755,6 +5026,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 +5119,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); @@ -4884,7 +5156,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); @@ -4939,7 +5211,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); +	      (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK);  	if (tp->mac_version > RTL_GIGA_MAC_VER_06) {  		u32 data = mc_filter[0]; @@ -5077,15 +5349,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,7 +5376,7 @@ 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);  |