r8169.c 159 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
/*
Francois Romieu's avatar
Francois Romieu committed
2
3
4
5
6
7
8
 * 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
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/init.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/firmware.h>
Stanislaw Gruszka's avatar
Stanislaw Gruszka committed
29
#include <linux/pci-aspm.h>
30
#include <linux/prefetch.h>
Linus Torvalds's avatar
Linus Torvalds committed
31
32
33
34

#include <asm/io.h>
#include <asm/irq.h>

Francois Romieu's avatar
Francois Romieu committed
35
#define RTL8169_VERSION "2.3LK-NAPI"
Linus Torvalds's avatar
Linus Torvalds committed
36
37
38
#define MODULENAME "r8169"
#define PFX MODULENAME ": "

39
40
#define FIRMWARE_8168D_1	"rtl_nic/rtl8168d-1.fw"
#define FIRMWARE_8168D_2	"rtl_nic/rtl8168d-2.fw"
hayeswang's avatar
hayeswang committed
41
42
#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
43
#define FIRMWARE_8168E_3	"rtl_nic/rtl8168e-3.fw"
44
45
#define FIRMWARE_8168F_1	"rtl_nic/rtl8168f-1.fw"
#define FIRMWARE_8168F_2	"rtl_nic/rtl8168f-2.fw"
46
#define FIRMWARE_8105E_1	"rtl_nic/rtl8105e-1.fw"
47
#define FIRMWARE_8402_1		"rtl_nic/rtl8402-1.fw"
48
#define FIRMWARE_8411_1		"rtl_nic/rtl8411-1.fw"
49

Linus Torvalds's avatar
Linus Torvalds committed
50
51
#ifdef RTL8169_DEBUG
#define assert(expr) \
52
53
	if (!(expr)) {					\
		printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
54
		#expr,__FILE__,__func__,__LINE__);		\
55
	}
56
57
#define dprintk(fmt, args...) \
	do { printk(KERN_DEBUG PFX fmt, ## args); } while (0)
Linus Torvalds's avatar
Linus Torvalds committed
58
59
60
61
62
#else
#define assert(expr) do {} while (0)
#define dprintk(fmt, args...)	do {} while (0)
#endif /* RTL8169_DEBUG */

63
#define R8169_MSG_DEFAULT \
64
	(NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)
65

66
67
68
69
70
71
#define TX_SLOTS_AVAIL(tp) \
	(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx)

/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */
#define TX_FRAGS_READY_FOR(tp,nr_frags) \
	(TX_SLOTS_AVAIL(tp) >= (nr_frags + 1))
Linus Torvalds's avatar
Linus Torvalds committed
72
73
74

/* 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. */
75
static const int multicast_filter_limit = 32;
Linus Torvalds's avatar
Linus Torvalds committed
76

77
#define MAX_READ_REQUEST_SHIFT	12
Linus Torvalds's avatar
Linus Torvalds committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
#define SafeMtu		0x1c20	/* ... actually life sucks beyond ~7k */
#define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */

#define R8169_REGS_SIZE		256
#define R8169_NAPI_WEIGHT	64
#define NUM_TX_DESC	64	/* Number of Tx descriptor registers */
#define NUM_RX_DESC	256	/* Number of Rx descriptor registers */
#define RX_BUF_SIZE	1536	/* Rx Buffer size */
#define R8169_TX_RING_BYTES	(NUM_TX_DESC * sizeof(struct TxDesc))
#define R8169_RX_RING_BYTES	(NUM_RX_DESC * sizeof(struct RxDesc))

#define RTL8169_TX_TIMEOUT	(6*HZ)
#define RTL8169_PHY_TIMEOUT	(10*HZ)

93
94
#define RTL_EEPROM_SIG		cpu_to_le32(0x8129)
#define RTL_EEPROM_SIG_MASK	cpu_to_le32(0xffff)
95
96
#define RTL_EEPROM_SIG_ADDR	0x0000

Linus Torvalds's avatar
Linus Torvalds committed
97
98
99
100
101
102
/* write/read MMIO register */
#define RTL_W8(reg, val8)	writeb ((val8), ioaddr + (reg))
#define RTL_W16(reg, val16)	writew ((val16), ioaddr + (reg))
#define RTL_W32(reg, val32)	writel ((val32), ioaddr + (reg))
#define RTL_R8(reg)		readb (ioaddr + (reg))
#define RTL_R16(reg)		readw (ioaddr + (reg))
103
#define RTL_R32(reg)		readl (ioaddr + (reg))
Linus Torvalds's avatar
Linus Torvalds committed
104
105

enum mac_version {
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
137
138
	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,
Hayes Wang's avatar
Hayes Wang committed
139
	RTL_GIGA_MAC_VER_34,
140
141
	RTL_GIGA_MAC_VER_35,
	RTL_GIGA_MAC_VER_36,
142
	RTL_GIGA_MAC_VER_37,
143
	RTL_GIGA_MAC_VER_38,
144
	RTL_GIGA_MAC_NONE   = 0xff,
Linus Torvalds's avatar
Linus Torvalds committed
145
146
};

Francois Romieu's avatar
Francois Romieu committed
147
148
149
150
151
enum rtl_tx_desc_version {
	RTL_TD_0	= 0,
	RTL_TD_1	= 1,
};

Francois Romieu's avatar
Francois Romieu committed
152
153
154
155
156
157
158
159
160
161
162
163
164
#define JUMBO_1K	ETH_DATA_LEN
#define JUMBO_4K	(4*1024 - ETH_HLEN - 2)
#define JUMBO_6K	(6*1024 - ETH_HLEN - 2)
#define JUMBO_7K	(7*1024 - ETH_HLEN - 2)
#define JUMBO_9K	(9*1024 - ETH_HLEN - 2)

#define _R(NAME,TD,FW,SZ,B) {	\
	.name = NAME,		\
	.txd_version = TD,	\
	.fw_name = FW,		\
	.jumbo_max = SZ,	\
	.jumbo_tx_csum = B	\
}
Linus Torvalds's avatar
Linus Torvalds committed
165

166
static const struct {
Linus Torvalds's avatar
Linus Torvalds committed
167
	const char *name;
Francois Romieu's avatar
Francois Romieu committed
168
	enum rtl_tx_desc_version txd_version;
169
	const char *fw_name;
Francois Romieu's avatar
Francois Romieu committed
170
171
	u16 jumbo_max;
	bool jumbo_tx_csum;
172
173
174
} rtl_chip_infos[] = {
	/* PCI devices. */
	[RTL_GIGA_MAC_VER_01] =
Francois Romieu's avatar
Francois Romieu committed
175
		_R("RTL8169",		RTL_TD_0, NULL, JUMBO_7K, true),
176
	[RTL_GIGA_MAC_VER_02] =
Francois Romieu's avatar
Francois Romieu committed
177
		_R("RTL8169s",		RTL_TD_0, NULL, JUMBO_7K, true),
178
	[RTL_GIGA_MAC_VER_03] =
Francois Romieu's avatar
Francois Romieu committed
179
		_R("RTL8110s",		RTL_TD_0, NULL, JUMBO_7K, true),
180
	[RTL_GIGA_MAC_VER_04] =
Francois Romieu's avatar
Francois Romieu committed
181
		_R("RTL8169sb/8110sb",	RTL_TD_0, NULL, JUMBO_7K, true),
182
	[RTL_GIGA_MAC_VER_05] =
Francois Romieu's avatar
Francois Romieu committed
183
		_R("RTL8169sc/8110sc",	RTL_TD_0, NULL, JUMBO_7K, true),
184
	[RTL_GIGA_MAC_VER_06] =
Francois Romieu's avatar
Francois Romieu committed
185
		_R("RTL8169sc/8110sc",	RTL_TD_0, NULL, JUMBO_7K, true),
186
187
	/* PCI-E devices. */
	[RTL_GIGA_MAC_VER_07] =
Francois Romieu's avatar
Francois Romieu committed
188
		_R("RTL8102e",		RTL_TD_1, NULL, JUMBO_1K, true),
189
	[RTL_GIGA_MAC_VER_08] =
Francois Romieu's avatar
Francois Romieu committed
190
		_R("RTL8102e",		RTL_TD_1, NULL, JUMBO_1K, true),
191
	[RTL_GIGA_MAC_VER_09] =
Francois Romieu's avatar
Francois Romieu committed
192
		_R("RTL8102e",		RTL_TD_1, NULL, JUMBO_1K, true),
193
	[RTL_GIGA_MAC_VER_10] =
Francois Romieu's avatar
Francois Romieu committed
194
		_R("RTL8101e",		RTL_TD_0, NULL, JUMBO_1K, true),
195
	[RTL_GIGA_MAC_VER_11] =
Francois Romieu's avatar
Francois Romieu committed
196
		_R("RTL8168b/8111b",	RTL_TD_0, NULL, JUMBO_4K, false),
197
	[RTL_GIGA_MAC_VER_12] =
Francois Romieu's avatar
Francois Romieu committed
198
		_R("RTL8168b/8111b",	RTL_TD_0, NULL, JUMBO_4K, false),
199
	[RTL_GIGA_MAC_VER_13] =
Francois Romieu's avatar
Francois Romieu committed
200
		_R("RTL8101e",		RTL_TD_0, NULL, JUMBO_1K, true),
201
	[RTL_GIGA_MAC_VER_14] =
Francois Romieu's avatar
Francois Romieu committed
202
		_R("RTL8100e",		RTL_TD_0, NULL, JUMBO_1K, true),
203
	[RTL_GIGA_MAC_VER_15] =
Francois Romieu's avatar
Francois Romieu committed
204
		_R("RTL8100e",		RTL_TD_0, NULL, JUMBO_1K, true),
205
	[RTL_GIGA_MAC_VER_16] =
Francois Romieu's avatar
Francois Romieu committed
206
		_R("RTL8101e",		RTL_TD_0, NULL, JUMBO_1K, true),
207
	[RTL_GIGA_MAC_VER_17] =
Francois Romieu's avatar
Francois Romieu committed
208
		_R("RTL8168b/8111b",	RTL_TD_1, NULL, JUMBO_4K, false),
209
	[RTL_GIGA_MAC_VER_18] =
Francois Romieu's avatar
Francois Romieu committed
210
		_R("RTL8168cp/8111cp",	RTL_TD_1, NULL, JUMBO_6K, false),
211
	[RTL_GIGA_MAC_VER_19] =
Francois Romieu's avatar
Francois Romieu committed
212
		_R("RTL8168c/8111c",	RTL_TD_1, NULL, JUMBO_6K, false),
213
	[RTL_GIGA_MAC_VER_20] =
Francois Romieu's avatar
Francois Romieu committed
214
		_R("RTL8168c/8111c",	RTL_TD_1, NULL, JUMBO_6K, false),
215
	[RTL_GIGA_MAC_VER_21] =
Francois Romieu's avatar
Francois Romieu committed
216
		_R("RTL8168c/8111c",	RTL_TD_1, NULL, JUMBO_6K, false),
217
	[RTL_GIGA_MAC_VER_22] =
Francois Romieu's avatar
Francois Romieu committed
218
		_R("RTL8168c/8111c",	RTL_TD_1, NULL, JUMBO_6K, false),
219
	[RTL_GIGA_MAC_VER_23] =
Francois Romieu's avatar
Francois Romieu committed
220
		_R("RTL8168cp/8111cp",	RTL_TD_1, NULL, JUMBO_6K, false),
221
	[RTL_GIGA_MAC_VER_24] =
Francois Romieu's avatar
Francois Romieu committed
222
		_R("RTL8168cp/8111cp",	RTL_TD_1, NULL, JUMBO_6K, false),
223
	[RTL_GIGA_MAC_VER_25] =
Francois Romieu's avatar
Francois Romieu committed
224
225
		_R("RTL8168d/8111d",	RTL_TD_1, FIRMWARE_8168D_1,
							JUMBO_9K, false),
226
	[RTL_GIGA_MAC_VER_26] =
Francois Romieu's avatar
Francois Romieu committed
227
228
		_R("RTL8168d/8111d",	RTL_TD_1, FIRMWARE_8168D_2,
							JUMBO_9K, false),
229
	[RTL_GIGA_MAC_VER_27] =
Francois Romieu's avatar
Francois Romieu committed
230
		_R("RTL8168dp/8111dp",	RTL_TD_1, NULL, JUMBO_9K, false),
231
	[RTL_GIGA_MAC_VER_28] =
Francois Romieu's avatar
Francois Romieu committed
232
		_R("RTL8168dp/8111dp",	RTL_TD_1, NULL, JUMBO_9K, false),
233
	[RTL_GIGA_MAC_VER_29] =
Francois Romieu's avatar
Francois Romieu committed
234
235
		_R("RTL8105e",		RTL_TD_1, FIRMWARE_8105E_1,
							JUMBO_1K, true),
236
	[RTL_GIGA_MAC_VER_30] =
Francois Romieu's avatar
Francois Romieu committed
237
238
		_R("RTL8105e",		RTL_TD_1, FIRMWARE_8105E_1,
							JUMBO_1K, true),
239
	[RTL_GIGA_MAC_VER_31] =
Francois Romieu's avatar
Francois Romieu committed
240
		_R("RTL8168dp/8111dp",	RTL_TD_1, NULL, JUMBO_9K, false),
241
	[RTL_GIGA_MAC_VER_32] =
Francois Romieu's avatar
Francois Romieu committed
242
243
		_R("RTL8168e/8111e",	RTL_TD_1, FIRMWARE_8168E_1,
							JUMBO_9K, false),
244
	[RTL_GIGA_MAC_VER_33] =
Francois Romieu's avatar
Francois Romieu committed
245
246
		_R("RTL8168e/8111e",	RTL_TD_1, FIRMWARE_8168E_2,
							JUMBO_9K, false),
Hayes Wang's avatar
Hayes Wang committed
247
	[RTL_GIGA_MAC_VER_34] =
Francois Romieu's avatar
Francois Romieu committed
248
249
		_R("RTL8168evl/8111evl",RTL_TD_1, FIRMWARE_8168E_3,
							JUMBO_9K, false),
250
	[RTL_GIGA_MAC_VER_35] =
Francois Romieu's avatar
Francois Romieu committed
251
252
		_R("RTL8168f/8111f",	RTL_TD_1, FIRMWARE_8168F_1,
							JUMBO_9K, false),
253
	[RTL_GIGA_MAC_VER_36] =
Francois Romieu's avatar
Francois Romieu committed
254
255
		_R("RTL8168f/8111f",	RTL_TD_1, FIRMWARE_8168F_2,
							JUMBO_9K, false),
256
257
258
	[RTL_GIGA_MAC_VER_37] =
		_R("RTL8402",		RTL_TD_1, FIRMWARE_8402_1,
							JUMBO_1K, true),
259
260
261
	[RTL_GIGA_MAC_VER_38] =
		_R("RTL8411",		RTL_TD_1, FIRMWARE_8411_1,
							JUMBO_9K, false),
262
};
263
#undef _R
264

265
266
267
268
269
270
enum cfg_version {
	RTL_CFG_0 = 0x00,
	RTL_CFG_1,
	RTL_CFG_2
};

271
static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
272
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), 0, 0, RTL_CFG_0 },
273
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, RTL_CFG_2 },
274
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8167), 0, 0, RTL_CFG_0 },
275
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_1 },
276
277
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, RTL_CFG_0 },
	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, RTL_CFG_0 },
278
	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4302), 0, 0, RTL_CFG_0 },
279
	{ PCI_DEVICE(PCI_VENDOR_ID_AT,		0xc107), 0, 0, RTL_CFG_0 },
280
281
282
	{ PCI_DEVICE(0x16ec,			0x0116), 0, 0, RTL_CFG_0 },
	{ PCI_VENDOR_ID_LINKSYS,		0x1032,
		PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
283
284
	{ 0x0001,				0x8168,
		PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_2 },
Linus Torvalds's avatar
Linus Torvalds committed
285
286
287
288
289
	{0,},
};

MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);

290
static int rx_buf_sz = 16383;
291
static int use_dac;
292
293
294
static struct {
	u32 msg_enable;
} debug = { -1 };
Linus Torvalds's avatar
Linus Torvalds committed
295

Francois Romieu's avatar
Francois Romieu committed
296
297
enum rtl_registers {
	MAC0		= 0,	/* Ethernet hardware address. */
298
	MAC4		= 4,
Francois Romieu's avatar
Francois Romieu committed
299
300
301
302
303
304
305
306
307
308
309
310
311
	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
312

Francois Romieu's avatar
Francois Romieu committed
313
	TxConfig	= 0x40,
Hayes Wang's avatar
Hayes Wang committed
314
315
#define	TXCFG_AUTO_FIFO			(1 << 7)	/* 8111e-vl */
#define	TXCFG_EMPTY			(1 << 11)	/* 8111e-vl */
Francois Romieu's avatar
Francois Romieu committed
316

Hayes Wang's avatar
Hayes Wang committed
317
318
319
320
321
322
323
324
325
	RxConfig	= 0x44,
#define	RX128_INT_EN			(1 << 15)	/* 8111c and later */
#define	RX_MULTI_EN			(1 << 14)	/* 8111c only */
#define	RXCFG_FIFO_SHIFT		13
					/* No threshold before first PCI xfer */
#define	RX_FIFO_THRESH			(7 << RXCFG_FIFO_SHIFT)
#define	RXCFG_DMA_SHIFT			8
					/* Unlimited maximum PCI burst. */
#define	RX_DMA_BURST			(7 << RXCFG_DMA_SHIFT)
Francois Romieu's avatar
Francois Romieu committed
326

Francois Romieu's avatar
Francois Romieu committed
327
328
329
330
331
	RxMissed	= 0x4c,
	Cfg9346		= 0x50,
	Config0		= 0x51,
	Config1		= 0x52,
	Config2		= 0x53,
332
333
#define PME_SIGNAL			(1 << 5)	/* 8168c and later */

Francois Romieu's avatar
Francois Romieu committed
334
335
336
337
338
339
340
341
342
343
344
	Config3		= 0x54,
	Config4		= 0x55,
	Config5		= 0x56,
	MultiIntr	= 0x5c,
	PHYAR		= 0x60,
	PHYstatus	= 0x6c,
	RxMaxSize	= 0xda,
	CPlusCmd	= 0xe0,
	IntrMitigate	= 0xe2,
	RxDescAddrLow	= 0xe4,
	RxDescAddrHigh	= 0xe8,
345
346
347
348
349
350
351
	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)
352
#define EarlySize	0x27
353

Francois Romieu's avatar
Francois Romieu committed
354
355
356
357
	FuncEvent	= 0xf0,
	FuncEventMask	= 0xf4,
	FuncPresetState	= 0xf8,
	FuncForceEvent	= 0xfc,
Linus Torvalds's avatar
Linus Torvalds committed
358
359
};

360
361
362
363
364
365
366
367
368
369
370
371
372
373
enum rtl8110_registers {
	TBICSR			= 0x64,
	TBI_ANAR		= 0x68,
	TBI_LPAR		= 0x6a,
};

enum rtl8168_8101_registers {
	CSIDR			= 0x64,
	CSIAR			= 0x68,
#define	CSIAR_FLAG			0x80000000
#define	CSIAR_WRITE_CMD			0x80000000
#define	CSIAR_BYTE_ENABLE		0x0f
#define	CSIAR_BYTE_ENABLE_SHIFT		12
#define	CSIAR_ADDR_MASK			0x0fff
374
375
376
#define CSIAR_FUNC_CARD			0x00000000
#define CSIAR_FUNC_SDIO			0x00010000
#define CSIAR_FUNC_NIC			0x00020000
françois romieu's avatar
françois romieu committed
377
	PMCH			= 0x6f,
378
379
380
381
382
383
	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
384
	DLLPR			= 0xd0,
Hayes Wang's avatar
Hayes Wang committed
385
#define	PFM_EN				(1 << 6)
386
387
388
	DBG_REG			= 0xd1,
#define	FIX_NAK_1			(1 << 4)
#define	FIX_NAK_2			(1 << 3)
389
390
	TWSI			= 0xd2,
	MCU			= 0xd3,
Hayes Wang's avatar
Hayes Wang committed
391
#define	NOW_IS_OOB			(1 << 7)
392
393
#define	EN_NDP				(1 << 3)
#define	EN_OOB_RESET			(1 << 2)
394
395
396
397
398
399
400
	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
401
402
};

403
enum rtl8168_registers {
Hayes Wang's avatar
Hayes Wang committed
404
405
	LED_FREQ		= 0x1a,
	EEE_LED			= 0x1b,
françois romieu's avatar
françois romieu committed
406
407
408
409
410
411
412
	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
413
414
415
416
417
418
419
#define ERIAR_EXGMAC			(0x00 << ERIAR_TYPE_SHIFT)
#define ERIAR_MSIX			(0x01 << ERIAR_TYPE_SHIFT)
#define ERIAR_ASF			(0x02 << ERIAR_TYPE_SHIFT)
#define ERIAR_MASK_SHIFT		12
#define ERIAR_MASK_0001			(0x1 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_0011			(0x3 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_1111			(0xf << ERIAR_MASK_SHIFT)
420
421
422
423
424
425
426
427
428
429
430
	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
hayeswang's avatar
hayeswang committed
431
432
	RDSAR1			= 0xd0,	/* 8168c only. Undocumented on 8168dp */
	MISC			= 0xf0,	/* 8168e only. */
Francois Romieu's avatar
Francois Romieu committed
433
#define TXPLA_RST			(1 << 29)
Hayes Wang's avatar
Hayes Wang committed
434
#define PWM_EN				(1 << 22)
435
436
};

Francois Romieu's avatar
Francois Romieu committed
437
enum rtl_register_content {
Linus Torvalds's avatar
Linus Torvalds committed
438
	/* InterruptStatusBits */
Francois Romieu's avatar
Francois Romieu committed
439
440
441
442
443
444
445
446
447
448
449
	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
450
451

	/* RxStatusDesc */
452
	RxBOVF	= (1 << 24),
453
454
455
456
457
	RxFOVF	= (1 << 23),
	RxRWT	= (1 << 22),
	RxRES	= (1 << 21),
	RxRUNT	= (1 << 20),
	RxCRC	= (1 << 19),
Linus Torvalds's avatar
Linus Torvalds committed
458
459

	/* ChipCmdBits */
Hayes Wang's avatar
Hayes Wang committed
460
	StopReq		= 0x80,
Francois Romieu's avatar
Francois Romieu committed
461
462
463
464
	CmdReset	= 0x10,
	CmdRxEnb	= 0x08,
	CmdTxEnb	= 0x04,
	RxBufEmpty	= 0x01,
Linus Torvalds's avatar
Linus Torvalds committed
465

466
467
468
469
470
	/* 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
471
	/* Cfg9346Bits */
Francois Romieu's avatar
Francois Romieu committed
472
473
	Cfg9346_Lock	= 0x00,
	Cfg9346_Unlock	= 0xc0,
Linus Torvalds's avatar
Linus Torvalds committed
474
475

	/* rx_mode_bits */
Francois Romieu's avatar
Francois Romieu committed
476
477
478
479
480
481
	AcceptErr	= 0x20,
	AcceptRunt	= 0x10,
	AcceptBroadcast	= 0x08,
	AcceptMulticast	= 0x04,
	AcceptMyPhys	= 0x02,
	AcceptAllPhys	= 0x01,
482
#define RX_CONFIG_ACCEPT_MASK		0x3f
Linus Torvalds's avatar
Linus Torvalds committed
483
484
485
486
487

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

488
	/* Config1 register p.24 */
489
490
491
492
493
494
	LEDS1		= (1 << 7),
	LEDS0		= (1 << 6),
	Speed_down	= (1 << 4),
	MEMMAP		= (1 << 3),
	IOMAP		= (1 << 2),
	VPD		= (1 << 1),
495
496
	PMEnable	= (1 << 0),	/* Power Management Enable */

497
	/* Config2 register p. 25 */
498
	MSIEnable	= (1 << 5),	/* 8169 only. Reserved in the 8168. */
499
500
501
	PCI_Clock_66MHz = 0x01,
	PCI_Clock_33MHz = 0x00,

Francois Romieu's avatar
Francois Romieu committed
502
503
504
	/* 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
505
	Jumbo_En0	= (1 << 2),	/* 8168 only. Reserved in the 8168b */
506
	Beacon_en	= (1 << 0),	/* 8168 only. Reserved in the 8168b */
Francois Romieu's avatar
Francois Romieu committed
507

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

511
	/* Config5 register p.27 */
Francois Romieu's avatar
Francois Romieu committed
512
513
514
	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
515
	Spi_en		= (1 << 3),
Francois Romieu's avatar
Francois Romieu committed
516
	LanWake		= (1 << 1),	/* LanWake enable/disable */
517
518
	PMEStatus	= (1 << 0),	/* PME status can be reset by PCI RST# */

Linus Torvalds's avatar
Linus Torvalds committed
519
520
521
522
523
524
525
526
527
	/* TBICSR p.28 */
	TBIReset	= 0x80000000,
	TBILoopback	= 0x40000000,
	TBINwEnable	= 0x20000000,
	TBINwRestart	= 0x10000000,
	TBILinkOk	= 0x02000000,
	TBINwComplete	= 0x01000000,

	/* CPlusCmd p.31 */
528
529
530
531
532
533
534
535
536
537
	EnableBist	= (1 << 15),	// 8168 8101
	Mac_dbgo_oe	= (1 << 14),	// 8168 8101
	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
538
539
540
541
	RxVlan		= (1 << 6),
	RxChkSum	= (1 << 5),
	PCIDAC		= (1 << 4),
	PCIMulRW	= (1 << 3),
542
543
544
545
	INTT_0		= 0x0000,	// 8168
	INTT_1		= 0x0001,	// 8168
	INTT_2		= 0x0002,	// 8168
	INTT_3		= 0x0003,	// 8168
Linus Torvalds's avatar
Linus Torvalds committed
546
547

	/* rtl8169_PHYstatus */
Francois Romieu's avatar
Francois Romieu committed
548
549
550
551
552
553
554
555
	TBI_Enable	= 0x80,
	TxFlowCtrl	= 0x40,
	RxFlowCtrl	= 0x20,
	_1000bpsF	= 0x10,
	_100bps		= 0x08,
	_10bps		= 0x04,
	LinkStatus	= 0x02,
	FullDup		= 0x01,
Linus Torvalds's avatar
Linus Torvalds committed
556
557

	/* _TBICSRBit */
Francois Romieu's avatar
Francois Romieu committed
558
	TBILinkOK	= 0x02000000,
559
560

	/* DumpCounterCommand */
Francois Romieu's avatar
Francois Romieu committed
561
	CounterDump	= 0x8,
Linus Torvalds's avatar
Linus Torvalds committed
562
563
};

Francois Romieu's avatar
Francois Romieu committed
564
565
enum rtl_desc_bit {
	/* First doubleword. */
Linus Torvalds's avatar
Linus Torvalds committed
566
567
568
569
	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
570
571
572
573
574
575
576
};

/* 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
577

Francois Romieu's avatar
Francois Romieu committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
	/* 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 {
	/* 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 */
};
Linus Torvalds's avatar
Linus Torvalds committed
599

Francois Romieu's avatar
Francois Romieu committed
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
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 {
Linus Torvalds's avatar
Linus Torvalds committed
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
	/* Rx private */
	PID1		= (1 << 18), /* Protocol ID bit 1/2 */
	PID0		= (1 << 17), /* Protocol ID bit 2/2 */

#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

struct TxDesc {
645
646
647
	__le32 opts1;
	__le32 opts2;
	__le64 addr;
Linus Torvalds's avatar
Linus Torvalds committed
648
649
650
};

struct RxDesc {
651
652
653
	__le32 opts1;
	__le32 opts2;
	__le64 addr;
Linus Torvalds's avatar
Linus Torvalds committed
654
655
656
657
658
659
660
661
};

struct ring_info {
	struct sk_buff	*skb;
	u32		len;
	u8		__pad[sizeof(void *) - sizeof(u32)];
};

662
enum features {
663
664
665
	RTL_FEATURE_WOL		= (1 << 0),
	RTL_FEATURE_MSI		= (1 << 1),
	RTL_FEATURE_GMII	= (1 << 2),
666
667
};

668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
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;
};

684
enum rtl_flag {
685
	RTL_FLAG_TASK_ENABLED,
686
687
688
689
690
691
	RTL_FLAG_TASK_SLOW_PENDING,
	RTL_FLAG_TASK_RESET_PENDING,
	RTL_FLAG_TASK_PHY_PENDING,
	RTL_FLAG_MAX
};

Junchang Wang's avatar
Junchang Wang committed
692
693
694
695
696
697
struct rtl8169_stats {
	u64			packets;
	u64			bytes;
	struct u64_stats_sync	syncp;
};

Linus Torvalds's avatar
Linus Torvalds committed
698
699
struct rtl8169_private {
	void __iomem *mmio_addr;	/* memory map physical address */
Francois Romieu's avatar
Francois Romieu committed
700
	struct pci_dev *pci_dev;
David Howells's avatar
David Howells committed
701
	struct net_device *dev;
702
	struct napi_struct napi;
703
	u32 msg_enable;
Francois Romieu's avatar
Francois Romieu committed
704
705
	u16 txd_version;
	u16 mac_version;
Linus Torvalds's avatar
Linus Torvalds committed
706
707
708
709
	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;
	u32 dirty_tx;
Junchang Wang's avatar
Junchang Wang committed
710
711
	struct rtl8169_stats rx_stats;
	struct rtl8169_stats tx_stats;
Linus Torvalds's avatar
Linus Torvalds committed
712
713
714
715
	struct TxDesc *TxDescArray;	/* 256-aligned Tx descriptor ring */
	struct RxDesc *RxDescArray;	/* 256-aligned Rx descriptor ring */
	dma_addr_t TxPhyAddr;
	dma_addr_t RxPhyAddr;
716
	void *Rx_databuff[NUM_RX_DESC];	/* Rx data buffers */
Linus Torvalds's avatar
Linus Torvalds committed
717
718
719
	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
	struct timer_list timer;
	u16 cp_cmd;
720
721

	u16 event_slow;
722
723
724
725
726
727

	struct mdio_ops {
		void (*write)(void __iomem *, int, int);
		int (*read)(void __iomem *, int);
	} mdio_ops;

françois romieu's avatar
françois romieu committed
728
729
730
731
732
	struct pll_power_ops {
		void (*down)(struct rtl8169_private *);
		void (*up)(struct rtl8169_private *);
	} pll_power_ops;

Francois Romieu's avatar
Francois Romieu committed
733
734
735
736
737
	struct jumbo_ops {
		void (*enable)(struct rtl8169_private *);
		void (*disable)(struct rtl8169_private *);
	} jumbo_ops;

738
739
740
741
742
	struct csi_ops {
		void (*write)(void __iomem *, int, int);
		u32 (*read)(void __iomem *, int);
	} csi_ops;

743
	int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv);
744
	int (*get_settings)(struct net_device *, struct ethtool_cmd *);
745
	void (*phy_reset_enable)(struct rtl8169_private *tp);
746
	void (*hw_start)(struct net_device *);
747
	unsigned int (*phy_reset_pending)(struct rtl8169_private *tp);
Linus Torvalds's avatar
Linus Torvalds committed
748
	unsigned int (*link_ok)(void __iomem *);
749
	int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
750
751

	struct {
752
753
		DECLARE_BITMAP(flags, RTL_FLAG_MAX);
		struct mutex mutex;
754
755
756
		struct work_struct work;
	} wk;

757
	unsigned features;
758
759

	struct mii_if_info mii;
760
	struct rtl8169_counters counters;
761
	u32 saved_wolopts;
762
	u32 opts1_mask;
763

764
765
	struct rtl_fw {
		const struct firmware *fw;
766
767
768
769
770
771
772
773
774

#define RTL_VER_SIZE		32

		char version[RTL_VER_SIZE];

		struct rtl_fw_phy_action {
			__le32 *code;
			size_t size;
		} phy_action;
775
	} *rtl_fw;
776
#define RTL_FIRMWARE_UNKNOWN	ERR_PTR(-EAGAIN)
Linus Torvalds's avatar
Linus Torvalds committed
777
778
};

779
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
Linus Torvalds's avatar
Linus Torvalds committed
780
781
MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
module_param(use_dac, int, 0);
782
MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
783
784
module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
Linus Torvalds's avatar
Linus Torvalds committed
785
786
MODULE_LICENSE("GPL");
MODULE_VERSION(RTL8169_VERSION);
787
788
MODULE_FIRMWARE(FIRMWARE_8168D_1);
MODULE_FIRMWARE(FIRMWARE_8168D_2);
hayeswang's avatar
hayeswang committed
789
790
MODULE_FIRMWARE(FIRMWARE_8168E_1);
MODULE_FIRMWARE(FIRMWARE_8168E_2);
791
MODULE_FIRMWARE(FIRMWARE_8168E_3);
792
MODULE_FIRMWARE(FIRMWARE_8105E_1);
793
794
MODULE_FIRMWARE(FIRMWARE_8168F_1);
MODULE_FIRMWARE(FIRMWARE_8168F_2);
795
MODULE_FIRMWARE(FIRMWARE_8402_1);
796
MODULE_FIRMWARE(FIRMWARE_8411_1);
Linus Torvalds's avatar
Linus Torvalds committed
797

798
799
800
801
802
803
804
805
806
807
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);
}

Francois Romieu's avatar
Francois Romieu committed
808
809
810
811
812
813
814
815
816
817
818
819
820
static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
{
	int cap = pci_pcie_cap(pdev);

	if (cap) {
		u16 ctl;

		pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
		ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
		pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
	}
}

françois romieu's avatar
françois romieu committed
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
{
	void __iomem *ioaddr = tp->mmio_addr;
	int i;

	RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
	for (i = 0; i < 20; i++) {
		udelay(100);
		if (RTL_R32(OCPAR) & OCPAR_FLAG)
			break;
	}
	return RTL_R32(OCPDR);
}

static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
{
	void __iomem *ioaddr = tp->mmio_addr;
	int i;

	RTL_W32(OCPDR, data);
	RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
	for (i = 0; i < 20; i++) {
		udelay(100);
		if ((RTL_R32(OCPAR) & OCPAR_FLAG) == 0)
			break;
	}
}

849
static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
françois romieu's avatar
françois romieu committed
850
{
851
	void __iomem *ioaddr = tp->mmio_addr;
françois romieu's avatar
françois romieu committed
852
853
854
855
856
857
858
	int i;

	RTL_W8(ERIDR, cmd);
	RTL_W32(ERIAR, 0x800010e8);
	msleep(2);
	for (i = 0; i < 5; i++) {
		udelay(100);
859
		if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
françois romieu's avatar
françois romieu committed
860
861
862
			break;
	}

863
	ocp_write(tp, 0x1, 0x30, 0x00000001);
françois romieu's avatar
françois romieu committed
864
865
866
867
868
869
}

#define OOB_CMD_RESET		0x00
#define OOB_CMD_DRIVER_START	0x05
#define OOB_CMD_DRIVER_STOP	0x06

Francois Romieu's avatar
Francois Romieu committed
870
871
872
873
874
static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp)
{
	return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10;
}

françois romieu's avatar
françois romieu committed
875
876
static void rtl8168_driver_start(struct rtl8169_private *tp)
{
Francois Romieu's avatar
Francois Romieu committed
877
	u16 reg;
françois romieu's avatar
françois romieu committed
878
879
880
881
	int i;

	rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);

Francois Romieu's avatar
Francois Romieu committed
882
	reg = rtl8168_get_ocp_reg(tp);
883

françois romieu's avatar
françois romieu committed
884
885
	for (i = 0; i < 10; i++) {
		msleep(10);
886
		if (ocp_read(tp, 0x0f, reg) & 0x00000800)
françois romieu's avatar
françois romieu committed
887
888
889
890
891
892
			break;
	}
}

static void rtl8168_driver_stop(struct rtl8169_private *tp)
{
Francois Romieu's avatar
Francois Romieu committed
893
	u16 reg;
françois romieu's avatar
françois romieu committed
894
895
896
897
	int i;

	rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);

Francois Romieu's avatar
Francois Romieu committed
898
	reg = rtl8168_get_ocp_reg(tp);
899

françois romieu's avatar
françois romieu committed
900
901
	for (i = 0; i < 10; i++) {
		msleep(10);
902
		if ((ocp_read(tp, 0x0f, reg) & 0x00000800) == 0)
françois romieu's avatar
françois romieu committed
903
904
905
906
			break;
	}
}

907
908
static int r8168dp_check_dash(struct rtl8169_private *tp)
{
Francois Romieu's avatar
Francois Romieu committed
909
	u16 reg = rtl8168_get_ocp_reg(tp);
910

Francois Romieu's avatar
Francois Romieu committed
911
	return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0;
912
}
françois romieu's avatar
françois romieu committed
913

914
static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
Linus Torvalds's avatar
Linus Torvalds committed
915
916
917
{
	int i;

918
	RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
Linus Torvalds's avatar
Linus Torvalds committed
919

920
	for (i = 20; i > 0; i--) {
Francois Romieu's avatar
Francois Romieu committed
921
922
923
924
		/*
		 * Check if the RTL8169 has completed writing to the specified
		 * MII register.
		 */
925
		if (!(RTL_R32(PHYAR) & 0x80000000))
Linus Torvalds's avatar
Linus Torvalds committed
926
			break;
927
		udelay(25);
Linus Torvalds's avatar
Linus Torvalds committed
928
	}
929
	/*
930
931
	 * According to hardware specs a 20us delay is required after write
	 * complete indication, but before sending next command.
932
	 */
933
	udelay(20);
Linus Torvalds's avatar
Linus Torvalds committed
934
935
}

936
static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr)
Linus Torvalds's avatar
Linus Torvalds committed
937
938
939
{
	int i, value = -1;

940
	RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
Linus Torvalds's avatar
Linus Torvalds committed
941

942
	for (i = 20; i > 0; i--) {
Francois Romieu's avatar
Francois Romieu committed
943
944
945
946
		/*
		 * Check if the RTL8169 has completed retrieving data from
		 * the specified MII register.
		 */
Linus Torvalds's avatar
Linus Torvalds committed
947
		if (RTL_R32(PHYAR) & 0x80000000) {
948
			value = RTL_R32(PHYAR) & 0xffff;
Linus Torvalds's avatar
Linus Torvalds committed
949
950
			break;
		}
951
		udelay(25);
Linus Torvalds's avatar
Linus Torvalds committed
952
	}
953
954
955
956
957
958
	/*
	 * 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
959
960
961
	return value;
}

962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data)
{
	int i;

	RTL_W32(OCPDR, data |
		((reg_addr & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
	RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD);
	RTL_W32(EPHY_RXER_NUM, 0);

	for (i = 0; i < 100; i++) {
		mdelay(1);
		if (!(RTL_R32(OCPAR) & OCPAR_FLAG))
			break;
	}
}

static void r8168dp_1_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{
	r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD |
		(value & OCPDR_DATA_MASK));
}

static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr)
{
	int i;

	r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD);

	mdelay(1);
	RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD);
	RTL_W32(EPHY_RXER_NUM, 0);

	for (i = 0; i < 100; i++) {
		mdelay(1);
		if (RTL_R32(OCPAR) & OCPAR_FLAG)
			break;
	}

	return RTL_R32(OCPDR) & OCPDR_DATA_MASK;
}

françois romieu's avatar
françois romieu committed
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
#define R8168DP_1_MDIO_ACCESS_BIT	0x00020000

static void r8168dp_2_mdio_start(void __iomem *ioaddr)
{
	RTL_W32(0xd0, RTL_R32(0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT);
}

static void r8168dp_2_mdio_stop(void __iomem *ioaddr)
{
	RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT);
}

static void r8168dp_2_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{
	r8168dp_2_mdio_start(ioaddr);

	r8169_mdio_write(ioaddr, reg_addr, value);

	r8168dp_2_mdio_stop(ioaddr);
}

static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr)
{
	int value;

	r8168dp_2_mdio_start(ioaddr);

	value = r8169_mdio_read(ioaddr, reg_addr);

	r8168dp_2_mdio_stop(ioaddr);

	return value;
}

1037
static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val)
1038
{
1039
	tp->mdio_ops.write(tp->mmio_addr, location, val);
1040
1041
}

1042
1043
static int rtl_readphy(struct rtl8169_private *tp, int location)
{
1044
	return tp->mdio_ops.read(tp->mmio_addr, location);
1045
1046
1047
1048
1049
1050
1051
1052
}

static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value)
{
	rtl_writephy(tp, reg_addr, rtl_readphy(tp, reg_addr) | value);
}

static void rtl_w1w0_phy(struct rtl8169_private *tp, int reg_addr, int p, int m)
1053
1054
1055
{
	int val;

1056
1057
	val = rtl_readphy(tp, reg_addr);
	rtl_writephy(tp, reg_addr, (val | p) & ~m);
1058
1059
}

1060
1061
1062
1063
1064
static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
			   int val)
{
	struct rtl8169_private *tp = netdev_priv(dev);

1065
	rtl_writephy(tp, location, val);
1066
1067
1068
1069
1070
1071
}

static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
{
	struct rtl8169_private *tp = netdev_priv(dev);

1072
	return rtl_readphy(tp, location);
1073
1074
}

1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
{
	unsigned int i;

	RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
		(reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);

	for (i = 0; i < 100; i++) {
		if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
			break;
		udelay(10);
	}
}

static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
{
	u16 value = 0xffff;
	unsigned int i;

	RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);

	for (i = 0; i < 100; i++) {
		if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
			value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
			break;
		}
		udelay(10);
	}

	return value;
}

Hayes Wang's avatar
Hayes Wang committed
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
static
void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type)
{
	unsigned int i;

	BUG_ON((addr & 3) || (mask == 0));
	RTL_W32(ERIDR, val);
	RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr);

	for (i = 0; i < 100; i++) {
		if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
			break;
		udelay(100);
	}
}

static u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type)
{
	u32 value = ~0x00;
	unsigned int i;

	RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr);

	for (i = 0; i < 100; i++) {
		if (RTL_R32(ERIAR) & ERIAR_FLAG) {
			value = RTL_R32(ERIDR);
			break;
		}
		udelay(100);
	}

	return value;
}

static void
rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type)
{
	u32 val;

	val = rtl_eri_read(ioaddr, addr, type);
	rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type);
}

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
struct exgmac_reg {
	u16 addr;
	u16 mask;
	u32 val;
};

static void rtl_write_exgmac_batch(void __iomem *ioaddr,
				   const struct exgmac_reg *r, int len)
{
	while (len-- > 0) {
		rtl_eri_write(ioaddr, r->addr, r->mask, r->val, ERIAR_EXGMAC);
		r++;
	}
}

1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
{
	u8 value = 0xff;
	unsigned int i;

	RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);

	for (i = 0; i < 300; i++) {
		if (RTL_R32(EFUSEAR) & EFUSEAR_FLAG) {
			value = RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK;
			break;
		}
		udelay(100);
	}

	return value;
}

Francois Romieu's avatar
Francois Romieu committed
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
static u16 rtl_get_events(struct rtl8169_private *tp)
{
	void __iomem *ioaddr = tp->mmio_addr;

	return RTL_R16(IntrStatus);
}

static void rtl_ack_events(struct rtl8169_private *tp, u16 bits)
{
	void __iomem *ioaddr = tp->mmio_addr;

	RTL_W16(IntrStatus, bits);
	mmiowb();
}

static void rtl_irq_disable(struct rtl8169_private *tp)
{
	void __iomem *ioaddr = tp->mmio_addr;

	RTL_W16(IntrMask, 0);
	mmiowb();
}

1206
1207
1208
1209
1210
1211
1212
static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits)
{
	void __iomem *ioaddr = tp->mmio_addr;

	RTL_W16(IntrMask, bits);
}

1213
1214
1215
1216
1217
1218
1219
1220
1221
#define RTL_EVENT_NAPI_RX	(RxOK | RxErr)
#define RTL_EVENT_NAPI_TX	(TxOK | TxErr)
#define RTL_EVENT_NAPI		(RTL_EVENT_NAPI_RX | RTL_EVENT_NAPI_TX)

static void rtl_irq_enable_all(struct rtl8169_private *tp)
{
	rtl_irq_enable(tp, RTL_EVENT_NAPI | tp->event_slow);
}

1222
static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp)
Linus Torvalds's avatar
Linus Torvalds committed
1223
{
1224
	void __iomem *ioaddr = tp->mmio_addr;
Linus Torvalds's avatar
Linus Torvalds committed
1225

Francois Romieu's avatar
Francois Romieu committed
1226
	rtl_irq_disable(tp);
1227
	rtl_ack_events(tp, RTL_EVENT_NAPI | tp->event_slow);
1228
	RTL_R8(ChipCmd);
Linus Torvalds's avatar
Linus Torvalds committed
1229
1230
}

1231
static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp)
Linus Torvalds's avatar
Linus Torvalds committed
1232
{
1233
1234
	void __iomem *ioaddr = tp->mmio_addr;

Linus Torvalds's avatar
Linus Torvalds committed
1235
1236
1237
	return RTL_R32(TBICSR) & TBIReset;
}

1238
static unsigned int rtl8169_xmii_reset_pending(struct rtl8169_private *tp)
Linus Torvalds's avatar
Linus Torvalds committed
1239
{
1240
	return rtl_readphy(tp, MII_BMCR) & BMCR_RESET;
Linus Torvalds's avatar
Linus Torvalds committed
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
}

static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr)
{
	return RTL_R32(TBICSR) & TBILinkOk;
}

static unsigned int rtl8169_xmii_link_ok(void __iomem *ioaddr)
{
	return RTL_R8(PHYstatus) & LinkStatus;
}

1253
static void rtl8169_tbi_reset_enable(struct rtl8169_private *tp)
Linus Torvalds's avatar
Linus Torvalds committed
1254
{
1255
1256
	void __iomem *ioaddr = tp->mmio_addr;

Linus Torvalds's avatar
Linus Torvalds committed
1257
1258
1259
	RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset);
}

1260
static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp)
Linus Torvalds's avatar
Linus Torvalds committed
1261
1262
1263
{
	unsigned int val;

1264
1265
	val = rtl_readphy(tp, MII_BMCR) | BMCR_RESET;
	rtl_writephy(tp, MII_BMCR, val & 0xffff);
Linus Torvalds's avatar
Linus Torvalds committed
1266