8139too.c 70.9 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*

	8139too.c: A RealTek RTL-8139 Fast Ethernet driver for Linux.

	Maintained by Jeff Garzik <jgarzik@pobox.com>
	Copyright 2000-2002 Jeff Garzik

	Much code comes from Donald Becker's rtl8139.c driver,
	versions 1.13 and older.  This driver was originally based
	on rtl8139.c version 1.07.  Header of rtl8139.c version 1.13:

	-----<snip>-----

        	Written 1997-2001 by Donald Becker.
		This software may be used and distributed according to the
		terms of the GNU General Public License (GPL), incorporated
		herein by reference.  Drivers based on or derived from this
		code fall under the GPL and must retain the authorship,
		copyright and license notice.  This file is not a complete
		program and may only be used when the entire operating
		system is licensed under the GPL.

		This driver is for boards based on the RTL8129 and RTL8139
		PCI ethernet chips.

		The author may be reached as becker@scyld.com, or C/O Scyld
		Computing Corporation 410 Severn Ave., Suite 210 Annapolis
		MD 21403

		Support and updates available at
		http://www.scyld.com/network/rtl8139.html

		Twister-tuning table provided by Kinston
		<shangh@realtek.com.tw>.

	-----<snip>-----

	This software may be used and distributed according to the terms
	of the GNU General Public License, incorporated herein by reference.

	Contributors:

		Donald Becker - he wrote the original driver, kudos to him!
		(but please don't e-mail him for support, this isn't his driver)

		Tigran Aivazian - bug fixes, skbuff free cleanup

		Martin Mares - suggestions for PCI cleanup

		David S. Miller - PCI DMA and softnet updates

		Ernst Gill - fixes ported from BSD driver

		Daniel Kobras - identified specific locations of
			posted MMIO write bugginess

		Gerard Sharp - bug fix, testing and feedback

		David Ford - Rx ring wrap fix

		Dan DeMaggio - swapped RTL8139 cards with me, and allowed me
		to find and fix a crucial bug on older chipsets.

		Donald Becker/Chris Butterworth/Marcus Westergren -
		Noticed various Rx packet size-related buglets.

		Santiago Garcia Mantinan - testing and feedback

		Jens David - 2.2.x kernel backports

		Martin Dennett - incredibly helpful insight on undocumented
		features of the 8139 chips

		Jean-Jacques Michel - bug fix

76
		Tobias Ringström - Rx interrupt status checking suggestion
Linus Torvalds's avatar
Linus Torvalds committed
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

		Andrew Morton - Clear blocked signals, avoid
		buffer overrun setting current->comm.

		Kalle Olavi Niemitalo - Wake-on-LAN ioctls

		Robert Kuebel - Save kernel thread from dying on any signal.

	Submitting bug reports:

		"rtl8139-diag -mmmaaavvveefN" output
		enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log

*/

92
93
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

Linus Torvalds's avatar
Linus Torvalds committed
94
#define DRV_NAME	"8139too"
95
#define DRV_VERSION	"0.9.28"
Linus Torvalds's avatar
Linus Torvalds committed
96
97
98
99
100
101
102


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/compiler.h>
#include <linux/pci.h>
#include <linux/init.h>
103
#include <linux/interrupt.h>
Linus Torvalds's avatar
Linus Torvalds committed
104
105
106
107
108
109
110
111
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/completion.h>
#include <linux/crc32.h>
Márton Németh's avatar
Márton Németh committed
112
113
#include <linux/io.h>
#include <linux/uaccess.h>
114
#include <linux/gfp.h>
Linus Torvalds's avatar
Linus Torvalds committed
115
116
117
118
119
120
121
122
123
124
#include <asm/irq.h>

#define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION

/* Default Message level */
#define RTL8139_DEF_MSG_ENABLE   (NETIF_MSG_DRV   | \
                                 NETIF_MSG_PROBE  | \
                                 NETIF_MSG_LINK)


125
126
/* define to 1, 2 or 3 to enable copious debugging info */
#define RTL8139_DEBUG 0
Linus Torvalds's avatar
Linus Torvalds committed
127
128
129
130
131
132
133
134
135

/* define to 1 to disable lightweight runtime debugging checks */
#undef RTL8139_NDEBUG


#ifdef RTL8139_NDEBUG
#  define assert(expr) do {} while (0)
#else
#  define assert(expr) \
136
137
138
        if (unlikely(!(expr))) {				\
		pr_err("Assertion failed! %s,%s,%s,line=%d\n",	\
		       #expr, __FILE__, __func__, __LINE__);	\
Linus Torvalds's avatar
Linus Torvalds committed
139
140
141
142
143
144
145
146
147
148
        }
#endif


/* A few user-configurable values. */
/* media options */
#define MAX_UNITS 8
static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};

149
150
/* Whether to use MMIO or PIO. Default to MMIO. */
#ifdef CONFIG_8139TOO_PIO
151
static bool use_io = true;
152
#else
153
static bool use_io = false;
154
155
#endif

Linus Torvalds's avatar
Linus Torvalds committed
156
157
158
159
160
161
162
163
/* 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.  */
static int multicast_filter_limit = 32;

/* bitmapped message enable number */
static int debug = -1;

/*
164
 * Receive ring size
Linus Torvalds's avatar
Linus Torvalds committed
165
166
167
 * Warning: 64K ring has hardware issues and may lock up.
 */
#if defined(CONFIG_SH_DREAMCAST)
Adrian McMenamin's avatar
Adrian McMenamin committed
168
#define RX_BUF_IDX 0	/* 8K ring */
Linus Torvalds's avatar
Linus Torvalds committed
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#else
#define RX_BUF_IDX	2	/* 32K ring */
#endif
#define RX_BUF_LEN	(8192 << RX_BUF_IDX)
#define RX_BUF_PAD	16
#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */

#if RX_BUF_LEN == 65536
#define RX_BUF_TOT_LEN	RX_BUF_LEN
#else
#define RX_BUF_TOT_LEN	(RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
#endif

/* Number of Tx descriptor registers. */
#define NUM_TX_DESC	4

/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/
186
#define MAX_ETH_FRAME_SIZE	1792
Linus Torvalds's avatar
Linus Torvalds committed
187

188
189
190
/* max supported payload size */
#define MAX_ETH_DATA_SIZE	(MAX_ETH_FRAME_SIZE - ETH_HLEN - ETH_FCS_LEN)

Linus Torvalds's avatar
Linus Torvalds committed
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
#define TX_BUF_SIZE	MAX_ETH_FRAME_SIZE
#define TX_BUF_TOT_LEN	(TX_BUF_SIZE * NUM_TX_DESC)

/* PCI Tuning Parameters
   Threshold is bytes transferred to chip before transmission starts. */
#define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */

/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024, 7==end of packet. */
#define RX_FIFO_THRESH	7	/* Rx buffer level before first PCI xfer.  */
#define RX_DMA_BURST	7	/* Maximum PCI burst, '6' is 1024 */
#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
#define TX_RETRY	8	/* 0-15.  retries = 16 + (TX_RETRY * 16) */

/* Operational parameters that usually are not changed. */
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT  (6*HZ)


enum {
	HAS_MII_XCVR = 0x010000,
	HAS_CHIP_XCVR = 0x020000,
	HAS_LNK_CHNG = 0x040000,
};

#define RTL_NUM_STATS 4		/* number of ETHTOOL_GSTATS u64's */
#define RTL_REGS_VER 1		/* version of reg. data in ETHTOOL_GREGS */
#define RTL_MIN_IO_SIZE 0x80
#define RTL8139B_IO_SIZE 256

#define RTL8129_CAPS	HAS_MII_XCVR
Márton Németh's avatar
Márton Németh committed
222
#define RTL8139_CAPS	(HAS_CHIP_XCVR|HAS_LNK_CHNG)
Linus Torvalds's avatar
Linus Torvalds committed
223
224
225
226
227
228
229
230

typedef enum {
	RTL8139 = 0,
	RTL8129,
} board_t;


/* indexed by board_t, above */
231
static const struct {
Linus Torvalds's avatar
Linus Torvalds committed
232
233
	const char *name;
	u32 hw_flags;
234
} board_info[] = {
Linus Torvalds's avatar
Linus Torvalds committed
235
236
237
238
239
	{ "RealTek RTL8139", RTL8139_CAPS },
	{ "RealTek RTL8129", RTL8129_CAPS },
};


240
static const struct pci_device_id rtl8139_pci_tbl[] = {
Linus Torvalds's avatar
Linus Torvalds committed
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
	{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x1259, 0xa11e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
	{0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
259
	{0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
Linus Torvalds's avatar
Linus Torvalds committed
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

#ifdef CONFIG_SH_SECUREEDGE5410
	/* Bogus 8139 silicon reports 8129 without external PROM :-( */
	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
#endif
#ifdef CONFIG_8139TOO_8129
	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
#endif

	/* some crazy cards report invalid vendor ids like
	 * 0x0001 here.  The other ids are valid and constant,
	 * so we simply don't match on the main vendor id.
	 */
	{PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 },
	{PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, RTL8139 },
	{PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, RTL8139 },

	{0,}
};
MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);

static struct {
	const char str[ETH_GSTRING_LEN];
} ethtool_stats_keys[] = {
	{ "early_rx" },
	{ "tx_buf_mapped" },
	{ "tx_timeouts" },
	{ "rx_lost_in_ring" },
};

/* The rest of these values should never change. */

/* Symbolic offsets to registers. */
enum RTL8139_registers {
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
	MAC0		= 0,	 /* Ethernet hardware address. */
	MAR0		= 8,	 /* Multicast filter. */
	TxStatus0	= 0x10,	 /* Transmit status (Four 32bit registers). */
	TxAddr0		= 0x20,	 /* Tx descriptors (also four 32bit). */
	RxBuf		= 0x30,
	ChipCmd		= 0x37,
	RxBufPtr	= 0x38,
	RxBufAddr	= 0x3A,
	IntrMask	= 0x3C,
	IntrStatus	= 0x3E,
	TxConfig	= 0x40,
	RxConfig	= 0x44,
	Timer		= 0x48,	 /* A general-purpose counter. */
	RxMissed	= 0x4C,  /* 24 bits valid, write clears. */
	Cfg9346		= 0x50,
	Config0		= 0x51,
	Config1		= 0x52,
311
	TimerInt	= 0x54,
312
313
314
315
316
317
318
319
320
321
322
	MediaStatus	= 0x58,
	Config3		= 0x59,
	Config4		= 0x5A,	 /* absent on RTL-8139A */
	HltClk		= 0x5B,
	MultiIntr	= 0x5C,
	TxSummary	= 0x60,
	BasicModeCtrl	= 0x62,
	BasicModeStatus	= 0x64,
	NWayAdvert	= 0x66,
	NWayLPAR	= 0x68,
	NWayExpansion	= 0x6A,
Linus Torvalds's avatar
Linus Torvalds committed
323
	/* Undocumented registers, but required for proper operation. */
324
325
326
	FIFOTMS		= 0x70,	 /* FIFO Control and test. */
	CSCR		= 0x74,	 /* Chip Status and Configuration Register. */
	PARA78		= 0x78,
327
	FlashReg	= 0xD4,	/* Communication with Flash ROM, four bytes. */
328
329
	PARA7c		= 0x7c,	 /* Magic transceiver parameter register. */
	Config5		= 0xD8,	 /* absent on RTL-8139A */
Linus Torvalds's avatar
Linus Torvalds committed
330
331
332
};

enum ClearBitMasks {
333
334
335
	MultiIntrClear	= 0xF000,
	ChipCmdClear	= 0xE2,
	Config1Clear	= (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
Linus Torvalds's avatar
Linus Torvalds committed
336
337
338
};

enum ChipCmdBits {
339
340
341
342
	CmdReset	= 0x10,
	CmdRxEnb	= 0x08,
	CmdTxEnb	= 0x04,
	RxBufEmpty	= 0x01,
Linus Torvalds's avatar
Linus Torvalds committed
343
344
345
346
};

/* Interrupt register bits, using my own meaningful names. */
enum IntrStatusBits {
347
348
349
350
351
352
353
354
355
356
357
	PCIErr		= 0x8000,
	PCSTimeout	= 0x4000,
	RxFIFOOver	= 0x40,
	RxUnderrun	= 0x20,
	RxOverflow	= 0x10,
	TxErr		= 0x08,
	TxOK		= 0x04,
	RxErr		= 0x02,
	RxOK		= 0x01,

	RxAckBits	= RxFIFOOver | RxOverflow | RxOK,
Linus Torvalds's avatar
Linus Torvalds committed
358
359
360
};

enum TxStatusBits {
361
362
363
364
365
366
	TxHostOwns	= 0x2000,
	TxUnderrun	= 0x4000,
	TxStatOK	= 0x8000,
	TxOutOfWindow	= 0x20000000,
	TxAborted	= 0x40000000,
	TxCarrierLost	= 0x80000000,
Linus Torvalds's avatar
Linus Torvalds committed
367
368
};
enum RxStatusBits {
369
370
371
372
373
374
375
376
377
	RxMulticast	= 0x8000,
	RxPhysical	= 0x4000,
	RxBroadcast	= 0x2000,
	RxBadSymbol	= 0x0020,
	RxRunt		= 0x0010,
	RxTooLong	= 0x0008,
	RxCRCErr	= 0x0004,
	RxBadAlign	= 0x0002,
	RxStatusOK	= 0x0001,
Linus Torvalds's avatar
Linus Torvalds committed
378
379
380
381
};

/* Bits in RxConfig. */
enum rx_mode_bits {
382
383
384
385
386
387
	AcceptErr	= 0x20,
	AcceptRunt	= 0x10,
	AcceptBroadcast	= 0x08,
	AcceptMulticast	= 0x04,
	AcceptMyPhys	= 0x02,
	AcceptAllPhys	= 0x01,
Linus Torvalds's avatar
Linus Torvalds committed
388
389
390
391
392
};

/* Bits in TxConfig. */
enum tx_config_bits {
        /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
393
394
395
396
397
398
399
400
401
402
403
404
405
        TxIFGShift	= 24,
        TxIFG84		= (0 << TxIFGShift), /* 8.4us / 840ns (10 / 100Mbps) */
        TxIFG88		= (1 << TxIFGShift), /* 8.8us / 880ns (10 / 100Mbps) */
        TxIFG92		= (2 << TxIFGShift), /* 9.2us / 920ns (10 / 100Mbps) */
        TxIFG96		= (3 << TxIFGShift), /* 9.6us / 960ns (10 / 100Mbps) */

	TxLoopBack	= (1 << 18) | (1 << 17), /* enable loopback test mode */
	TxCRC		= (1 << 16),	/* DISABLE Tx pkt CRC append */
	TxClearAbt	= (1 << 0),	/* Clear abort (WO) */
	TxDMAShift	= 8, /* DMA burst value (0-7) is shifted X many bits */
	TxRetryShift	= 4, /* TXRR value (0-15) is shifted X many bits */

	TxVersionMask	= 0x7C800000, /* mask out version bits 30-26, 23 */
Linus Torvalds's avatar
Linus Torvalds committed
406
407
408
409
};

/* Bits in Config1 */
enum Config1Bits {
410
411
412
413
414
	Cfg1_PM_Enable	= 0x01,
	Cfg1_VPD_Enable	= 0x02,
	Cfg1_PIO	= 0x04,
	Cfg1_MMIO	= 0x08,
	LWAKE		= 0x10,		/* not on 8139, 8139A */
Linus Torvalds's avatar
Linus Torvalds committed
415
	Cfg1_Driver_Load = 0x20,
416
417
418
419
	Cfg1_LED0	= 0x40,
	Cfg1_LED1	= 0x80,
	SLEEP		= (1 << 1),	/* only on 8139, 8139A */
	PWRDN		= (1 << 0),	/* only on 8139, 8139A */
Linus Torvalds's avatar
Linus Torvalds committed
420
421
422
423
};

/* Bits in Config3 */
enum Config3Bits {
424
425
426
427
428
429
430
431
	Cfg3_FBtBEn   	= (1 << 0), /* 1	= Fast Back to Back */
	Cfg3_FuncRegEn	= (1 << 1), /* 1	= enable CardBus Function registers */
	Cfg3_CLKRUN_En	= (1 << 2), /* 1	= enable CLKRUN */
	Cfg3_CardB_En 	= (1 << 3), /* 1	= enable CardBus registers */
	Cfg3_LinkUp   	= (1 << 4), /* 1	= wake up on link up */
	Cfg3_Magic    	= (1 << 5), /* 1	= wake up on Magic Packet (tm) */
	Cfg3_PARM_En  	= (1 << 6), /* 0	= software can set twister parameters */
	Cfg3_GNTSel   	= (1 << 7), /* 1	= delay 1 clock from PCI GNT signal */
Linus Torvalds's avatar
Linus Torvalds committed
432
433
434
435
};

/* Bits in Config4 */
enum Config4Bits {
436
	LWPTN	= (1 << 2),	/* not on 8139, 8139A */
Linus Torvalds's avatar
Linus Torvalds committed
437
438
439
440
};

/* Bits in Config5 */
enum Config5Bits {
441
442
443
444
445
446
447
	Cfg5_PME_STS   	= (1 << 0), /* 1	= PCI reset resets PME_Status */
	Cfg5_LANWake   	= (1 << 1), /* 1	= enable LANWake signal */
	Cfg5_LDPS      	= (1 << 2), /* 0	= save power when link is down */
	Cfg5_FIFOAddrPtr= (1 << 3), /* Realtek internal SRAM testing */
	Cfg5_UWF        = (1 << 4), /* 1 = accept unicast wakeup frame */
	Cfg5_MWF        = (1 << 5), /* 1 = accept multicast wakeup frame */
	Cfg5_BWF        = (1 << 6), /* 1 = accept broadcast wakeup frame */
Linus Torvalds's avatar
Linus Torvalds committed
448
449
450
451
};

enum RxConfigBits {
	/* rx fifo threshold */
452
453
	RxCfgFIFOShift	= 13,
	RxCfgFIFONone	= (7 << RxCfgFIFOShift),
Linus Torvalds's avatar
Linus Torvalds committed
454
455

	/* Max DMA burst */
456
	RxCfgDMAShift	= 8,
Linus Torvalds's avatar
Linus Torvalds committed
457
458
459
	RxCfgDMAUnlimited = (7 << RxCfgDMAShift),

	/* rx ring buffer length */
460
461
462
463
	RxCfgRcv8K	= 0,
	RxCfgRcv16K	= (1 << 11),
	RxCfgRcv32K	= (1 << 12),
	RxCfgRcv64K	= (1 << 11) | (1 << 12),
Linus Torvalds's avatar
Linus Torvalds committed
464
465

	/* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
466
	RxNoWrap	= (1 << 7),
Linus Torvalds's avatar
Linus Torvalds committed
467
468
469
470
471
};

/* Twister tuning parameters from RealTek.
   Completely undocumented, but required to tune bad links on some boards. */
enum CSCRBits {
472
473
474
475
476
	CSCR_LinkOKBit		= 0x0400,
	CSCR_LinkChangeBit	= 0x0800,
	CSCR_LinkStatusBits	= 0x0f000,
	CSCR_LinkDownOffCmd	= 0x003c0,
	CSCR_LinkDownCmd	= 0x0f3c0,
Linus Torvalds's avatar
Linus Torvalds committed
477
478
479
};

enum Cfg9346Bits {
480
481
	Cfg9346_Lock	= 0x00,
	Cfg9346_Unlock	= 0xC0,
Linus Torvalds's avatar
Linus Torvalds committed
482
483
484
};

typedef enum {
485
	CH_8139	= 0,
Linus Torvalds's avatar
Linus Torvalds committed
486
487
488
489
490
491
492
493
494
495
496
497
	CH_8139_K,
	CH_8139A,
	CH_8139A_G,
	CH_8139B,
	CH_8130,
	CH_8139C,
	CH_8100,
	CH_8100B_8139D,
	CH_8101,
} chip_t;

enum chip_flags {
498
499
	HasHltClk	= (1 << 0),
	HasLWake	= (1 << 1),
Linus Torvalds's avatar
Linus Torvalds committed
500
501
502
503
504
505
506
};

#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
	(b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
#define HW_REVID_MASK	HW_REVID(1, 1, 1, 1, 1, 1, 1)

/* directly indexed by chip_t, above */
507
static const struct {
Linus Torvalds's avatar
Linus Torvalds committed
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
	const char *name;
	u32 version; /* from RTL8139C/RTL8139D docs */
	u32 flags;
} rtl_chip_info[] = {
	{ "RTL-8139",
	  HW_REVID(1, 0, 0, 0, 0, 0, 0),
	  HasHltClk,
	},

	{ "RTL-8139 rev K",
	  HW_REVID(1, 1, 0, 0, 0, 0, 0),
	  HasHltClk,
	},

	{ "RTL-8139A",
	  HW_REVID(1, 1, 1, 0, 0, 0, 0),
	  HasHltClk, /* XXX undocumented? */
	},

	{ "RTL-8139A rev G",
	  HW_REVID(1, 1, 1, 0, 0, 1, 0),
	  HasHltClk, /* XXX undocumented? */
	},

	{ "RTL-8139B",
	  HW_REVID(1, 1, 1, 1, 0, 0, 0),
	  HasLWake,
	},

	{ "RTL-8130",
	  HW_REVID(1, 1, 1, 1, 1, 0, 0),
	  HasLWake,
	},

	{ "RTL-8139C",
	  HW_REVID(1, 1, 1, 0, 1, 0, 0),
	  HasLWake,
	},

	{ "RTL-8100",
	  HW_REVID(1, 1, 1, 1, 0, 1, 0),
 	  HasLWake,
 	},

	{ "RTL-8100B/8139D",
	  HW_REVID(1, 1, 1, 0, 1, 0, 1),
554
555
	  HasHltClk /* XXX undocumented? */
	| HasLWake,
Linus Torvalds's avatar
Linus Torvalds committed
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
	},

	{ "RTL-8101",
	  HW_REVID(1, 1, 1, 0, 1, 1, 1),
	  HasLWake,
	},
};

struct rtl_extra_stats {
	unsigned long early_rx;
	unsigned long tx_buf_mapped;
	unsigned long tx_timeouts;
	unsigned long rx_lost_in_ring;
};

Junchang Wang's avatar
Junchang Wang committed
571
572
573
574
575
576
struct rtl8139_stats {
	u64	packets;
	u64	bytes;
	struct u64_stats_sync	syncp;
};

Linus Torvalds's avatar
Linus Torvalds committed
577
struct rtl8139_private {
578
579
580
581
582
583
584
585
586
	void __iomem		*mmio_addr;
	int			drv_flags;
	struct pci_dev		*pci_dev;
	u32			msg_enable;
	struct napi_struct	napi;
	struct net_device	*dev;

	unsigned char		*rx_ring;
	unsigned int		cur_rx;	/* RX buf index of next pkt */
Junchang Wang's avatar
Junchang Wang committed
587
	struct rtl8139_stats	rx_stats;
588
589
590
591
592
	dma_addr_t		rx_ring_dma;

	unsigned int		tx_flag;
	unsigned long		cur_tx;
	unsigned long		dirty_tx;
Junchang Wang's avatar
Junchang Wang committed
593
	struct rtl8139_stats	tx_stats;
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
	unsigned char		*tx_buf[NUM_TX_DESC];	/* Tx bounce buffers */
	unsigned char		*tx_bufs;	/* Tx bounce buffer region. */
	dma_addr_t		tx_bufs_dma;

	signed char		phys[4];	/* MII device addresses. */

				/* Twister tune state. */
	char			twistie, twist_row, twist_col;

	unsigned int		watchdog_fired : 1;
	unsigned int		default_port : 4; /* Last dev->if_port value. */
	unsigned int		have_thread : 1;

	spinlock_t		lock;
	spinlock_t		rx_lock;

	chip_t			chipset;
	u32			rx_config;
	struct rtl_extra_stats	xstats;

	struct delayed_work	thread;

	struct mii_if_info	mii;
	unsigned int		regs_len;
	unsigned long		fifo_copy_timeout;
Linus Torvalds's avatar
Linus Torvalds committed
619
620
621
622
623
624
625
};

MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

626
module_param(use_io, bool, 0);
627
MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
Linus Torvalds's avatar
Linus Torvalds committed
628
629
630
631
632
633
634
635
636
module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
module_param(debug, int, 0);
MODULE_PARM_DESC (debug, "8139too bitmapped message enable number");
MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");

637
static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
Linus Torvalds's avatar
Linus Torvalds committed
638
639
640
641
static int rtl8139_open (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location);
static void mdio_write (struct net_device *dev, int phy_id, int location,
			int val);
642
static void rtl8139_start_thread(struct rtl8139_private *tp);
Linus Torvalds's avatar
Linus Torvalds committed
643
644
static void rtl8139_tx_timeout (struct net_device *dev);
static void rtl8139_init_ring (struct net_device *dev);
645
646
static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
				       struct net_device *dev);
Linus Torvalds's avatar
Linus Torvalds committed
647
648
649
#ifdef CONFIG_NET_POLL_CONTROLLER
static void rtl8139_poll_controller(struct net_device *dev);
#endif
650
static int rtl8139_set_mac_address(struct net_device *dev, void *p);
651
static int rtl8139_poll(struct napi_struct *napi, int budget);
652
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
Linus Torvalds's avatar
Linus Torvalds committed
653
654
static int rtl8139_close (struct net_device *dev);
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
Junchang Wang's avatar
Junchang Wang committed
655
656
657
static struct rtnl_link_stats64 *rtl8139_get_stats64(struct net_device *dev,
						    struct rtnl_link_stats64
						    *stats);
Linus Torvalds's avatar
Linus Torvalds committed
658
659
660
static void rtl8139_set_rx_mode (struct net_device *dev);
static void __set_rx_mode (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev);
David Howells's avatar
David Howells committed
661
662
static void rtl8139_thread (struct work_struct *work);
static void rtl8139_tx_timeout_task(struct work_struct *work);
663
static const struct ethtool_ops rtl8139_ethtool_ops;
Linus Torvalds's avatar
Linus Torvalds committed
664
665
666

/* write MMIO register, with flush */
/* Flush avoids rtl8139 bug w/ posted MMIO writes */
667
668
669
#define RTL_W8_F(reg, val8)	do { iowrite8 ((val8), ioaddr + (reg)); ioread8 (ioaddr + (reg)); } while (0)
#define RTL_W16_F(reg, val16)	do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0)
#define RTL_W32_F(reg, val32)	do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0)
Linus Torvalds's avatar
Linus Torvalds committed
670
671

/* write MMIO register */
672
673
674
#define RTL_W8(reg, val8)	iowrite8 ((val8), ioaddr + (reg))
#define RTL_W16(reg, val16)	iowrite16 ((val16), ioaddr + (reg))
#define RTL_W32(reg, val32)	iowrite32 ((val32), ioaddr + (reg))
Linus Torvalds's avatar
Linus Torvalds committed
675
676

/* read MMIO register */
677
678
#define RTL_R8(reg)		ioread8 (ioaddr + (reg))
#define RTL_R16(reg)		ioread16 (ioaddr + (reg))
679
#define RTL_R32(reg)		ioread32 (ioaddr + (reg))
Linus Torvalds's avatar
Linus Torvalds committed
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726


static const u16 rtl8139_intr_mask =
	PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
	TxErr | TxOK | RxErr | RxOK;

static const u16 rtl8139_norx_intr_mask =
	PCIErr | PCSTimeout | RxUnderrun |
	TxErr | TxOK | RxErr ;

#if RX_BUF_IDX == 0
static const unsigned int rtl8139_rx_config =
	RxCfgRcv8K | RxNoWrap |
	(RX_FIFO_THRESH << RxCfgFIFOShift) |
	(RX_DMA_BURST << RxCfgDMAShift);
#elif RX_BUF_IDX == 1
static const unsigned int rtl8139_rx_config =
	RxCfgRcv16K | RxNoWrap |
	(RX_FIFO_THRESH << RxCfgFIFOShift) |
	(RX_DMA_BURST << RxCfgDMAShift);
#elif RX_BUF_IDX == 2
static const unsigned int rtl8139_rx_config =
	RxCfgRcv32K | RxNoWrap |
	(RX_FIFO_THRESH << RxCfgFIFOShift) |
	(RX_DMA_BURST << RxCfgDMAShift);
#elif RX_BUF_IDX == 3
static const unsigned int rtl8139_rx_config =
	RxCfgRcv64K |
	(RX_FIFO_THRESH << RxCfgFIFOShift) |
	(RX_DMA_BURST << RxCfgDMAShift);
#else
#error "Invalid configuration for 8139_RXBUF_IDX"
#endif

static const unsigned int rtl8139_tx_config =
	TxIFG96 | (TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift);

static void __rtl8139_cleanup_dev (struct net_device *dev)
{
	struct rtl8139_private *tp = netdev_priv(dev);
	struct pci_dev *pdev;

	assert (dev != NULL);
	assert (tp->pci_dev != NULL);
	pdev = tp->pci_dev;

	if (tp->mmio_addr)
727
		pci_iounmap (pdev, tp->mmio_addr);
Linus Torvalds's avatar
Linus Torvalds committed
728
729
730
731
732
733
734
735

	/* it's ok to call this even if we have no regions to free */
	pci_release_regions (pdev);

	free_netdev(dev);
}


736
static void rtl8139_chip_reset (void __iomem *ioaddr)
Linus Torvalds's avatar
Linus Torvalds committed
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
{
	int i;

	/* Soft reset the chip. */
	RTL_W8 (ChipCmd, CmdReset);

	/* Check that the chip has finished the reset. */
	for (i = 1000; i > 0; i--) {
		barrier();
		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
			break;
		udelay (10);
	}
}


753
static struct net_device *rtl8139_init_board(struct pci_dev *pdev)
Linus Torvalds's avatar
Linus Torvalds committed
754
{
755
	struct device *d = &pdev->dev;
756
	void __iomem *ioaddr;
Linus Torvalds's avatar
Linus Torvalds committed
757
758
759
760
	struct net_device *dev;
	struct rtl8139_private *tp;
	u8 tmp8;
	int rc, disable_dev_on_err = 0;
761
762
	unsigned int i, bar;
	unsigned long io_len;
Linus Torvalds's avatar
Linus Torvalds committed
763
	u32 version;
764
765
766
767
768
769
770
	static const struct {
		unsigned long mask;
		char *type;
	} res[] = {
		{ IORESOURCE_IO,  "PIO" },
		{ IORESOURCE_MEM, "MMIO" }
	};
Linus Torvalds's avatar
Linus Torvalds committed
771
772
773
774
775

	assert (pdev != NULL);

	/* dev and priv zeroed in alloc_etherdev */
	dev = alloc_etherdev (sizeof (*tp));
776
	if (dev == NULL)
Stephen Hemminger's avatar
Stephen Hemminger committed
777
		return ERR_PTR(-ENOMEM);
778

Linus Torvalds's avatar
Linus Torvalds committed
779
780
781
782
783
784
785
786
787
788
	SET_NETDEV_DEV(dev, &pdev->dev);

	tp = netdev_priv(dev);
	tp->pci_dev = pdev;

	/* enable device (incl. PCI PM wakeup and hotplug setup) */
	rc = pci_enable_device (pdev);
	if (rc)
		goto err_out;

789
	rc = pci_request_regions (pdev, DRV_NAME);
Linus Torvalds's avatar
Linus Torvalds committed
790
791
792
793
794
795
	if (rc)
		goto err_out;
	disable_dev_on_err = 1;

	pci_set_master (pdev);

796
797
798
	u64_stats_init(&tp->rx_stats.syncp);
	u64_stats_init(&tp->tx_stats.syncp);

799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
retry:
	/* PIO bar register comes first. */
	bar = !use_io;

	io_len = pci_resource_len(pdev, bar);

	dev_dbg(d, "%s region size = 0x%02lX\n", res[bar].type, io_len);

	if (!(pci_resource_flags(pdev, bar) & res[bar].mask)) {
		dev_err(d, "region #%d not a %s resource, aborting\n", bar,
			res[bar].type);
		rc = -ENODEV;
		goto err_out;
	}
	if (io_len < RTL_MIN_IO_SIZE) {
		dev_err(d, "Invalid PCI %s region size(s), aborting\n",
			res[bar].type);
		rc = -ENODEV;
		goto err_out;
	}

	ioaddr = pci_iomap(pdev, bar, 0);
	if (!ioaddr) {
		dev_err(d, "cannot map %s\n", res[bar].type);
		if (!use_io) {
			use_io = true;
825
			goto retry;
826
		}
827
828
		rc = -ENODEV;
		goto err_out;
Linus Torvalds's avatar
Linus Torvalds committed
829
	}
830
	tp->regs_len = io_len;
Linus Torvalds's avatar
Linus Torvalds committed
831
832
833
834
835
836
837
	tp->mmio_addr = ioaddr;

	/* Bring old chips out of low-power mode. */
	RTL_W8 (HltClk, 'R');

	/* check for missing/broken hardware */
	if (RTL_R32 (TxConfig) == 0xFFFFFFFF) {
838
		dev_err(&pdev->dev, "Chip not responding, ignoring board\n");
Linus Torvalds's avatar
Linus Torvalds committed
839
840
841
842
843
844
845
846
847
848
849
850
851
		rc = -EIO;
		goto err_out;
	}

	/* identify chip attached to board */
	version = RTL_R32 (TxConfig) & HW_REVID_MASK;
	for (i = 0; i < ARRAY_SIZE (rtl_chip_info); i++)
		if (version == rtl_chip_info[i].version) {
			tp->chipset = i;
			goto match;
		}

	/* if unknown chip, assume array element #0, original RTL-8139 in this case */
852
	i = 0;
853
	dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n");
854
	dev_dbg(&pdev->dev, "TxConfig = 0x%x\n", RTL_R32 (TxConfig));
Linus Torvalds's avatar
Linus Torvalds committed
855
856
857
	tp->chipset = 0;

match:
858
	pr_debug("chipset id (%d) == index %d, '%s'\n",
Linus Torvalds's avatar
Linus Torvalds committed
859
860
861
862
		 version, i, rtl_chip_info[i].name);

	if (tp->chipset >= CH_8139B) {
		u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
863
		pr_debug("PCI PM wakeup\n");
Linus Torvalds's avatar
Linus Torvalds committed
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
		if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
		    (tmp8 & LWAKE))
			new_tmp8 &= ~LWAKE;
		new_tmp8 |= Cfg1_PM_Enable;
		if (new_tmp8 != tmp8) {
			RTL_W8 (Cfg9346, Cfg9346_Unlock);
			RTL_W8 (Config1, tmp8);
			RTL_W8 (Cfg9346, Cfg9346_Lock);
		}
		if (rtl_chip_info[tp->chipset].flags & HasLWake) {
			tmp8 = RTL_R8 (Config4);
			if (tmp8 & LWPTN) {
				RTL_W8 (Cfg9346, Cfg9346_Unlock);
				RTL_W8 (Config4, tmp8 & ~LWPTN);
				RTL_W8 (Cfg9346, Cfg9346_Lock);
			}
		}
	} else {
882
		pr_debug("Old chip wakeup\n");
Linus Torvalds's avatar
Linus Torvalds committed
883
884
885
886
887
888
889
		tmp8 = RTL_R8 (Config1);
		tmp8 &= ~(SLEEP | PWRDN);
		RTL_W8 (Config1, tmp8);
	}

	rtl8139_chip_reset (ioaddr);

Stephen Hemminger's avatar
Stephen Hemminger committed
890
	return dev;
Linus Torvalds's avatar
Linus Torvalds committed
891
892
893
894
895

err_out:
	__rtl8139_cleanup_dev (dev);
	if (disable_dev_on_err)
		pci_disable_device (pdev);
Stephen Hemminger's avatar
Stephen Hemminger committed
896
	return ERR_PTR(rc);
Linus Torvalds's avatar
Linus Torvalds committed
897
898
}

Ben Greear's avatar
Ben Greear committed
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
static int rtl8139_set_features(struct net_device *dev, netdev_features_t features)
{
	struct rtl8139_private *tp = netdev_priv(dev);
	unsigned long flags;
	netdev_features_t changed = features ^ dev->features;
	void __iomem *ioaddr = tp->mmio_addr;

	if (!(changed & (NETIF_F_RXALL)))
		return 0;

	spin_lock_irqsave(&tp->lock, flags);

	if (changed & NETIF_F_RXALL) {
		int rx_mode = tp->rx_config;
		if (features & NETIF_F_RXALL)
			rx_mode |= (AcceptErr | AcceptRunt);
		else
			rx_mode &= ~(AcceptErr | AcceptRunt);
		tp->rx_config = rtl8139_rx_config | rx_mode;
		RTL_W32_F(RxConfig, tp->rx_config);
	}

	spin_unlock_irqrestore(&tp->lock, flags);

	return 0;
}

926
927
928
929
930
931
932
933
static int rtl8139_change_mtu(struct net_device *dev, int new_mtu)
{
	if (new_mtu < 68 || new_mtu > MAX_ETH_DATA_SIZE)
		return -EINVAL;
	dev->mtu = new_mtu;
	return 0;
}

934
935
936
static const struct net_device_ops rtl8139_netdev_ops = {
	.ndo_open		= rtl8139_open,
	.ndo_stop		= rtl8139_close,
Junchang Wang's avatar
Junchang Wang committed
937
	.ndo_get_stats64	= rtl8139_get_stats64,
938
	.ndo_change_mtu		= rtl8139_change_mtu,
939
	.ndo_validate_addr	= eth_validate_addr,
940
	.ndo_set_mac_address 	= rtl8139_set_mac_address,
941
	.ndo_start_xmit		= rtl8139_start_xmit,
942
	.ndo_set_rx_mode	= rtl8139_set_rx_mode,
943
944
945
946
947
	.ndo_do_ioctl		= netdev_ioctl,
	.ndo_tx_timeout		= rtl8139_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= rtl8139_poll_controller,
#endif
Ben Greear's avatar
Ben Greear committed
948
	.ndo_set_features	= rtl8139_set_features,
949
};
Linus Torvalds's avatar
Linus Torvalds committed
950

951
952
static int rtl8139_init_one(struct pci_dev *pdev,
			    const struct pci_device_id *ent)
Linus Torvalds's avatar
Linus Torvalds committed
953
954
955
956
{
	struct net_device *dev = NULL;
	struct rtl8139_private *tp;
	int i, addr_len, option;
957
	void __iomem *ioaddr;
Linus Torvalds's avatar
Linus Torvalds committed
958
959
960
961
962
963
964
965
966
967
968
969
970
971
	static int board_idx = -1;

	assert (pdev != NULL);
	assert (ent != NULL);

	board_idx++;

	/* when we're built into the kernel, the driver version message
	 * is only printed if at least one 8139 board has been found
	 */
#ifndef MODULE
	{
		static int printed_version;
		if (!printed_version++)
972
			pr_info(RTL8139_DRIVER_NAME "\n");
Linus Torvalds's avatar
Linus Torvalds committed
973
974
975
976
	}
#endif

	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
977
	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision >= 0x20) {
978
		dev_info(&pdev->dev,
979
			   "This (id %04x:%04x rev %02x) is an enhanced 8139C+ chip, use 8139cp\n",
980
		       	   pdev->vendor, pdev->device, pdev->revision);
981
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
982
983
	}

984
985
986
987
	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
	    pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
	    pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
988
		pr_info("OQO Model 2 detected. Forcing PIO\n");
989
990
991
		use_io = 1;
	}

Stephen Hemminger's avatar
Stephen Hemminger committed
992
993
994
	dev = rtl8139_init_board (pdev);
	if (IS_ERR(dev))
		return PTR_ERR(dev);
Linus Torvalds's avatar
Linus Torvalds committed
995
996
997

	assert (dev != NULL);
	tp = netdev_priv(dev);
998
	tp->dev = dev;
Linus Torvalds's avatar
Linus Torvalds committed
999
1000
1001
1002
1003
1004

	ioaddr = tp->mmio_addr;
	assert (ioaddr != NULL);

	addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
	for (i = 0; i < 3; i++)
Al Viro's avatar
Al Viro committed
1005
1006
		((__le16 *) (dev->dev_addr))[i] =
		    cpu_to_le16(read_eeprom (ioaddr, i + 7, addr_len));
Linus Torvalds's avatar
Linus Torvalds committed
1007
1008

	/* The Rtl8139-specific entries in the device structure. */
1009
	dev->netdev_ops = &rtl8139_netdev_ops;
Linus Torvalds's avatar
Linus Torvalds committed
1010
1011
	dev->ethtool_ops = &rtl8139_ethtool_ops;
	dev->watchdog_timeo = TX_TIMEOUT;
1012
	netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
Linus Torvalds's avatar
Linus Torvalds committed
1013
1014
1015
1016
1017
1018

	/* note: the hardware is not capable of sg/csum/highdma, however
	 * through the use of skb_copy_and_csum_dev we enable these
	 * features
	 */
	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
1019
	dev->vlan_features = dev->features;
Linus Torvalds's avatar
Linus Torvalds committed
1020

Ben Greear's avatar
Ben Greear committed
1021
	dev->hw_features |= NETIF_F_RXALL;
Ben Greear's avatar
Ben Greear committed
1022
	dev->hw_features |= NETIF_F_RXFCS;
Ben Greear's avatar
Ben Greear committed
1023

Linus Torvalds's avatar
Linus Torvalds committed
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
	/* tp zeroed and aligned in alloc_etherdev */
	tp = netdev_priv(dev);

	/* note: tp->chipset set in rtl8139_init_board */
	tp->drv_flags = board_info[ent->driver_data].hw_flags;
	tp->mmio_addr = ioaddr;
	tp->msg_enable =
		(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
	spin_lock_init (&tp->lock);
	spin_lock_init (&tp->rx_lock);
David Howells's avatar
David Howells committed
1034
	INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
Linus Torvalds's avatar
Linus Torvalds committed
1035
1036
1037
1038
1039
1040
1041
	tp->mii.dev = dev;
	tp->mii.mdio_read = mdio_read;
	tp->mii.mdio_write = mdio_write;
	tp->mii.phy_id_mask = 0x3f;
	tp->mii.reg_num_mask = 0x1f;

	/* dev is fully set up and ready to use now */
1042
1043
	pr_debug("about to register device named %s (%p)...\n",
		 dev->name, dev);
Linus Torvalds's avatar
Linus Torvalds committed
1044
1045
1046
1047
1048
	i = register_netdev (dev);
	if (i) goto err_out;

	pci_set_drvdata (pdev, dev);

1049
	netdev_info(dev, "%s at 0x%p, %pM, IRQ %d\n",
1050
		    board_info[ent->driver_data].name,
1051
		    ioaddr, dev->dev_addr, pdev->irq);
Linus Torvalds's avatar
Linus Torvalds committed
1052

1053
1054
	netdev_dbg(dev, "Identified 8139 chip type '%s'\n",
		   rtl_chip_info[tp->chipset].name);
Linus Torvalds's avatar
Linus Torvalds committed
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066

	/* Find the connected MII xcvrs.
	   Doing this in open() would allow detecting external xcvrs later, but
	   takes too much time. */
#ifdef CONFIG_8139TOO_8129
	if (tp->drv_flags & HAS_MII_XCVR) {
		int phy, phy_idx = 0;
		for (phy = 0; phy < 32 && phy_idx < sizeof(tp->phys); phy++) {
			int mii_status = mdio_read(dev, phy, 1);
			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
				u16 advertising = mdio_read(dev, phy, 4);
				tp->phys[phy_idx++] = phy;
1067
1068
				netdev_info(dev, "MII transceiver %d status 0x%04x advertising %04x\n",
					    phy, mii_status, advertising);
Linus Torvalds's avatar
Linus Torvalds committed
1069
1070
1071
			}
		}
		if (phy_idx == 0) {
1072
			netdev_info(dev, "No MII transceivers found! Assuming SYM transceiver\n");
Linus Torvalds's avatar
Linus Torvalds committed
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
			tp->phys[0] = 32;
		}
	} else
#endif
		tp->phys[0] = 32;
	tp->mii.phy_id = tp->phys[0];

	/* The lower four bits are the media type. */
	option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
	if (option > 0) {
		tp->mii.full_duplex = (option & 0x210) ? 1 : 0;
		tp->default_port = option & 0xFF;
		if (tp->default_port)
			tp->mii.force_media = 1;
	}
	if (board_idx < MAX_UNITS  &&  full_duplex[board_idx] > 0)
		tp->mii.full_duplex = full_duplex[board_idx];
	if (tp->mii.full_duplex) {
1091
		netdev_info(dev, "Media type forced to Full Duplex\n");
Linus Torvalds's avatar
Linus Torvalds committed
1092
1093
1094
1095
1096
		/* Changing the MII-advertised media because might prevent
		   re-connection. */
		tp->mii.force_media = 1;
	}
	if (tp->default_port) {
1097
1098
1099
		netdev_info(dev, "  Forcing %dMbps %s-duplex operation\n",
			    (option & 0x20 ? 100 : 10),
			    (option & 0x10 ? "full" : "half"));
Linus Torvalds's avatar
Linus Torvalds committed
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
		mdio_write(dev, tp->phys[0], 0,
				   ((option & 0x20) ? 0x2000 : 0) | 	/* 100Mbps? */
				   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
	}

	/* Put the chip into low-power mode. */
	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */

	return 0;

err_out:
	__rtl8139_cleanup_dev (dev);
	pci_disable_device (pdev);
	return i;
}


1118
static void rtl8139_remove_one(struct pci_dev *pdev)
Linus Torvalds's avatar
Linus Torvalds committed
1119
1120
{
	struct net_device *dev = pci_get_drvdata (pdev);
1121
	struct rtl8139_private *tp = netdev_priv(dev);
Linus Torvalds's avatar
Linus Torvalds committed
1122
1123
1124

	assert (dev != NULL);

1125
	cancel_delayed_work_sync(&tp->thread);
1126

Linus Torvalds's avatar
Linus Torvalds committed
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
	unregister_netdev (dev);

	__rtl8139_cleanup_dev (dev);
	pci_disable_device (pdev);
}


/* Serial EEPROM section. */

/*  EEPROM_Ctrl bits. */
#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
#define EE_CS			0x08	/* EEPROM chip select. */
#define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */
#define EE_WRITE_0		0x00
#define EE_WRITE_1		0x02
#define EE_DATA_READ	0x01	/* EEPROM chip data out. */
#define EE_ENB			(0x80 | EE_CS)

/* Delay between EEPROM clock transitions.
   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
 */

1149
#define eeprom_delay()	(void)RTL_R8(Cfg9346)
Linus Torvalds's avatar
Linus Torvalds committed
1150
1151
1152
1153
1154
1155

/* The EEPROM commands include the alway-set leading bit. */
#define EE_WRITE_CMD	(5)
#define EE_READ_CMD		(6)
#define EE_ERASE_CMD	(7)

1156
static int read_eeprom(void __iomem *ioaddr, int location, int addr_len)
Linus Torvalds's avatar
Linus Torvalds committed
1157
1158
1159
1160
1161
{
	int i;
	unsigned retval = 0;
	int read_cmd = location | (EE_READ_CMD << addr_len);

1162
1163
	RTL_W8 (Cfg9346, EE_ENB & ~EE_CS);
	RTL_W8 (Cfg9346, EE_ENB);
Linus Torvalds's avatar
Linus Torvalds committed
1164
1165
1166
1167
1168
	eeprom_delay ();

	/* Shift the read command bits out. */
	for (i = 4 + addr_len; i >= 0; i--) {
		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
1169
		RTL_W8 (Cfg9346, EE_ENB | dataval);
Linus Torvalds's avatar
Linus Torvalds committed
1170
		eeprom_delay ();
1171
		RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK);
Linus Torvalds's avatar
Linus Torvalds committed
1172
1173
		eeprom_delay ();
	}
1174
	RTL_W8 (Cfg9346, EE_ENB);
Linus Torvalds's avatar
Linus Torvalds committed
1175
1176
1177
	eeprom_delay ();

	for (i = 16; i > 0; i--) {
1178
		RTL_W8 (Cfg9346, EE_ENB | EE_SHIFT_CLK);
Linus Torvalds's avatar
Linus Torvalds committed
1179
1180
		eeprom_delay ();
		retval =
1181
		    (retval << 1) | ((RTL_R8 (Cfg9346) & EE_DATA_READ) ? 1 :
Linus Torvalds's avatar
Linus Torvalds committed
1182
				     0);
1183
		RTL_W8 (Cfg9346, EE_ENB);
Linus Torvalds's avatar
Linus Torvalds committed
1184
1185
1186
1187
		eeprom_delay ();
	}

	/* Terminate the EEPROM access. */
1188
	RTL_W8(Cfg9346, 0);
Linus Torvalds's avatar
Linus Torvalds committed
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
	eeprom_delay ();

	return retval;
}

/* MII serial management: mostly bogus for now. */
/* Read and write the MII management registers using software-generated
   serial MDIO protocol.
   The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
   "overclocking" issues. */
#define MDIO_DIR		0x80
#define MDIO_DATA_OUT	0x04
#define MDIO_DATA_IN	0x02
#define MDIO_CLK		0x01
#define MDIO_WRITE0 (MDIO_DIR)
#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)

1207
#define mdio_delay()	RTL_R8(Config4)
Linus Torvalds's avatar
Linus Torvalds committed
1208
1209


1210
static const char mii_2_8139_map[8] = {
Linus Torvalds's avatar
Linus Torvalds committed
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
	BasicModeCtrl,
	BasicModeStatus,
	0,
	0,
	NWayAdvert,
	NWayLPAR,
	NWayExpansion,
	0
};


#ifdef CONFIG_8139TOO_8129
/* Syncronize the MII management interface by shifting 32 one bits out. */
1224
static void mdio_sync (void __iomem *ioaddr)
Linus Torvalds's avatar
Linus Torvalds committed
1225
1226
1227
1228
{
	int i;

	for (i = 32; i >= 0; i--) {
1229
1230
1231
1232
		RTL_W8 (Config4, MDIO_WRITE1);
		mdio_delay ();
		RTL_W8 (Config4, MDIO_WRITE1 | MDIO_CLK);
		mdio_delay ();
Linus Torvalds's avatar
Linus Torvalds committed
1233
1234
1235
1236
1237
1238
1239
1240
1241
	}
}
#endif

static int mdio_read (struct net_device *dev, int phy_id, int location)
{
	struct rtl8139_private *tp = netdev_priv(dev);
	int retval = 0;
#ifdef CONFIG_8139TOO_8129
1242
	void __iomem *ioaddr = tp->mmio_addr;
Linus Torvalds's avatar
Linus Torvalds committed
1243
1244
1245
1246
1247
	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
	int i;
#endif

	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
1248
		void __iomem *ioaddr = tp->mmio_addr;
Linus Torvalds's avatar
Linus Torvalds committed
1249
		return location < 8 && mii_2_8139_map[location] ?
1250
		    RTL_R16 (mii_2_8139_map[location]) : 0;
Linus Torvalds's avatar
Linus Torvalds committed
1251
1252
1253
	}

#ifdef CONFIG_8139TOO_8129
1254
	mdio_sync (ioaddr);
Linus Torvalds's avatar
Linus Torvalds committed
1255
1256
1257
1258
	/* Shift the read command bits out. */
	for (i = 15; i >= 0; i--) {
		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;

1259
1260
1261
1262
		RTL_W8 (Config4, MDIO_DIR | dataval);
		mdio_delay ();
		RTL_W8 (Config4, MDIO_DIR | dataval | MDIO_CLK);
		mdio_delay ();
Linus Torvalds's avatar
Linus Torvalds committed
1263
1264
1265
1266
	}

	/* Read the two transition, 16 data, and wire-idle bits. */
	for (i = 19; i > 0; i--) {
1267
1268
1269
1270
1271
		RTL_W8 (Config4, 0);
		mdio_delay ();
		retval = (retval << 1) | ((RTL_R8 (Config4) & MDIO_DATA_IN) ? 1 : 0);
		RTL_W8 (Config4, MDIO_CLK);
		mdio_delay ();
Linus Torvalds's avatar
Linus Torvalds committed
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
	}
#endif

	return (retval >> 1) & 0xffff;
}


static void mdio_write (struct net_device *dev, int phy_id, int location,
			int value)
{
	struct rtl8139_private *tp = netdev_priv(dev);
#ifdef CONFIG_8139TOO_8129
1284
	void __iomem *ioaddr = tp->mmio_addr;
Linus Torvalds's avatar
Linus Torvalds committed
1285
1286
1287
1288
1289
	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
	int i;
#endif

	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
1290
		void __iomem *ioaddr = tp->mmio_addr;
Linus Torvalds's avatar
Linus Torvalds committed
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
		if (location == 0) {
			RTL_W8 (Cfg9346, Cfg9346_Unlock);
			RTL_W16 (BasicModeCtrl, value);
			RTL_W8 (Cfg9346, Cfg9346_Lock);
		} else if (location < 8 && mii_2_8139_map[location])
			RTL_W16 (mii_2_8139_map[location], value);
		return;
	}

#ifdef CONFIG_8139TOO_8129
1301
	mdio_sync (ioaddr);
Linus Torvalds's avatar
Linus Torvalds committed
1302
1303
1304
1305
1306

	/* Shift the command bits out. */
	for (i = 31; i >= 0; i--) {
		int dataval =
		    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
1307
1308
1309
1310
		RTL_W8 (Config4, dataval);
		mdio_delay ();
		RTL_W8 (Config4, dataval | MDIO_CLK);
		mdio_delay ();
Linus Torvalds's avatar
Linus Torvalds committed
1311
1312
1313
	}
	/* Clear out extra bits. */
	for (i = 2; i > 0; i--) {
1314
1315
1316
1317
		RTL_W8 (Config4, 0);
		mdio_delay ();
		RTL_W8 (Config4, MDIO_CLK);
		mdio_delay ();
Linus Torvalds's avatar
Linus Torvalds committed
1318
1319
1320
1321
1322
1323
1324
1325
	}
#endif
}


static int rtl8139_open (struct net_device *dev)
{
	struct rtl8139_private *tp = netdev_priv(dev);
1326
	void __iomem *ioaddr = tp->mmio_addr;
1327
1328
	const int irq = tp->pci_dev->irq;
	int retval;
Linus Torvalds's avatar
Linus Torvalds committed
1329

1330
	retval = request_irq(irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
Linus Torvalds's avatar
Linus Torvalds committed
1331
1332
1333
	if (retval)
		return retval;

1334
1335
1336
1337
	tp->tx_bufs = dma_alloc_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
					   &tp->tx_bufs_dma, GFP_KERNEL);
	tp->rx_ring = dma_alloc_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
					   &tp->rx_ring_dma, GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
1338
	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
1339
		free_irq(irq, dev);
Linus Torvalds's avatar
Linus Torvalds committed
1340
1341

		if (tp->tx_bufs)
1342
			dma_free_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
Linus Torvalds's avatar
Linus Torvalds committed
1343
1344
					    tp->tx_bufs, tp->tx_bufs_dma);
		if (tp->rx_ring)
1345
			dma_free_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
Linus Torvalds's avatar
Linus Torvalds committed
1346
1347
1348
1349
1350
1351
					    tp->rx_ring, tp->rx_ring_dma);

		return -ENOMEM;

	}

1352
1353
	napi_enable(&tp->napi);

Linus Torvalds's avatar
Linus Torvalds committed
1354
1355
1356
1357
1358
1359
1360
	tp->mii.full_duplex = tp->mii.force_media;
	tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;

	rtl8139_init_ring (dev);
	rtl8139_hw_start (dev);
	netif_start_queue (dev);

1361
1362
1363
1364
	netif_dbg(tp, ifup, dev,
		  "%s() ioaddr %#llx IRQ %d GP Pins %02x %s-duplex\n",
		  __func__,
		  (unsigned long long)pci_resource_start (tp->pci_dev, 1),
1365
		  irq, RTL_R8 (MediaStatus),
1366
		  tp->mii.full_duplex ? "full" : "half");
Linus Torvalds's avatar
Linus Torvalds committed
1367

1368
	rtl8139_start_thread(tp);
Linus Torvalds's avatar
Linus Torvalds committed
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386

	return 0;
}


static void rtl_check_media (struct net_device *dev, unsigned int init_media)
{
	struct rtl8139_private *tp = netdev_priv(dev);

	if (tp->phys[0] >= 0) {
		mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
	}
}

/* Start the hardware at open or resume. */
static void rtl8139_hw_start (struct net_device *dev)
{
	struct rtl8139_private *tp = netdev_priv(dev);
1387
	void __iomem *ioaddr = tp->mmio_addr;
Linus Torvalds's avatar
Linus Torvalds committed
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
	u32 i;
	u8 tmp;

	/* Bring old chips out of low-power mode. */
	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
		RTL_W8 (HltClk, 'R');

	rtl8139_chip_reset (ioaddr);

	/* unlock Config[01234] and BMCR register writes */
	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
	/* Restore our idea of the MAC address. */
Al Viro's avatar
Al Viro committed
1400
1401
	RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
	RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4)));
Linus Torvalds's avatar
Linus Torvalds committed
1402

Jianjun kong's avatar
Jianjun kong committed
1403
1404
1405
1406
1407
	tp->cur_rx = 0;

	/* init Rx ring buffer DMA address */
	RTL_W32_F (RxBuf, tp->rx_ring_dma);

Linus Torvalds's avatar
Linus Torvalds committed
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
	/* Must enable Tx/Rx before setting transfer thresholds! */
	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);

	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
	RTL_W32 (RxConfig, tp->rx_config);
	RTL_W32 (TxConfig, rtl8139_tx_config);

	rtl_check_media (dev, 1);

	if (tp->chipset >= CH_8139B) {
		/* Disable magic packet scanning, which is enabled
		 * when PM is enabled in Config1.  It can be reenabled
		 * via ETHTOOL_SWOL if desired.  */
		RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
	}

1424
	netdev_dbg(dev, "init buffer addresses\n");
Linus Torvalds's avatar
Linus Torvalds committed
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488

	/* Lock Config[01234] and BMCR register writes */
	RTL_W8 (Cfg9346, Cfg9346_Lock);

	/* init Tx buffer DMA addresses */
	for (i = 0; i < NUM_TX_DESC; i++)
		RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));

	RTL_W32 (RxMissed, 0);

	rtl8139_set_rx_mode (dev);

	/* no early-rx interrupts */
	RTL_W16 (MultiIntr, RTL_R16 (MultiIntr) & MultiIntrClear);

	/* make sure RxTx has started */
	tmp = RTL_R8 (ChipCmd);
	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);

	/* Enable all known interrupts by setting the interrupt mask. */
	RTL_W16 (IntrMask, rtl8139_intr_mask);
}


/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
static void rtl8139_init_ring (struct net_device *dev)
{
	struct rtl8139_private *tp = netdev_priv(dev);
	int i;

	tp->cur_rx = 0;
	tp->cur_tx = 0;
	tp->dirty_tx = 0;

	for (i = 0; i < NUM_TX_DESC; i++)
		tp->tx_buf[i] = &tp->tx_bufs[i * TX_BUF_SIZE];
}


/* This must be global for CONFIG_8139TOO_TUNE_TWISTER case */
static int next_tick = 3 * HZ;

#ifndef CONFIG_8139TOO_TUNE_TWISTER
static inline void rtl8139_tune_twister (struct net_device *dev,
				  struct rtl8139_private *tp) {}
#else
enum TwisterParamVals {
	PARA78_default	= 0x78fa8388,
	PARA7c_default	= 0xcb38de43,	/* param[0][3] */
	PARA7c_xxx	= 0xcb38de43,
};

static const unsigned long param[4][4] = {
	{0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43},
	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
	{0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83}
};

static void rtl8139_tune_twister (struct net_device *dev,
				  struct rtl8139_private *tp)
{
	int linkcase;
1489
	void __iomem *ioaddr = tp->mmio_addr;
Linus Torvalds's avatar
Linus Torvalds committed
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572

	/* This is a complicated state machine to configure the "twister" for
	   impedance/echos based on the cable length.
	   All of this is magic and undocumented.
	 */
	switch (tp->twistie) {
	case 1:
		if (RTL_R16 (CSCR) & CSCR_LinkOKBit) {
			/* We have link beat, let us tune the twister. */
			RTL_W16 (CSCR, CSCR_LinkDownOffCmd);
			tp->twistie = 2;	/* Change to state 2. */
			next_tick = HZ / 10;
		} else {
			/* Just put in some reasonable defaults for when beat returns. */
			RTL_W16 (CSCR, CSCR_LinkDownCmd);
			RTL_W32 (FIFOTMS, 0x20);	/* Turn on cable test mode. */
			RTL_W32 (PARA78, PARA78_default);
			RTL_W32 (PARA7c, PARA7c_default);
			tp->twistie = 0;	/* Bail from future actions. */
		}
		break;
	case 2:
		/* Read how long it took to hear the echo. */
		linkcase = RTL_R16 (CSCR) & CSCR_LinkStatusBits;
		if (linkcase == 0x7000)
			tp->twist_row = 3;
		else if (linkcase == 0x3000)
			tp->twist_row = 2;
		else if (linkcase == 0x1000)
			tp->twist_row = 1;
		else
			tp->twist_row = 0;
		tp->twist_col = 0;
		tp->twistie = 3;	/* Change to state 2. */
		next_tick = HZ / 10;
		break;
	case 3:
		/* Put out four tuning parameters, one per 100msec. */
		if (tp->twist_col == 0)
			RTL_W16 (FIFOTMS, 0);
		RTL_W32 (PARA7c, param[(int) tp->twist_row]
			 [(int) tp->twist_col]);
		next_tick = HZ / 10;
		if (++tp->twist_col >= 4) {
			/* For short cables we are done.
			   For long cables (row == 3) check for mistune. */
			tp->twistie =
			    (tp->twist_row == 3) ? 4 : 0;
		}
		break;
	case 4:
		/* Special case for long cables: check for mistune. */
		if ((RTL_R16 (CSCR) &
		     CSCR_LinkStatusBits) == 0x7000) {
			tp->twistie = 0;
			break;
		} else {
			RTL_W32 (PARA7c, 0xfb38de03);
			tp->twistie = 5;
			next_tick = HZ / 10;
		}
		break;
	case 5:
		/* Retune for shorter cable (column 2). */
		RTL_W32 (FIFOTMS, 0x20);
		RTL_W32 (PARA78, PARA78_default);
		RTL_W32 (PARA7c, PARA7c_default);
		RTL_W32 (FIFOTMS, 0x00);
		tp->twist_row = 2;
		tp->twist_col = 0;
		tp->twistie = 3;
		next_tick = HZ / 10;
		break;

	default:
		/* do nothing */
		break;
	}
}
#endif /* CONFIG_8139TOO_TUNE_TWISTER */

static inline void rtl8139_thread_iter (struct net_device *dev,
				 struct rtl8139_private *tp,
1573
				 void __iomem *ioaddr)
Linus Torvalds's avatar
Linus Torvalds committed
1574
1575
1576
1577
1578
1579
{
	int mii_lpa;

	mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA);

	if (!tp->mii.force_media && mii_lpa != 0xffff) {
1580
1581
		int duplex = ((mii_lpa & LPA_100FULL) ||
			      (mii_lpa & 0x01C0) == 0x0040);
Linus Torvalds's avatar
Linus Torvalds committed
1582
1583
1584
1585
		if (tp->mii.full_duplex != duplex) {
			tp->mii.full_duplex = duplex;

			if (mii_lpa) {
1586
1587
1588
				netdev_info(dev, "Setting %s-duplex based on MII #%d link partner ability of %04x\n",
					    tp->mii.full_duplex ? "full" : "half",
					    tp->phys[0], mii_lpa);
Linus Torvalds's avatar
Linus Torvalds committed
1589
			} else {
1590
				netdev_info(dev, "media is unconnected, link down, or incompatible connection\n");
Linus Torvalds's avatar
Linus Torvalds committed
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
			}
#if 0
			RTL_W8 (Cfg9346, Cfg9346_Unlock);
			RTL_W8 (Config1, tp->mii.full_duplex ? 0x60 : 0x20);
			RTL_W8 (Cfg9346, Cfg9346_Lock);
#endif
		}
	}

	next_tick = HZ * 60;

	rtl8139_tune_twister (dev, tp);

Joe Perches's avatar