r8169_main.c 140 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-only
Linus Torvalds's avatar
Linus Torvalds committed
2
/*
Francois Romieu's avatar
Francois Romieu committed
3
4
5
6
7
8
9
 * r8169.c: RealTek 8169/8168/8101 ethernet driver.
 *
 * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
 * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
 * Copyright (c) a lot of people too. Please respect their work.
 *
 * See MAINTAINERS file for support contact information.
Linus Torvalds's avatar
Linus Torvalds committed
10
11
12
13
14
15
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
16
#include <linux/clk.h>
Linus Torvalds's avatar
Linus Torvalds committed
17
18
#include <linux/delay.h>
#include <linux/ethtool.h>
19
#include <linux/phy.h>
Linus Torvalds's avatar
Linus Torvalds committed
20
21
#include <linux/if_vlan.h>
#include <linux/in.h>
22
#include <linux/io.h>
Linus Torvalds's avatar
Linus Torvalds committed
23
24
#include <linux/ip.h>
#include <linux/tcp.h>
25
#include <linux/interrupt.h>
Linus Torvalds's avatar
Linus Torvalds committed
26
#include <linux/dma-mapping.h>
27
#include <linux/pm_runtime.h>
28
#include <linux/bitfield.h>
29
#include <linux/prefetch.h>
hayeswang's avatar
hayeswang committed
30
31
#include <linux/ipv6.h>
#include <net/ip6_checksum.h>
Linus Torvalds's avatar
Linus Torvalds committed
32

Heiner Kallweit's avatar
Heiner Kallweit committed
33
#include "r8169.h"
34
35
#include "r8169_firmware.h"

Linus Torvalds's avatar
Linus Torvalds committed
36
37
#define MODULENAME "r8169"

38
39
#define FIRMWARE_8168D_1	"rtl_nic/rtl8168d-1.fw"
#define FIRMWARE_8168D_2	"rtl_nic/rtl8168d-2.fw"
hayeswang's avatar
hayeswang committed
40
41
#define FIRMWARE_8168E_1	"rtl_nic/rtl8168e-1.fw"
#define FIRMWARE_8168E_2	"rtl_nic/rtl8168e-2.fw"
Hayes Wang's avatar
Hayes Wang committed
42
#define FIRMWARE_8168E_3	"rtl_nic/rtl8168e-3.fw"
43
44
#define FIRMWARE_8168F_1	"rtl_nic/rtl8168f-1.fw"
#define FIRMWARE_8168F_2	"rtl_nic/rtl8168f-2.fw"
45
#define FIRMWARE_8105E_1	"rtl_nic/rtl8105e-1.fw"
46
#define FIRMWARE_8402_1		"rtl_nic/rtl8402-1.fw"
47
#define FIRMWARE_8411_1		"rtl_nic/rtl8411-1.fw"
hayeswang's avatar
hayeswang committed
48
#define FIRMWARE_8411_2		"rtl_nic/rtl8411-2.fw"
Hayes Wang's avatar
Hayes Wang committed
49
#define FIRMWARE_8106E_1	"rtl_nic/rtl8106e-1.fw"
hayeswang's avatar
hayeswang committed
50
#define FIRMWARE_8106E_2	"rtl_nic/rtl8106e-2.fw"
51
#define FIRMWARE_8168G_2	"rtl_nic/rtl8168g-2.fw"
hayeswang's avatar
hayeswang committed
52
#define FIRMWARE_8168G_3	"rtl_nic/rtl8168g-3.fw"
53
54
#define FIRMWARE_8168H_1	"rtl_nic/rtl8168h-1.fw"
#define FIRMWARE_8168H_2	"rtl_nic/rtl8168h-2.fw"
55
#define FIRMWARE_8168FP_3	"rtl_nic/rtl8168fp-3.fw"
56
57
#define FIRMWARE_8107E_1	"rtl_nic/rtl8107e-1.fw"
#define FIRMWARE_8107E_2	"rtl_nic/rtl8107e-2.fw"
58
#define FIRMWARE_8125A_3	"rtl_nic/rtl8125a-3.fw"
59

Linus Torvalds's avatar
Linus Torvalds committed
60
61
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
   The RTL chips use a 64 element hash table based on the Ethernet CRC. */
62
#define	MC_FILTER_LIMIT	32
Linus Torvalds's avatar
Linus Torvalds committed
63

64
#define TX_DMA_BURST	7	/* Maximum PCI burst, '7' is unlimited */
Linus Torvalds's avatar
Linus Torvalds committed
65
66
67
#define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */

#define R8169_REGS_SIZE		256
68
#define R8169_RX_BUF_SIZE	(SZ_16K - 1)
Linus Torvalds's avatar
Linus Torvalds committed
69
#define NUM_TX_DESC	64	/* Number of Tx descriptor registers */
70
#define NUM_RX_DESC	256U	/* Number of Rx descriptor registers */
Linus Torvalds's avatar
Linus Torvalds committed
71
72
73
#define R8169_TX_RING_BYTES	(NUM_TX_DESC * sizeof(struct TxDesc))
#define R8169_RX_RING_BYTES	(NUM_RX_DESC * sizeof(struct RxDesc))

74
75
#define OCP_STD_PHY_BASE	0xa400

76
77
#define RTL_CFG_NO_GBIT	1

Linus Torvalds's avatar
Linus Torvalds committed
78
/* write/read MMIO register */
79
80
81
82
83
84
#define RTL_W8(tp, reg, val8)	writeb((val8), tp->mmio_addr + (reg))
#define RTL_W16(tp, reg, val16)	writew((val16), tp->mmio_addr + (reg))
#define RTL_W32(tp, reg, val32)	writel((val32), tp->mmio_addr + (reg))
#define RTL_R8(tp, reg)		readb(tp->mmio_addr + (reg))
#define RTL_R16(tp, reg)		readw(tp->mmio_addr + (reg))
#define RTL_R32(tp, reg)		readl(tp->mmio_addr + (reg))
Linus Torvalds's avatar
Linus Torvalds committed
85

86
87
88
89
#define JUMBO_4K	(4 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
#define JUMBO_6K	(6 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
#define JUMBO_7K	(7 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
#define JUMBO_9K	(9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
Francois Romieu's avatar
Francois Romieu committed
90

91
static const struct {
Linus Torvalds's avatar
Linus Torvalds committed
92
	const char *name;
93
	const char *fw_name;
94
95
} rtl_chip_infos[] = {
	/* PCI devices. */
96
97
98
99
100
	[RTL_GIGA_MAC_VER_02] = {"RTL8169s"				},
	[RTL_GIGA_MAC_VER_03] = {"RTL8110s"				},
	[RTL_GIGA_MAC_VER_04] = {"RTL8169sb/8110sb"			},
	[RTL_GIGA_MAC_VER_05] = {"RTL8169sc/8110sc"			},
	[RTL_GIGA_MAC_VER_06] = {"RTL8169sc/8110sc"			},
101
	/* PCI-E devices. */
102
103
	[RTL_GIGA_MAC_VER_07] = {"RTL8102e"				},
	[RTL_GIGA_MAC_VER_08] = {"RTL8102e"				},
104
	[RTL_GIGA_MAC_VER_09] = {"RTL8102e/RTL8103e"			},
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
	[RTL_GIGA_MAC_VER_10] = {"RTL8101e"				},
	[RTL_GIGA_MAC_VER_11] = {"RTL8168b/8111b"			},
	[RTL_GIGA_MAC_VER_12] = {"RTL8168b/8111b"			},
	[RTL_GIGA_MAC_VER_13] = {"RTL8101e"				},
	[RTL_GIGA_MAC_VER_14] = {"RTL8100e"				},
	[RTL_GIGA_MAC_VER_15] = {"RTL8100e"				},
	[RTL_GIGA_MAC_VER_16] = {"RTL8101e"				},
	[RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b"			},
	[RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp"			},
	[RTL_GIGA_MAC_VER_19] = {"RTL8168c/8111c"			},
	[RTL_GIGA_MAC_VER_20] = {"RTL8168c/8111c"			},
	[RTL_GIGA_MAC_VER_21] = {"RTL8168c/8111c"			},
	[RTL_GIGA_MAC_VER_22] = {"RTL8168c/8111c"			},
	[RTL_GIGA_MAC_VER_23] = {"RTL8168cp/8111cp"			},
	[RTL_GIGA_MAC_VER_24] = {"RTL8168cp/8111cp"			},
	[RTL_GIGA_MAC_VER_25] = {"RTL8168d/8111d",	FIRMWARE_8168D_1},
	[RTL_GIGA_MAC_VER_26] = {"RTL8168d/8111d",	FIRMWARE_8168D_2},
	[RTL_GIGA_MAC_VER_27] = {"RTL8168dp/8111dp"			},
	[RTL_GIGA_MAC_VER_28] = {"RTL8168dp/8111dp"			},
	[RTL_GIGA_MAC_VER_29] = {"RTL8105e",		FIRMWARE_8105E_1},
	[RTL_GIGA_MAC_VER_30] = {"RTL8105e",		FIRMWARE_8105E_1},
	[RTL_GIGA_MAC_VER_31] = {"RTL8168dp/8111dp"			},
	[RTL_GIGA_MAC_VER_32] = {"RTL8168e/8111e",	FIRMWARE_8168E_1},
	[RTL_GIGA_MAC_VER_33] = {"RTL8168e/8111e",	FIRMWARE_8168E_2},
	[RTL_GIGA_MAC_VER_34] = {"RTL8168evl/8111evl",	FIRMWARE_8168E_3},
	[RTL_GIGA_MAC_VER_35] = {"RTL8168f/8111f",	FIRMWARE_8168F_1},
	[RTL_GIGA_MAC_VER_36] = {"RTL8168f/8111f",	FIRMWARE_8168F_2},
	[RTL_GIGA_MAC_VER_37] = {"RTL8402",		FIRMWARE_8402_1 },
	[RTL_GIGA_MAC_VER_38] = {"RTL8411",		FIRMWARE_8411_1 },
	[RTL_GIGA_MAC_VER_39] = {"RTL8106e",		FIRMWARE_8106E_1},
	[RTL_GIGA_MAC_VER_40] = {"RTL8168g/8111g",	FIRMWARE_8168G_2},
	[RTL_GIGA_MAC_VER_41] = {"RTL8168g/8111g"			},
137
138
139
	[RTL_GIGA_MAC_VER_42] = {"RTL8168gu/8111gu",	FIRMWARE_8168G_3},
	[RTL_GIGA_MAC_VER_43] = {"RTL8106eus",		FIRMWARE_8106E_2},
	[RTL_GIGA_MAC_VER_44] = {"RTL8411b",		FIRMWARE_8411_2 },
140
141
142
143
144
145
146
	[RTL_GIGA_MAC_VER_45] = {"RTL8168h/8111h",	FIRMWARE_8168H_1},
	[RTL_GIGA_MAC_VER_46] = {"RTL8168h/8111h",	FIRMWARE_8168H_2},
	[RTL_GIGA_MAC_VER_47] = {"RTL8107e",		FIRMWARE_8107E_1},
	[RTL_GIGA_MAC_VER_48] = {"RTL8107e",		FIRMWARE_8107E_2},
	[RTL_GIGA_MAC_VER_49] = {"RTL8168ep/8111ep"			},
	[RTL_GIGA_MAC_VER_50] = {"RTL8168ep/8111ep"			},
	[RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep"			},
147
	[RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117",  FIRMWARE_8168FP_3},
148
	[RTL_GIGA_MAC_VER_60] = {"RTL8125"				},
149
	[RTL_GIGA_MAC_VER_61] = {"RTL8125",		FIRMWARE_8125A_3},
150
151
};

152
static const struct pci_device_id rtl8169_pci_tbl[] = {
153
154
155
156
157
158
159
160
161
	{ PCI_VDEVICE(REALTEK,	0x2502) },
	{ PCI_VDEVICE(REALTEK,	0x2600) },
	{ PCI_VDEVICE(REALTEK,	0x8129) },
	{ PCI_VDEVICE(REALTEK,	0x8136), RTL_CFG_NO_GBIT },
	{ PCI_VDEVICE(REALTEK,	0x8161) },
	{ PCI_VDEVICE(REALTEK,	0x8167) },
	{ PCI_VDEVICE(REALTEK,	0x8168) },
	{ PCI_VDEVICE(NCUBE,	0x8168) },
	{ PCI_VDEVICE(REALTEK,	0x8169) },
Heiner Kallweit's avatar
Heiner Kallweit committed
162
	{ PCI_VENDOR_ID_DLINK,	0x4300,
163
		PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0 },
164
165
166
167
168
169
	{ PCI_VDEVICE(DLINK,	0x4300) },
	{ PCI_VDEVICE(DLINK,	0x4302) },
	{ PCI_VDEVICE(AT,	0xc107) },
	{ PCI_VDEVICE(USR,	0x0116) },
	{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
	{ 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
170
171
	{ PCI_VDEVICE(REALTEK,	0x8125) },
	{ PCI_VDEVICE(REALTEK,	0x3000) },
Heiner Kallweit's avatar
Heiner Kallweit committed
172
	{}
Linus Torvalds's avatar
Linus Torvalds committed
173
174
175
176
};

MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);

Francois Romieu's avatar
Francois Romieu committed
177
178
enum rtl_registers {
	MAC0		= 0,	/* Ethernet hardware address. */
179
	MAC4		= 4,
Francois Romieu's avatar
Francois Romieu committed
180
181
182
183
184
185
186
187
188
189
190
191
192
	MAR0		= 8,	/* Multicast filter. */
	CounterAddrLow		= 0x10,
	CounterAddrHigh		= 0x14,
	TxDescStartAddrLow	= 0x20,
	TxDescStartAddrHigh	= 0x24,
	TxHDescStartAddrLow	= 0x28,
	TxHDescStartAddrHigh	= 0x2c,
	FLASH		= 0x30,
	ERSR		= 0x36,
	ChipCmd		= 0x37,
	TxPoll		= 0x38,
	IntrMask	= 0x3c,
	IntrStatus	= 0x3e,
Hayes Wang's avatar
Hayes Wang committed
193

Francois Romieu's avatar
Francois Romieu committed
194
	TxConfig	= 0x40,
Hayes Wang's avatar
Hayes Wang committed
195
196
#define	TXCFG_AUTO_FIFO			(1 << 7)	/* 8111e-vl */
#define	TXCFG_EMPTY			(1 << 11)	/* 8111e-vl */
Francois Romieu's avatar
Francois Romieu committed
197

Hayes Wang's avatar
Hayes Wang committed
198
199
200
201
202
203
	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)
204
#define	RX_EARLY_OFF			(1 << 11)
Hayes Wang's avatar
Hayes Wang committed
205
206
207
#define	RXCFG_DMA_SHIFT			8
					/* Unlimited maximum PCI burst. */
#define	RX_DMA_BURST			(7 << RXCFG_DMA_SHIFT)
Francois Romieu's avatar
Francois Romieu committed
208

Francois Romieu's avatar
Francois Romieu committed
209
210
211
212
	Cfg9346		= 0x50,
	Config0		= 0x51,
	Config1		= 0x52,
	Config2		= 0x53,
213
214
#define PME_SIGNAL			(1 << 5)	/* 8168c and later */

Francois Romieu's avatar
Francois Romieu committed
215
216
217
218
219
220
221
222
	Config3		= 0x54,
	Config4		= 0x55,
	Config5		= 0x56,
	PHYAR		= 0x60,
	PHYstatus	= 0x6c,
	RxMaxSize	= 0xda,
	CPlusCmd	= 0xe0,
	IntrMitigate	= 0xe2,
223

224
225
226
227
228
#define RTL_COALESCE_TX_USECS	GENMASK(15, 12)
#define RTL_COALESCE_TX_FRAMES	GENMASK(11, 8)
#define RTL_COALESCE_RX_USECS	GENMASK(7, 4)
#define RTL_COALESCE_RX_FRAMES	GENMASK(3, 0)

229
230
#define RTL_COALESCE_T_MAX	0x0fU
#define RTL_COALESCE_FRAME_MAX	(RTL_COALESCE_T_MAX * 4)
231

Francois Romieu's avatar
Francois Romieu committed
232
233
	RxDescAddrLow	= 0xe4,
	RxDescAddrHigh	= 0xe8,
234
235
236
237
238
239
240
	EarlyTxThres	= 0xec,	/* 8169. Unit of 32 bytes. */

#define NoEarlyTx	0x3f	/* Max value : no early transmit. */

	MaxTxPacketSize	= 0xec,	/* 8101/8168. Unit of 128 bytes. */

#define TxPacketMax	(8064 >> 7)
241
#define EarlySize	0x27
242

Francois Romieu's avatar
Francois Romieu committed
243
244
245
	FuncEvent	= 0xf0,
	FuncEventMask	= 0xf4,
	FuncPresetState	= 0xf8,
Chun-Hao Lin's avatar
Chun-Hao Lin committed
246
247
248
249
	IBCR0           = 0xf8,
	IBCR2           = 0xf9,
	IBIMR0          = 0xfa,
	IBISR0          = 0xfb,
Francois Romieu's avatar
Francois Romieu committed
250
	FuncForceEvent	= 0xfc,
Linus Torvalds's avatar
Linus Torvalds committed
251
252
};

253
254
255
256
257
enum rtl8168_8101_registers {
	CSIDR			= 0x64,
	CSIAR			= 0x68,
#define	CSIAR_FLAG			0x80000000
#define	CSIAR_WRITE_CMD			0x80000000
258
259
#define	CSIAR_BYTE_ENABLE		0x0000f000
#define	CSIAR_ADDR_MASK			0x00000fff
françois romieu's avatar
françois romieu committed
260
	PMCH			= 0x6f,
261
262
263
264
265
266
	EPHYAR			= 0x80,
#define	EPHYAR_FLAG			0x80000000
#define	EPHYAR_WRITE_CMD		0x80000000
#define	EPHYAR_REG_MASK			0x1f
#define	EPHYAR_REG_SHIFT		16
#define	EPHYAR_DATA_MASK		0xffff
267
	DLLPR			= 0xd0,
Hayes Wang's avatar
Hayes Wang committed
268
#define	PFM_EN				(1 << 6)
269
#define	TX_10M_PS_EN			(1 << 7)
270
271
272
	DBG_REG			= 0xd1,
#define	FIX_NAK_1			(1 << 4)
#define	FIX_NAK_2			(1 << 3)
273
274
	TWSI			= 0xd2,
	MCU			= 0xd3,
Hayes Wang's avatar
Hayes Wang committed
275
#define	NOW_IS_OOB			(1 << 7)
Hayes Wang's avatar
Hayes Wang committed
276
277
278
#define	TX_EMPTY			(1 << 5)
#define	RX_EMPTY			(1 << 4)
#define	RXTX_EMPTY			(TX_EMPTY | RX_EMPTY)
279
280
#define	EN_NDP				(1 << 3)
#define	EN_OOB_RESET			(1 << 2)
Hayes Wang's avatar
Hayes Wang committed
281
#define	LINK_LIST_RDY			(1 << 1)
282
283
284
285
286
287
288
	EFUSEAR			= 0xdc,
#define	EFUSEAR_FLAG			0x80000000
#define	EFUSEAR_WRITE_CMD		0x80000000
#define	EFUSEAR_READ_CMD		0x00000000
#define	EFUSEAR_REG_MASK		0x03ff
#define	EFUSEAR_REG_SHIFT		8
#define	EFUSEAR_DATA_MASK		0xff
289
290
	MISC_1			= 0xf2,
#define	PFM_D3COLD_EN			(1 << 6)
291
292
};

293
enum rtl8168_registers {
Hayes Wang's avatar
Hayes Wang committed
294
295
	LED_FREQ		= 0x1a,
	EEE_LED			= 0x1b,
françois romieu's avatar
françois romieu committed
296
297
298
299
300
301
302
	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_TYPE_SHIFT		16
Hayes Wang's avatar
Hayes Wang committed
303
304
305
#define ERIAR_EXGMAC			(0x00 << ERIAR_TYPE_SHIFT)
#define ERIAR_MSIX			(0x01 << ERIAR_TYPE_SHIFT)
#define ERIAR_ASF			(0x02 << ERIAR_TYPE_SHIFT)
Chun-Hao Lin's avatar
Chun-Hao Lin committed
306
#define ERIAR_OOB			(0x02 << ERIAR_TYPE_SHIFT)
Hayes Wang's avatar
Hayes Wang committed
307
308
309
#define ERIAR_MASK_SHIFT		12
#define ERIAR_MASK_0001			(0x1 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_0011			(0x3 << ERIAR_MASK_SHIFT)
310
#define ERIAR_MASK_0100			(0x4 << ERIAR_MASK_SHIFT)
Hayes Wang's avatar
Hayes Wang committed
311
#define ERIAR_MASK_0101			(0x5 << ERIAR_MASK_SHIFT)
Hayes Wang's avatar
Hayes Wang committed
312
#define ERIAR_MASK_1111			(0xf << ERIAR_MASK_SHIFT)
313
314
315
316
317
318
319
320
321
322
323
	EPHY_RXER_NUM		= 0x7c,
	OCPDR			= 0xb0,	/* OCP GPHY access */
#define OCPDR_WRITE_CMD			0x80000000
#define OCPDR_READ_CMD			0x00000000
#define OCPDR_REG_MASK			0x7f
#define OCPDR_GPHY_REG_SHIFT		16
#define OCPDR_DATA_MASK			0xffff
	OCPAR			= 0xb4,
#define OCPAR_FLAG			0x80000000
#define OCPAR_GPHY_WRITE_CMD		0x8000f060
#define OCPAR_GPHY_READ_CMD		0x0000f060
Hayes Wang's avatar
Hayes Wang committed
324
	GPHY_OCP		= 0xb8,
hayeswang's avatar
hayeswang committed
325
326
	RDSAR1			= 0xd0,	/* 8168c only. Undocumented on 8168dp */
	MISC			= 0xf0,	/* 8168e only. */
Francois Romieu's avatar
Francois Romieu committed
327
#define TXPLA_RST			(1 << 29)
Hayes Wang's avatar
Hayes Wang committed
328
#define DISABLE_LAN_EN			(1 << 23) /* Enable GPIO pin */
Hayes Wang's avatar
Hayes Wang committed
329
#define PWM_EN				(1 << 22)
Hayes Wang's avatar
Hayes Wang committed
330
#define RXDV_GATED_EN			(1 << 19)
Hayes Wang's avatar
Hayes Wang committed
331
#define EARLY_TALLY_EN			(1 << 16)
332
333
};

334
335
336
337
338
339
340
341
342
343
344
345
346
enum rtl8125_registers {
	IntrMask_8125		= 0x38,
	IntrStatus_8125		= 0x3c,
	TxPoll_8125		= 0x90,
	MAC0_BKP		= 0x19e0,
};

#define RX_VLAN_INNER_8125	BIT(22)
#define RX_VLAN_OUTER_8125	BIT(23)
#define RX_VLAN_8125		(RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125)

#define RX_FETCH_DFLT_8125	(8 << 27)

Francois Romieu's avatar
Francois Romieu committed
347
enum rtl_register_content {
Linus Torvalds's avatar
Linus Torvalds committed
348
	/* InterruptStatusBits */
Francois Romieu's avatar
Francois Romieu committed
349
350
351
352
353
354
355
356
357
358
359
	SYSErr		= 0x8000,
	PCSTimeout	= 0x4000,
	SWInt		= 0x0100,
	TxDescUnavail	= 0x0080,
	RxFIFOOver	= 0x0040,
	LinkChg		= 0x0020,
	RxOverflow	= 0x0010,
	TxErr		= 0x0008,
	TxOK		= 0x0004,
	RxErr		= 0x0002,
	RxOK		= 0x0001,
Linus Torvalds's avatar
Linus Torvalds committed
360
361

	/* RxStatusDesc */
362
363
364
365
	RxRWT	= (1 << 22),
	RxRES	= (1 << 21),
	RxRUNT	= (1 << 20),
	RxCRC	= (1 << 19),
Linus Torvalds's avatar
Linus Torvalds committed
366
367

	/* ChipCmdBits */
Hayes Wang's avatar
Hayes Wang committed
368
	StopReq		= 0x80,
Francois Romieu's avatar
Francois Romieu committed
369
370
371
372
	CmdReset	= 0x10,
	CmdRxEnb	= 0x08,
	CmdTxEnb	= 0x04,
	RxBufEmpty	= 0x01,
Linus Torvalds's avatar
Linus Torvalds committed
373

374
375
376
377
378
	/* TXPoll register p.5 */
	HPQ		= 0x80,		/* Poll cmd on the high prio queue */
	NPQ		= 0x40,		/* Poll cmd on the low prio queue */
	FSWInt		= 0x01,		/* Forced software interrupt */

Linus Torvalds's avatar
Linus Torvalds committed
379
	/* Cfg9346Bits */
Francois Romieu's avatar
Francois Romieu committed
380
381
	Cfg9346_Lock	= 0x00,
	Cfg9346_Unlock	= 0xc0,
Linus Torvalds's avatar
Linus Torvalds committed
382
383

	/* rx_mode_bits */
Francois Romieu's avatar
Francois Romieu committed
384
385
	AcceptErr	= 0x20,
	AcceptRunt	= 0x10,
386
#define RX_CONFIG_ACCEPT_ERR_MASK	0x30
Francois Romieu's avatar
Francois Romieu committed
387
388
389
390
	AcceptBroadcast	= 0x08,
	AcceptMulticast	= 0x04,
	AcceptMyPhys	= 0x02,
	AcceptAllPhys	= 0x01,
391
#define RX_CONFIG_ACCEPT_OK_MASK	0x0f
392
#define RX_CONFIG_ACCEPT_MASK		0x3f
Linus Torvalds's avatar
Linus Torvalds committed
393
394
395
396
397

	/* TxConfigBits */
	TxInterFrameGapShift = 24,
	TxDMAShift = 8,	/* DMA burst value (0-7) is shift this many bits */

398
	/* Config1 register p.24 */
399
400
401
402
403
404
	LEDS1		= (1 << 7),
	LEDS0		= (1 << 6),
	Speed_down	= (1 << 4),
	MEMMAP		= (1 << 3),
	IOMAP		= (1 << 2),
	VPD		= (1 << 1),
405
406
	PMEnable	= (1 << 0),	/* Power Management Enable */

407
	/* Config2 register p. 25 */
hayeswang's avatar
hayeswang committed
408
	ClkReqEn	= (1 << 7),	/* Clock Request Enable */
409
	MSIEnable	= (1 << 5),	/* 8169 only. Reserved in the 8168. */
410
411
412
	PCI_Clock_66MHz = 0x01,
	PCI_Clock_33MHz = 0x00,

Francois Romieu's avatar
Francois Romieu committed
413
414
415
	/* Config3 register p.25 */
	MagicPacket	= (1 << 5),	/* Wake up when receives a Magic Packet */
	LinkUp		= (1 << 4),	/* Wake up when the cable connection is re-established */
Francois Romieu's avatar
Francois Romieu committed
416
	Jumbo_En0	= (1 << 2),	/* 8168 only. Reserved in the 8168b */
hayeswang's avatar
hayeswang committed
417
	Rdy_to_L23	= (1 << 1),	/* L23 Enable */
418
	Beacon_en	= (1 << 0),	/* 8168 only. Reserved in the 8168b */
Francois Romieu's avatar
Francois Romieu committed
419

Francois Romieu's avatar
Francois Romieu committed
420
421
422
	/* Config4 register */
	Jumbo_En1	= (1 << 1),	/* 8168 only. Reserved in the 8168b */

423
	/* Config5 register p.27 */
Francois Romieu's avatar
Francois Romieu committed
424
425
426
	BWF		= (1 << 6),	/* Accept Broadcast wakeup frame */
	MWF		= (1 << 5),	/* Accept Multicast wakeup frame */
	UWF		= (1 << 4),	/* Accept Unicast wakeup frame */
Francois Romieu's avatar
Francois Romieu committed
427
	Spi_en		= (1 << 3),
Francois Romieu's avatar
Francois Romieu committed
428
	LanWake		= (1 << 1),	/* LanWake enable/disable */
429
	PMEStatus	= (1 << 0),	/* PME status can be reset by PCI RST# */
hayeswang's avatar
hayeswang committed
430
	ASPM_en		= (1 << 0),	/* ASPM enable */
431

Linus Torvalds's avatar
Linus Torvalds committed
432
	/* CPlusCmd p.31 */
433
434
	EnableBist	= (1 << 15),	// 8168 8101
	Mac_dbgo_oe	= (1 << 14),	// 8168 8101
Heiner Kallweit's avatar
Heiner Kallweit committed
435
	EnAnaPLL	= (1 << 14),	// 8169
436
437
438
439
440
441
442
443
	Normal_mode	= (1 << 13),	// unused
	Force_half_dup	= (1 << 12),	// 8168 8101
	Force_rxflow_en	= (1 << 11),	// 8168 8101
	Force_txflow_en	= (1 << 10),	// 8168 8101
	Cxpl_dbg_sel	= (1 << 9),	// 8168 8101
	ASF		= (1 << 8),	// 8168 8101
	PktCntrDisable	= (1 << 7),	// 8168 8101
	Mac_dbgo_sel	= 0x001c,	// 8168
Linus Torvalds's avatar
Linus Torvalds committed
444
445
446
447
	RxVlan		= (1 << 6),
	RxChkSum	= (1 << 5),
	PCIDAC		= (1 << 4),
	PCIMulRW	= (1 << 3),
448
#define INTT_MASK	GENMASK(1, 0)
449
#define CPCMD_MASK	(Normal_mode | RxVlan | RxChkSum | INTT_MASK)
Linus Torvalds's avatar
Linus Torvalds committed
450
451

	/* rtl8169_PHYstatus */
Francois Romieu's avatar
Francois Romieu committed
452
453
454
455
456
457
458
459
	TBI_Enable	= 0x80,
	TxFlowCtrl	= 0x40,
	RxFlowCtrl	= 0x20,
	_1000bpsF	= 0x10,
	_100bps		= 0x08,
	_10bps		= 0x04,
	LinkStatus	= 0x02,
	FullDup		= 0x01,
Linus Torvalds's avatar
Linus Torvalds committed
460

461
462
463
	/* ResetCounterCommand */
	CounterReset	= 0x1,

464
	/* DumpCounterCommand */
Francois Romieu's avatar
Francois Romieu committed
465
	CounterDump	= 0x8,
466
467
468

	/* magic enable v2 */
	MagicPacket_v2	= (1 << 16),	/* Wake up when receives a Magic Packet */
Linus Torvalds's avatar
Linus Torvalds committed
469
470
};

Francois Romieu's avatar
Francois Romieu committed
471
472
enum rtl_desc_bit {
	/* First doubleword. */
Linus Torvalds's avatar
Linus Torvalds committed
473
474
475
476
	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 */
Francois Romieu's avatar
Francois Romieu committed
477
478
479
480
481
482
483
};

/* Generic case. */
enum rtl_tx_desc_bit {
	/* First doubleword. */
	TD_LSO		= (1 << 27),		/* Large Send Offload */
#define TD_MSS_MAX			0x07ffu	/* MSS value */
Linus Torvalds's avatar
Linus Torvalds committed
484

Francois Romieu's avatar
Francois Romieu committed
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
	/* 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 */
};

/* 8102e, 8168c and beyond. */
enum rtl_tx_desc_bit_1 {
hayeswang's avatar
hayeswang committed
500
501
	/* First doubleword. */
	TD1_GTSENV4	= (1 << 26),		/* Giant Send for IPv4 */
hayeswang's avatar
hayeswang committed
502
	TD1_GTSENV6	= (1 << 25),		/* Giant Send for IPv6 */
hayeswang's avatar
hayeswang committed
503
#define GTTCPHO_SHIFT			18
504
#define GTTCPHO_MAX			0x7f
hayeswang's avatar
hayeswang committed
505

Francois Romieu's avatar
Francois Romieu committed
506
	/* Second doubleword. */
hayeswang's avatar
hayeswang committed
507
#define TCPHO_SHIFT			18
508
#define TCPHO_MAX			0x3ff
Francois Romieu's avatar
Francois Romieu committed
509
#define TD1_MSS_SHIFT			18	/* MSS position (11 bits) */
hayeswang's avatar
hayeswang committed
510
511
	TD1_IPv6_CS	= (1 << 28),		/* Calculate IPv6 checksum */
	TD1_IPv4_CS	= (1 << 29),		/* Calculate IPv4 checksum */
Francois Romieu's avatar
Francois Romieu committed
512
513
514
	TD1_TCP_CS	= (1 << 30),		/* Calculate TCP/IP checksum */
	TD1_UDP_CS	= (1 << 31),		/* Calculate UDP/IP checksum */
};
Linus Torvalds's avatar
Linus Torvalds committed
515

Francois Romieu's avatar
Francois Romieu committed
516
enum rtl_rx_desc_bit {
Linus Torvalds's avatar
Linus Torvalds committed
517
518
	/* Rx private */
	PID1		= (1 << 18), /* Protocol ID bit 1/2 */
519
	PID0		= (1 << 17), /* Protocol ID bit 0/2 */
Linus Torvalds's avatar
Linus Torvalds committed
520
521
522
523
524
525
526
527
528
529
530
531
532
533

#define RxProtoUDP	(PID1)
#define RxProtoTCP	(PID0)
#define RxProtoIP	(PID1 | PID0)
#define RxProtoMask	RxProtoIP

	IPFail		= (1 << 16), /* IP checksum failed */
	UDPFail		= (1 << 15), /* UDP/IP checksum failed */
	TCPFail		= (1 << 14), /* TCP/IP checksum failed */
	RxVlanTag	= (1 << 16), /* VLAN tag available */
};

#define RsvdMask	0x3fffc000

534
535
536
537
538
#define RTL_GSO_MAX_SIZE_V1	32000
#define RTL_GSO_MAX_SEGS_V1	24
#define RTL_GSO_MAX_SIZE_V2	64000
#define RTL_GSO_MAX_SEGS_V2	64

Linus Torvalds's avatar
Linus Torvalds committed
539
struct TxDesc {
540
541
542
	__le32 opts1;
	__le32 opts2;
	__le64 addr;
Linus Torvalds's avatar
Linus Torvalds committed
543
544
545
};

struct RxDesc {
546
547
548
	__le32 opts1;
	__le32 opts2;
	__le64 addr;
Linus Torvalds's avatar
Linus Torvalds committed
549
550
551
552
553
554
555
};

struct ring_info {
	struct sk_buff	*skb;
	u32		len;
};

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
struct rtl8169_counters {
	__le64	tx_packets;
	__le64	rx_packets;
	__le64	tx_errors;
	__le32	rx_errors;
	__le16	rx_missed;
	__le16	align_errors;
	__le32	tx_one_collision;
	__le32	tx_multi_collision;
	__le64	rx_unicast;
	__le64	rx_broadcast;
	__le32	rx_multicast;
	__le16	tx_aborted;
	__le16	tx_underun;
};

572
573
574
575
576
struct rtl8169_tc_offsets {
	bool	inited;
	__le64	tx_errors;
	__le32	tx_multi_collision;
	__le16	tx_aborted;
577
	__le16	rx_missed;
578
579
};

580
enum rtl_flag {
581
	RTL_FLAG_TASK_ENABLED = 0,
582
583
584
585
	RTL_FLAG_TASK_RESET_PENDING,
	RTL_FLAG_MAX
};

Junchang Wang's avatar
Junchang Wang committed
586
587
588
589
590
591
struct rtl8169_stats {
	u64			packets;
	u64			bytes;
	struct u64_stats_sync	syncp;
};

Linus Torvalds's avatar
Linus Torvalds committed
592
593
struct rtl8169_private {
	void __iomem *mmio_addr;	/* memory map physical address */
Francois Romieu's avatar
Francois Romieu committed
594
	struct pci_dev *pci_dev;
David Howells's avatar
David Howells committed
595
	struct net_device *dev;
596
	struct phy_device *phydev;
597
	struct napi_struct napi;
598
	enum mac_version mac_version;
Linus Torvalds's avatar
Linus Torvalds committed
599
600
601
	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_tx;
Junchang Wang's avatar
Junchang Wang committed
602
603
	struct rtl8169_stats rx_stats;
	struct rtl8169_stats tx_stats;
Linus Torvalds's avatar
Linus Torvalds committed
604
605
606
607
	struct TxDesc *TxDescArray;	/* 256-aligned Tx descriptor ring */
	struct RxDesc *RxDescArray;	/* 256-aligned Rx descriptor ring */
	dma_addr_t TxPhyAddr;
	dma_addr_t RxPhyAddr;
608
	struct page *Rx_databuff[NUM_RX_DESC];	/* Rx data buffers */
Linus Torvalds's avatar
Linus Torvalds committed
609
610
	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
	u16 cp_cmd;
611
	u32 irq_mask;
612
	struct clk *clk;
613

614
	struct {
615
616
		DECLARE_BITMAP(flags, RTL_FLAG_MAX);
		struct mutex mutex;
617
618
619
		struct work_struct work;
	} wk;

620
	unsigned irq_enabled:1;
621
	unsigned supports_gmii:1;
622
	unsigned aspm_manageable:1;
623
624
	dma_addr_t counters_phys_addr;
	struct rtl8169_counters *counters;
625
	struct rtl8169_tc_offsets tc_offset;
626
	u32 saved_wolopts;
627
	int eee_adv;
628

629
	const char *fw_name;
630
	struct rtl_fw *rtl_fw;
Hayes Wang's avatar
Hayes Wang committed
631
632

	u32 ocp_base;
Linus Torvalds's avatar
Linus Torvalds committed
633
634
};

635
636
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);

637
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
Linus Torvalds's avatar
Linus Torvalds committed
638
MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
639
MODULE_SOFTDEP("pre: realtek");
Linus Torvalds's avatar
Linus Torvalds committed
640
MODULE_LICENSE("GPL");
641
642
MODULE_FIRMWARE(FIRMWARE_8168D_1);
MODULE_FIRMWARE(FIRMWARE_8168D_2);
hayeswang's avatar
hayeswang committed
643
644
MODULE_FIRMWARE(FIRMWARE_8168E_1);
MODULE_FIRMWARE(FIRMWARE_8168E_2);
645
MODULE_FIRMWARE(FIRMWARE_8168E_3);
646
MODULE_FIRMWARE(FIRMWARE_8105E_1);
647
648
MODULE_FIRMWARE(FIRMWARE_8168F_1);
MODULE_FIRMWARE(FIRMWARE_8168F_2);
649
MODULE_FIRMWARE(FIRMWARE_8402_1);
650
MODULE_FIRMWARE(FIRMWARE_8411_1);
hayeswang's avatar
hayeswang committed
651
MODULE_FIRMWARE(FIRMWARE_8411_2);
Hayes Wang's avatar
Hayes Wang committed
652
MODULE_FIRMWARE(FIRMWARE_8106E_1);
hayeswang's avatar
hayeswang committed
653
MODULE_FIRMWARE(FIRMWARE_8106E_2);
654
MODULE_FIRMWARE(FIRMWARE_8168G_2);
hayeswang's avatar
hayeswang committed
655
MODULE_FIRMWARE(FIRMWARE_8168G_3);
656
657
MODULE_FIRMWARE(FIRMWARE_8168H_1);
MODULE_FIRMWARE(FIRMWARE_8168H_2);
658
MODULE_FIRMWARE(FIRMWARE_8168FP_3);
659
660
MODULE_FIRMWARE(FIRMWARE_8107E_1);
MODULE_FIRMWARE(FIRMWARE_8107E_2);
661
MODULE_FIRMWARE(FIRMWARE_8125A_3);
Linus Torvalds's avatar
Linus Torvalds committed
662

Heiner Kallweit's avatar
Heiner Kallweit committed
663
664
665
666
667
static inline struct device *tp_to_dev(struct rtl8169_private *tp)
{
	return &tp->pci_dev->dev;
}

668
669
670
671
672
673
674
675
676
677
static void rtl_lock_work(struct rtl8169_private *tp)
{
	mutex_lock(&tp->wk.mutex);
}

static void rtl_unlock_work(struct rtl8169_private *tp)
{
	mutex_unlock(&tp->wk.mutex);
}

678
679
680
681
682
683
684
685
686
687
static void rtl_lock_config_regs(struct rtl8169_private *tp)
{
	RTL_W8(tp, Cfg9346, Cfg9346_Lock);
}

static void rtl_unlock_config_regs(struct rtl8169_private *tp)
{
	RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
}

688
689
690
691
692
693
static void rtl_pci_commit(struct rtl8169_private *tp)
{
	/* Read an arbitrary register to commit a preceding PCI write */
	RTL_R8(tp, ChipCmd);
}

694
695
696
697
698
static bool rtl_is_8125(struct rtl8169_private *tp)
{
	return tp->mac_version >= RTL_GIGA_MAC_VER_60;
}

699
700
701
static bool rtl_is_8168evl_up(struct rtl8169_private *tp)
{
	return tp->mac_version >= RTL_GIGA_MAC_VER_34 &&
702
	       tp->mac_version != RTL_GIGA_MAC_VER_39 &&
703
	       tp->mac_version <= RTL_GIGA_MAC_VER_52;
704
705
}

706
707
708
709
710
711
712
static bool rtl_supports_eee(struct rtl8169_private *tp)
{
	return tp->mac_version >= RTL_GIGA_MAC_VER_34 &&
	       tp->mac_version != RTL_GIGA_MAC_VER_37 &&
	       tp->mac_version != RTL_GIGA_MAC_VER_39;
}

713
714
715
716
717
718
719
720
static void rtl_read_mac_from_reg(struct rtl8169_private *tp, u8 *mac, int reg)
{
	int i;

	for (i = 0; i < ETH_ALEN; i++)
		mac[i] = RTL_R8(tp, reg + i);
}

721
722
723
724
725
726
struct rtl_cond {
	bool (*check)(struct rtl8169_private *);
	const char *msg;
};

static bool rtl_loop_wait(struct rtl8169_private *tp, const struct rtl_cond *c,
727
			  unsigned long usecs, int n, bool high)
728
729
730
731
732
733
{
	int i;

	for (i = 0; i < n; i++) {
		if (c->check(tp) == high)
			return true;
734
		fsleep(usecs);
735
	}
736
737

	if (net_ratelimit())
738
739
		netdev_err(tp->dev, "%s == %d (loop: %d, delay: %lu).\n",
			   c->msg, !high, n, usecs);
740
741
742
	return false;
}

743
744
745
static bool rtl_loop_wait_high(struct rtl8169_private *tp,
			       const struct rtl_cond *c,
			       unsigned long d, int n)
746
{
747
	return rtl_loop_wait(tp, c, d, n, true);
748
749
}

750
751
752
static bool rtl_loop_wait_low(struct rtl8169_private *tp,
			      const struct rtl_cond *c,
			      unsigned long d, int n)
753
{
754
	return rtl_loop_wait(tp, c, d, n, false);
755
756
757
758
759
760
761
762
763
764
765
766
}

#define DECLARE_RTL_COND(name)				\
static bool name ## _check(struct rtl8169_private *);	\
							\
static const struct rtl_cond name = {			\
	.check	= name ## _check,			\
	.msg	= #name					\
};							\
							\
static bool name ## _check(struct rtl8169_private *tp)

Hayes Wang's avatar
Hayes Wang committed
767
768
769
static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg)
{
	if (reg & 0xffff0001) {
770
771
		if (net_ratelimit())
			netdev_err(tp->dev, "Invalid ocp reg %x!\n", reg);
Hayes Wang's avatar
Hayes Wang committed
772
773
774
775
776
777
778
		return true;
	}
	return false;
}

DECLARE_RTL_COND(rtl_ocp_gphy_cond)
{
779
	return RTL_R32(tp, GPHY_OCP) & OCPAR_FLAG;
Hayes Wang's avatar
Hayes Wang committed
780
781
782
783
784
785
786
}

static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
{
	if (rtl_ocp_reg_failure(tp, reg))
		return;

787
	RTL_W32(tp, GPHY_OCP, OCPAR_FLAG | (reg << 15) | data);
Hayes Wang's avatar
Hayes Wang committed
788

789
	rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10);
Hayes Wang's avatar
Hayes Wang committed
790
791
}

792
static int r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg)
Hayes Wang's avatar
Hayes Wang committed
793
794
795
796
{
	if (rtl_ocp_reg_failure(tp, reg))
		return 0;

797
	RTL_W32(tp, GPHY_OCP, reg << 15);
Hayes Wang's avatar
Hayes Wang committed
798

799
	return rtl_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ?
800
		(RTL_R32(tp, GPHY_OCP) & 0xffff) : -ETIMEDOUT;
Hayes Wang's avatar
Hayes Wang committed
801
802
803
804
805
806
807
}

static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
{
	if (rtl_ocp_reg_failure(tp, reg))
		return;

808
	RTL_W32(tp, OCPDR, OCPAR_FLAG | (reg << 15) | data);
Hayes Wang's avatar
Hayes Wang committed
809
810
811
812
813
814
815
}

static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
{
	if (rtl_ocp_reg_failure(tp, reg))
		return 0;

816
	RTL_W32(tp, OCPDR, reg << 15);
Hayes Wang's avatar
Hayes Wang committed
817

818
	return RTL_R32(tp, OCPDR);
Hayes Wang's avatar
Hayes Wang committed
819
820
}

821
822
823
824
825
826
827
828
static void r8168_mac_ocp_modify(struct rtl8169_private *tp, u32 reg, u16 mask,
				 u16 set)
{
	u16 data = r8168_mac_ocp_read(tp, reg);

	r8168_mac_ocp_write(tp, reg, (data & ~mask) | set);
}

Hayes Wang's avatar
Hayes Wang committed
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value)
{
	if (reg == 0x1f) {
		tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE;
		return;
	}

	if (tp->ocp_base != OCP_STD_PHY_BASE)
		reg -= 0x10;

	r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value);
}

static int r8168g_mdio_read(struct rtl8169_private *tp, int reg)
{
844
845
846
	if (reg == 0x1f)
		return tp->ocp_base == OCP_STD_PHY_BASE ? 0 : tp->ocp_base >> 4;

Hayes Wang's avatar
Hayes Wang committed
847
848
849
850
851
852
	if (tp->ocp_base != OCP_STD_PHY_BASE)
		reg -= 0x10;

	return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2);
}

853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value)
{
	if (reg == 0x1f) {
		tp->ocp_base = value << 4;
		return;
	}

	r8168_mac_ocp_write(tp, tp->ocp_base + reg, value);
}

static int mac_mcu_read(struct rtl8169_private *tp, int reg)
{
	return r8168_mac_ocp_read(tp, tp->ocp_base + reg);
}

868
869
DECLARE_RTL_COND(rtl_phyar_cond)
{
870
	return RTL_R32(tp, PHYAR) & 0x80000000;
871
872
}

873
static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value)
Linus Torvalds's avatar
Linus Torvalds committed
874
{
875
	RTL_W32(tp, PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff));
Linus Torvalds's avatar
Linus Torvalds committed
876

877
	rtl_loop_wait_low(tp, &rtl_phyar_cond, 25, 20);
878
	/*
879
880
	 * According to hardware specs a 20us delay is required after write
	 * complete indication, but before sending next command.
881
	 */
882
	udelay(20);
Linus Torvalds's avatar
Linus Torvalds committed
883
884
}

885
static int r8169_mdio_read(struct rtl8169_private *tp, int reg)
Linus Torvalds's avatar
Linus Torvalds committed
886
{
887
	int value;
Linus Torvalds's avatar
Linus Torvalds committed
888

889
	RTL_W32(tp, PHYAR, 0x0 | (reg & 0x1f) << 16);
Linus Torvalds's avatar
Linus Torvalds committed
890

891
	value = rtl_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ?
892
		RTL_R32(tp, PHYAR) & 0xffff : -ETIMEDOUT;
893

894
895
896
897
898
899
	/*
	 * According to hardware specs a 20us delay is required after read
	 * complete indication, but before sending next command.
	 */
	udelay(20);

Linus Torvalds's avatar
Linus Torvalds committed
900
901
902
	return value;
}

Chun-Hao Lin's avatar
Chun-Hao Lin committed
903
904
DECLARE_RTL_COND(rtl_ocpar_cond)
{
905
	return RTL_R32(tp, OCPAR) & OCPAR_FLAG;
Chun-Hao Lin's avatar
Chun-Hao Lin committed
906
907
}

908
static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data)
909
{
910
911
912
	RTL_W32(tp, OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
	RTL_W32(tp, OCPAR, OCPAR_GPHY_WRITE_CMD);
	RTL_W32(tp, EPHY_RXER_NUM, 0);
913

914
	rtl_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100);
915
916
}

917
static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value)
918
{
919
920
	r8168dp_1_mdio_access(tp, reg,
			      OCPDR_WRITE_CMD | (value & OCPDR_DATA_MASK));
921
922
}

923
static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg)
924
{
925
	r8168dp_1_mdio_access(tp, reg, OCPDR_READ_CMD);
926
927

	mdelay(1);
928
929
	RTL_W32(tp, OCPAR, OCPAR_GPHY_READ_CMD);
	RTL_W32(tp, EPHY_RXER_NUM, 0);
930

931
	return rtl_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ?
932
		RTL_R32(tp, OCPDR) & OCPDR_DATA_MASK : -ETIMEDOUT;
933
934
}

françois romieu's avatar
françois romieu committed
935
936
#define R8168DP_1_MDIO_ACCESS_BIT	0x00020000

937
static void r8168dp_2_mdio_start(struct rtl8169_private *tp)
françois romieu's avatar
françois romieu committed
938
{
939
	RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT);
françois romieu's avatar
françois romieu committed
940
941
}

942
static void r8168dp_2_mdio_stop(struct rtl8169_private *tp)
françois romieu's avatar
françois romieu committed
943
{
944
	RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) | R8168DP_1_MDIO_ACCESS_BIT);
françois romieu's avatar
françois romieu committed
945
946
}

947
static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value)
françois romieu's avatar
françois romieu committed
948
{
949
	r8168dp_2_mdio_start(tp);
françois romieu's avatar
françois romieu committed
950

951
	r8169_mdio_write(tp, reg, value);
françois romieu's avatar
françois romieu committed
952

953
	r8168dp_2_mdio_stop(tp);
françois romieu's avatar
françois romieu committed
954
955
}

956
static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg)
françois romieu's avatar
françois romieu committed
957
958
959
{
	int value;

960
961
962
963
	/* Work around issue with chip reporting wrong PHY ID */
	if (reg == MII_PHYSID2)
		return 0xc912;

964
	r8168dp_2_mdio_start(tp);
françois romieu's avatar
françois romieu committed
965

966
	value = r8169_mdio_read(tp, reg);
françois romieu's avatar
françois romieu committed
967

968
	r8168dp_2_mdio_stop(tp);
françois romieu's avatar
françois romieu committed
969
970
971
972

	return value;
}

973
static void rtl_writephy(struct rtl8169_private *tp, int location, int val)
974
{
975
976
977
978
979
980
981
982
	switch (tp->mac_version) {
	case RTL_GIGA_MAC_VER_27:
		r8168dp_1_mdio_write(tp, location, val);
		break;
	case RTL_GIGA_MAC_VER_28:
	case RTL_GIGA_MAC_VER_31:
		r8168dp_2_mdio_write(tp, location, val);
		break;
983
	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61:
984
985
986
987
988
989
		r8168g_mdio_write(tp, location, val);
		break;
	default:
		r8169_mdio_write(tp, location, val);
		break;
	}
990
991
}

992
993
static int rtl_readphy(struct rtl8169_private *tp, int location)
{
994
995
996
997
998
999
	switch (tp->mac_version) {
	case RTL_GIGA_MAC_VER_27:
		return r8168dp_1_mdio_read(tp, location);
	case RTL_GIGA_MAC_VER_28:
	case RTL_GIGA_MAC_VER_31:
		return r8168dp_2_mdio_read(tp, location);
1000
	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61:
1001
1002
1003
1004
		return r8168g_mdio_read(tp, location);
	default:
		return r8169_mdio_read(tp, location);
	}
1005
1006
}

1007
1008
DECLARE_RTL_COND(rtl_ephyar_cond)
{
1009
	return RTL_R32(tp, EPHYAR) & EPHYAR_FLAG;
1010
1011
}

1012
static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value)
1013
{
1014
	RTL_W32(tp, EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
1015
1016
		(reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);

1017
	rtl_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100);
1018
1019

	udelay(10);
1020
1021
}

1022
static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr)
1023
{
1024
	RTL_W32(tp, EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
1025

1026
	return rtl_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ?
1027
		RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0;
1028
1029
}

1030
1031
1032
1033
1034
1035
1036
static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
{
	/* based on RTL8168FP_OOBMAC_BASE in vendor driver */
	if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB)
		*cmd |= 0x7f0 << 18;
}

Chun-Hao Lin's avatar
Chun-Hao Lin committed
1037
1038
DECLARE_RTL_COND(rtl_eriar_cond)
{
1039
	return RTL_R32(tp, ERIAR) & ERIAR_FLAG;
Chun-Hao Lin's avatar
Chun-Hao Lin committed
1040