tg3.c 468 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
/*
 * tg3.c: Broadcom Tigon3 ethernet driver.
 *
 * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
 * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
 * Copyright (C) 2004 Sun Microsystems Inc.
Siva Reddy Kallam's avatar
Siva Reddy Kallam committed
7
8
 * Copyright (C) 2005-2016 Broadcom Corporation.
 * Copyright (C) 2016-2017 Broadcom Limited.
Siva Reddy Kallam's avatar
Siva Reddy Kallam committed
9
10
 * Copyright (C) 2018 Broadcom. All Rights Reserved. The term "Broadcom"
 * refers to Broadcom Inc. and/or its subsidiaries.
Linus Torvalds's avatar
Linus Torvalds committed
11
12
 *
 * Firmware is:
Michael Chan's avatar
Michael Chan committed
13
 *	Derived from proprietary unpublished source code,
Siva Reddy Kallam's avatar
Siva Reddy Kallam committed
14
15
 *	Copyright (C) 2000-2016 Broadcom Corporation.
 *	Copyright (C) 2016-2017 Broadcom Ltd.
Siva Reddy Kallam's avatar
Siva Reddy Kallam committed
16
17
 *	Copyright (C) 2018 Broadcom. All Rights Reserved. The term "Broadcom"
 *	refers to Broadcom Inc. and/or its subsidiaries.
Michael Chan's avatar
Michael Chan committed
18
19
20
21
 *
 *	Permission is hereby granted for the distribution of this firmware
 *	data in hexadecimal or equivalent format, provided this copyright
 *	notice is accompanying it.
Linus Torvalds's avatar
Linus Torvalds committed
22
23
24
25
26
 */


#include <linux/module.h>
#include <linux/moduleparam.h>
27
#include <linux/stringify.h>
Linus Torvalds's avatar
Linus Torvalds committed
28
#include <linux/kernel.h>
29
#include <linux/sched/signal.h>
Linus Torvalds's avatar
Linus Torvalds committed
30
31
32
33
#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/delay.h>
34
#include <linux/in.h>
35
#include <linux/interrupt.h>
Linus Torvalds's avatar
Linus Torvalds committed
36
37
38
39
40
41
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
42
#include <linux/mdio.h>
Linus Torvalds's avatar
Linus Torvalds committed
43
#include <linux/mii.h>
Matt Carlson's avatar
Matt Carlson committed
44
#include <linux/phy.h>
Matt Carlson's avatar
Matt Carlson committed
45
#include <linux/brcmphy.h>
46
#include <linux/if.h>
Linus Torvalds's avatar
Linus Torvalds committed
47
48
49
50
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/workqueue.h>
51
#include <linux/prefetch.h>
52
#include <linux/dma-mapping.h>
53
#include <linux/firmware.h>
54
#include <linux/ssb/ssb_driver_gige.h>
55
56
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
57
#include <linux/crc32poly.h>
Linus Torvalds's avatar
Linus Torvalds committed
58
59

#include <net/checksum.h>
60
#include <net/ip.h>
Linus Torvalds's avatar
Linus Torvalds committed
61

62
#include <linux/io.h>
Linus Torvalds's avatar
Linus Torvalds committed
63
#include <asm/byteorder.h>
64
#include <linux/uaccess.h>
Linus Torvalds's avatar
Linus Torvalds committed
65

66
67
68
#include <uapi/linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>

Matt Carlson's avatar
Matt Carlson committed
69
70
71
#define BAR_0	0
#define BAR_2	2

Linus Torvalds's avatar
Linus Torvalds committed
72
73
#include "tg3.h"

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* Functions & macros to verify TG3_FLAGS types */

static inline int _tg3_flag(enum TG3_FLAGS flag, unsigned long *bits)
{
	return test_bit(flag, bits);
}

static inline void _tg3_flag_set(enum TG3_FLAGS flag, unsigned long *bits)
{
	set_bit(flag, bits);
}

static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
{
	clear_bit(flag, bits);
}

#define tg3_flag(tp, flag)				\
	_tg3_flag(TG3_FLAG_##flag, (tp)->tg3_flags)
#define tg3_flag_set(tp, flag)				\
	_tg3_flag_set(TG3_FLAG_##flag, (tp)->tg3_flags)
#define tg3_flag_clear(tp, flag)			\
	_tg3_flag_clear(TG3_FLAG_##flag, (tp)->tg3_flags)

Linus Torvalds's avatar
Linus Torvalds committed
98
#define DRV_MODULE_NAME		"tg3"
99
#define TG3_MAJ_NUM			3
100
#define TG3_MIN_NUM			137
101
102
#define DRV_MODULE_VERSION	\
	__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
103
#define DRV_MODULE_RELDATE	"May 11, 2014"
Linus Torvalds's avatar
Linus Torvalds committed
104

105
106
107
108
#define RESET_KIND_SHUTDOWN	0
#define RESET_KIND_INIT		1
#define RESET_KIND_SUSPEND	2

Linus Torvalds's avatar
Linus Torvalds committed
109
110
111
112
113
114
115
116
117
118
119
120
#define TG3_DEF_RX_MODE		0
#define TG3_DEF_TX_MODE		0
#define TG3_DEF_MSG_ENABLE	  \
	(NETIF_MSG_DRV		| \
	 NETIF_MSG_PROBE	| \
	 NETIF_MSG_LINK		| \
	 NETIF_MSG_TIMER	| \
	 NETIF_MSG_IFDOWN	| \
	 NETIF_MSG_IFUP		| \
	 NETIF_MSG_RX_ERR	| \
	 NETIF_MSG_TX_ERR)

121
122
#define TG3_GRC_LCLCTL_PWRSW_DELAY	100

Linus Torvalds's avatar
Linus Torvalds committed
123
124
125
/* length of time before we decide the hardware is borked,
 * and dev->tx_timeout() should be called to fix the problem
 */
126

Linus Torvalds's avatar
Linus Torvalds committed
127
128
129
#define TG3_TX_TIMEOUT			(5 * HZ)

/* hardware minimum and maximum for a single frame's data payload */
130
#define TG3_MIN_MTU			ETH_ZLEN
Linus Torvalds's avatar
Linus Torvalds committed
131
#define TG3_MAX_MTU(tp)	\
132
	(tg3_flag(tp, JUMBO_CAPABLE) ? 9000 : 1500)
Linus Torvalds's avatar
Linus Torvalds committed
133
134
135
136
137

/* These numbers seem to be hard coded in the NIC firmware somehow.
 * You can't change the ring sizes, but you can change where you place
 * them in the NIC onboard memory.
 */
138
#define TG3_RX_STD_RING_SIZE(tp) \
139
	(tg3_flag(tp, LRG_PROD_RING_CAP) ? \
140
	 TG3_RX_STD_MAX_SIZE_5717 : TG3_RX_STD_MAX_SIZE_5700)
Linus Torvalds's avatar
Linus Torvalds committed
141
#define TG3_DEF_RX_RING_PENDING		200
142
#define TG3_RX_JMB_RING_SIZE(tp) \
143
	(tg3_flag(tp, LRG_PROD_RING_CAP) ? \
144
	 TG3_RX_JMB_MAX_SIZE_5717 : TG3_RX_JMB_MAX_SIZE_5700)
Linus Torvalds's avatar
Linus Torvalds committed
145
146
147
148
149
150
151
152
153
154
155
156
#define TG3_DEF_RX_JUMBO_RING_PENDING	100

/* Do not place this n-ring entries value into the tp struct itself,
 * we really want to expose these constants to GCC so that modulo et
 * al.  operations are done with shifts and masks instead of with
 * hw multiply/modulo instructions.  Another solution would be to
 * replace things like '% foo' with '& (foo - 1)'.
 */

#define TG3_TX_RING_SIZE		512
#define TG3_DEF_TX_RING_PENDING		(TG3_TX_RING_SIZE - 1)

157
158
159
160
161
#define TG3_RX_STD_RING_BYTES(tp) \
	(sizeof(struct tg3_rx_buffer_desc) * TG3_RX_STD_RING_SIZE(tp))
#define TG3_RX_JMB_RING_BYTES(tp) \
	(sizeof(struct tg3_ext_rx_buffer_desc) * TG3_RX_JMB_RING_SIZE(tp))
#define TG3_RX_RCB_RING_BYTES(tp) \
162
	(sizeof(struct tg3_rx_buffer_desc) * (tp->rx_ret_ring_mask + 1))
Linus Torvalds's avatar
Linus Torvalds committed
163
164
165
166
#define TG3_TX_RING_BYTES	(sizeof(struct tg3_tx_buffer_desc) * \
				 TG3_TX_RING_SIZE)
#define NEXT_TX(N)		(((N) + 1) & (TG3_TX_RING_SIZE - 1))

167
168
169
170
171
172
173
174
175
#define TG3_DMA_BYTE_ENAB		64

#define TG3_RX_STD_DMA_SZ		1536
#define TG3_RX_JMB_DMA_SZ		9046

#define TG3_RX_DMA_TO_MAP_SZ(x)		((x) + TG3_DMA_BYTE_ENAB)

#define TG3_RX_STD_MAP_SZ		TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ)
#define TG3_RX_JMB_MAP_SZ		TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)
Linus Torvalds's avatar
Linus Torvalds committed
176

177
178
#define TG3_RX_STD_BUFF_RING_SIZE(tp) \
	(sizeof(struct ring_info) * TG3_RX_STD_RING_SIZE(tp))
179

180
181
#define TG3_RX_JMB_BUFF_RING_SIZE(tp) \
	(sizeof(struct ring_info) * TG3_RX_JMB_RING_SIZE(tp))
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* Due to a hardware bug, the 5701 can only DMA to memory addresses
 * that are at least dword aligned when used in PCIX mode.  The driver
 * works around this bug by double copying the packet.  This workaround
 * is built into the normal double copy length check for efficiency.
 *
 * However, the double copy is only necessary on those architectures
 * where unaligned memory accesses are inefficient.  For those architectures
 * where unaligned memory accesses incur little penalty, we can reintegrate
 * the 5701 in the normal rx path.  Doing so saves a device structure
 * dereference by hardcoding the double copy threshold in place.
 */
#define TG3_RX_COPY_THRESHOLD		256
#if NET_IP_ALIGN == 0 || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
	#define TG3_RX_COPY_THRESH(tp)	TG3_RX_COPY_THRESHOLD
#else
	#define TG3_RX_COPY_THRESH(tp)	((tp)->rx_copy_thresh)
#endif

201
202
203
#if (NET_IP_ALIGN != 0)
#define TG3_RX_OFFSET(tp)	((tp)->rx_offset)
#else
204
#define TG3_RX_OFFSET(tp)	(NET_SKB_PAD)
205
206
#endif

Linus Torvalds's avatar
Linus Torvalds committed
207
/* minimum number of free TX descriptors required to wake up TX process */
208
#define TG3_TX_WAKEUP_THRESH(tnapi)		((tnapi)->tx_pending / 4)
Matt Carlson's avatar
Matt Carlson committed
209
#define TG3_TX_BD_DMA_MAX_2K		2048
210
#define TG3_TX_BD_DMA_MAX_4K		4096
Linus Torvalds's avatar
Linus Torvalds committed
211

Matt Carlson's avatar
Matt Carlson committed
212
213
#define TG3_RAW_IP_ALIGN 2

214
215
216
#define TG3_MAX_UCAST_ADDR(tp) (tg3_flag((tp), ENABLE_ASF) ? 2 : 3)
#define TG3_UCAST_ADDR_IDX(tp) (tg3_flag((tp), ENABLE_ASF) ? 2 : 1)

217
#define TG3_FW_UPDATE_TIMEOUT_SEC	5
218
#define TG3_FW_UPDATE_FREQ_SEC		(TG3_FW_UPDATE_TIMEOUT_SEC / 2)
219

220
#define FIRMWARE_TG3		"tigon/tg3.bin"
221
#define FIRMWARE_TG357766	"tigon/tg357766.bin"
222
223
224
#define FIRMWARE_TG3TSO		"tigon/tg3_tso.bin"
#define FIRMWARE_TG3TSO5	"tigon/tg3_tso5.bin"

Bill Pemberton's avatar
Bill Pemberton committed
225
static char version[] =
226
	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")";
Linus Torvalds's avatar
Linus Torvalds committed
227
228
229
230
231

MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox.com)");
MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
232
233
234
235
MODULE_FIRMWARE(FIRMWARE_TG3);
MODULE_FIRMWARE(FIRMWARE_TG3TSO);
MODULE_FIRMWARE(FIRMWARE_TG3TSO5);

Linus Torvalds's avatar
Linus Torvalds committed
236
237
238
239
static int tg3_debug = -1;	/* -1 == use TG3_DEF_MSG_ENABLE as value */
module_param(tg3_debug, int, 0);
MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value");

240
241
242
#define TG3_DRV_DATA_FLAG_10_100_ONLY	0x0001
#define TG3_DRV_DATA_FLAG_5705_10_100	0x0002

243
static const struct pci_device_id tg3_pci_tbl[] = {
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5701)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705_2)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M_2)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702A3)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5782)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5789)},
262
263
264
265
266
267
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY |
			TG3_DRV_DATA_FLAG_5705_10_100},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY |
			TG3_DRV_DATA_FLAG_5705_10_100},
268
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2)},
269
270
271
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY |
			TG3_DRV_DATA_FLAG_5705_10_100},
272
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)},
273
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5722)},
274
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)},
275
276
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M)},
277
278
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
279
280
281
282
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752M)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753M)},
283
284
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
285
286
287
288
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M)},
289
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5756)},
290
291
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)},
292
293
294
295
	{PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5787M,
			PCI_VENDOR_ID_LENOVO,
			TG3PCI_SUBDEVICE_ID_LENOVO_5787M),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
296
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)},
297
298
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787F),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
299
300
301
302
303
304
305
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715S)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781)},
Michael Chan's avatar
Michael Chan committed
306
307
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)},
308
309
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5784)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5764)},
Matt Carlson's avatar
Matt Carlson committed
310
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)},
Matt Carlson's avatar
Matt Carlson committed
311
312
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
Matt Carlson's avatar
Matt Carlson committed
313
314
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761S)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761SE)},
315
316
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_G)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_F)},
317
318
319
320
321
322
	{PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780,
			PCI_VENDOR_ID_AI, TG3PCI_SUBDEVICE_ID_ACER_57780_A),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
	{PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780,
			PCI_VENDOR_ID_AI, TG3PCI_SUBDEVICE_ID_ACER_57780_B),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
Matt Carlson's avatar
Matt Carlson committed
323
324
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)},
325
326
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
Matt Carlson's avatar
Matt Carlson committed
327
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)},
328
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)},
Michael Chan's avatar
Michael Chan committed
329
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717_C)},
330
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)},
331
332
333
334
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57761)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57765)},
335
336
337
338
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795),
	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
339
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
Matt Carlson's avatar
Matt Carlson committed
340
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
341
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)},
Matt Carlson's avatar
Matt Carlson committed
342
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57766)},
Michael Chan's avatar
Michael Chan committed
343
344
345
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)},
346
347
348
349
350
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57764)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57767)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57787)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57782)},
	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57786)},
351
352
353
354
355
356
357
	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1001)},
	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1003)},
	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100)},
	{PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_TIGON3)},
358
	{PCI_DEVICE(0x10cf, 0x11a2)}, /* Fujitsu 1000base-SX with BCM5703SKHB */
359
	{}
Linus Torvalds's avatar
Linus Torvalds committed
360
361
362
363
};

MODULE_DEVICE_TABLE(pci, tg3_pci_tbl);

364
static const struct {
Linus Torvalds's avatar
Linus Torvalds committed
365
	const char string[ETH_GSTRING_LEN];
366
} ethtool_stats_keys[] = {
Linus Torvalds's avatar
Linus Torvalds committed
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
	{ "rx_octets" },
	{ "rx_fragments" },
	{ "rx_ucast_packets" },
	{ "rx_mcast_packets" },
	{ "rx_bcast_packets" },
	{ "rx_fcs_errors" },
	{ "rx_align_errors" },
	{ "rx_xon_pause_rcvd" },
	{ "rx_xoff_pause_rcvd" },
	{ "rx_mac_ctrl_rcvd" },
	{ "rx_xoff_entered" },
	{ "rx_frame_too_long_errors" },
	{ "rx_jabbers" },
	{ "rx_undersize_packets" },
	{ "rx_in_length_errors" },
	{ "rx_out_length_errors" },
	{ "rx_64_or_less_octet_packets" },
	{ "rx_65_to_127_octet_packets" },
	{ "rx_128_to_255_octet_packets" },
	{ "rx_256_to_511_octet_packets" },
	{ "rx_512_to_1023_octet_packets" },
	{ "rx_1024_to_1522_octet_packets" },
	{ "rx_1523_to_2047_octet_packets" },
	{ "rx_2048_to_4095_octet_packets" },
	{ "rx_4096_to_8191_octet_packets" },
	{ "rx_8192_to_9022_octet_packets" },

	{ "tx_octets" },
	{ "tx_collisions" },

	{ "tx_xon_sent" },
	{ "tx_xoff_sent" },
	{ "tx_flow_control" },
	{ "tx_mac_errors" },
	{ "tx_single_collisions" },
	{ "tx_mult_collisions" },
	{ "tx_deferred" },
	{ "tx_excessive_collisions" },
	{ "tx_late_collisions" },
	{ "tx_collide_2times" },
	{ "tx_collide_3times" },
	{ "tx_collide_4times" },
	{ "tx_collide_5times" },
	{ "tx_collide_6times" },
	{ "tx_collide_7times" },
	{ "tx_collide_8times" },
	{ "tx_collide_9times" },
	{ "tx_collide_10times" },
	{ "tx_collide_11times" },
	{ "tx_collide_12times" },
	{ "tx_collide_13times" },
	{ "tx_collide_14times" },
	{ "tx_collide_15times" },
	{ "tx_ucast_packets" },
	{ "tx_mcast_packets" },
	{ "tx_bcast_packets" },
	{ "tx_carrier_sense_errors" },
	{ "tx_discards" },
	{ "tx_errors" },

	{ "dma_writeq_full" },
	{ "dma_write_prioq_full" },
	{ "rxbds_empty" },
	{ "rx_discards" },
	{ "rx_errors" },
	{ "rx_threshold_hit" },

	{ "dma_readq_full" },
	{ "dma_read_prioq_full" },
	{ "tx_comp_queue_full" },

	{ "ring_set_send_prod_index" },
	{ "ring_status_update" },
	{ "nic_irqs" },
	{ "nic_avoided_irqs" },
442
443
444
	{ "nic_tx_threshold_hit" },

	{ "mbuf_lwm_thresh_hit" },
Linus Torvalds's avatar
Linus Torvalds committed
445
446
};

447
#define TG3_NUM_STATS	ARRAY_SIZE(ethtool_stats_keys)
448
449
450
451
452
453
454
455
#define TG3_NVRAM_TEST		0
#define TG3_LINK_TEST		1
#define TG3_REGISTER_TEST	2
#define TG3_MEMORY_TEST		3
#define TG3_MAC_LOOPB_TEST	4
#define TG3_PHY_LOOPB_TEST	5
#define TG3_EXT_LOOPB_TEST	6
#define TG3_INTERRUPT_TEST	7
456
457


458
static const struct {
459
	const char string[ETH_GSTRING_LEN];
460
} ethtool_test_keys[] = {
461
462
463
464
465
466
467
468
	[TG3_NVRAM_TEST]	= { "nvram test        (online) " },
	[TG3_LINK_TEST]		= { "link test         (online) " },
	[TG3_REGISTER_TEST]	= { "register test     (offline)" },
	[TG3_MEMORY_TEST]	= { "memory test       (offline)" },
	[TG3_MAC_LOOPB_TEST]	= { "mac loopback test (offline)" },
	[TG3_PHY_LOOPB_TEST]	= { "phy loopback test (offline)" },
	[TG3_EXT_LOOPB_TEST]	= { "ext loopback test (offline)" },
	[TG3_INTERRUPT_TEST]	= { "interrupt test    (offline)" },
469
470
};

471
472
473
#define TG3_NUM_TEST	ARRAY_SIZE(ethtool_test_keys)


474
475
476
477
478
479
480
static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
{
	writel(val, tp->regs + off);
}

static u32 tg3_read32(struct tg3 *tp, u32 off)
{
481
	return readl(tp->regs + off);
482
483
}

Matt Carlson's avatar
Matt Carlson committed
484
485
486
487
488
489
490
static void tg3_ape_write32(struct tg3 *tp, u32 off, u32 val)
{
	writel(val, tp->aperegs + off);
}

static u32 tg3_ape_read32(struct tg3 *tp, u32 off)
{
491
	return readl(tp->aperegs + off);
Matt Carlson's avatar
Matt Carlson committed
492
493
}

Linus Torvalds's avatar
Linus Torvalds committed
494
495
static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
{
496
497
498
	unsigned long flags;

	spin_lock_irqsave(&tp->indirect_lock, flags);
499
500
	pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
	pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
501
	spin_unlock_irqrestore(&tp->indirect_lock, flags);
502
503
504
505
506
507
}

static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val)
{
	writel(val, tp->regs + off);
	readl(tp->regs + off);
Linus Torvalds's avatar
Linus Torvalds committed
508
509
}

510
static u32 tg3_read_indirect_reg32(struct tg3 *tp, u32 off)
Linus Torvalds's avatar
Linus Torvalds committed
511
{
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&tp->indirect_lock, flags);
	pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
	pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val);
	spin_unlock_irqrestore(&tp->indirect_lock, flags);
	return val;
}

static void tg3_write_indirect_mbox(struct tg3 *tp, u32 off, u32 val)
{
	unsigned long flags;

	if (off == (MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW)) {
		pci_write_config_dword(tp->pdev, TG3PCI_RCV_RET_RING_CON_IDX +
				       TG3_64BIT_REG_LOW, val);
		return;
	}
531
	if (off == TG3_RX_STD_PROD_IDX_REG) {
532
533
534
		pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX +
				       TG3_64BIT_REG_LOW, val);
		return;
Linus Torvalds's avatar
Linus Torvalds committed
535
	}
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563

	spin_lock_irqsave(&tp->indirect_lock, flags);
	pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600);
	pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
	spin_unlock_irqrestore(&tp->indirect_lock, flags);

	/* In indirect mode when disabling interrupts, we also need
	 * to clear the interrupt bit in the GRC local ctrl register.
	 */
	if ((off == (MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW)) &&
	    (val == 0x1)) {
		pci_write_config_dword(tp->pdev, TG3PCI_MISC_LOCAL_CTRL,
				       tp->grc_local_ctrl|GRC_LCLCTRL_CLEARINT);
	}
}

static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off)
{
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&tp->indirect_lock, flags);
	pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600);
	pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val);
	spin_unlock_irqrestore(&tp->indirect_lock, flags);
	return val;
}

564
565
566
567
568
569
/* usec_wait specifies the wait time in usec when writing to certain registers
 * where it is unsafe to read back the register without some delay.
 * GRC_LOCAL_CTRL is one example if the GPIOs are toggled to switch power.
 * TG3PCI_CLOCK_CTRL is another example if the clock frequencies are changed.
 */
static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait)
570
{
571
	if (tg3_flag(tp, PCIX_TARGET_HWBUG) || tg3_flag(tp, ICH_WORKAROUND))
572
573
574
575
576
577
578
579
580
581
582
583
584
585
		/* Non-posted methods */
		tp->write32(tp, off, val);
	else {
		/* Posted method */
		tg3_write32(tp, off, val);
		if (usec_wait)
			udelay(usec_wait);
		tp->read32(tp, off);
	}
	/* Wait again after the read for the posted method to guarantee that
	 * the wait time is met.
	 */
	if (usec_wait)
		udelay(usec_wait);
Linus Torvalds's avatar
Linus Torvalds committed
586
587
}

Michael Chan's avatar
Michael Chan committed
588
589
590
static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
{
	tp->write32_mbox(tp, off, val);
591
592
593
	if (tg3_flag(tp, FLUSH_POSTED_WRITES) ||
	    (!tg3_flag(tp, MBOX_WRITE_REORDER) &&
	     !tg3_flag(tp, ICH_WORKAROUND)))
594
		tp->read32_mbox(tp, off);
Michael Chan's avatar
Michael Chan committed
595
596
}

597
static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
Linus Torvalds's avatar
Linus Torvalds committed
598
599
600
{
	void __iomem *mbox = tp->regs + off;
	writel(val, mbox);
601
	if (tg3_flag(tp, TXD_MBOX_HWBUG))
Linus Torvalds's avatar
Linus Torvalds committed
602
		writel(val, mbox);
603
604
	if (tg3_flag(tp, MBOX_WRITE_REORDER) ||
	    tg3_flag(tp, FLUSH_POSTED_WRITES))
Linus Torvalds's avatar
Linus Torvalds committed
605
606
607
		readl(mbox);
}

Michael Chan's avatar
Michael Chan committed
608
609
static u32 tg3_read32_mbox_5906(struct tg3 *tp, u32 off)
{
610
	return readl(tp->regs + off + GRCMBOX_BASE);
Michael Chan's avatar
Michael Chan committed
611
612
613
614
615
616
617
}

static void tg3_write32_mbox_5906(struct tg3 *tp, u32 off, u32 val)
{
	writel(val, tp->regs + off + GRCMBOX_BASE);
}

618
#define tw32_mailbox(reg, val)		tp->write32_mbox(tp, reg, val)
Michael Chan's avatar
Michael Chan committed
619
#define tw32_mailbox_f(reg, val)	tw32_mailbox_flush(tp, (reg), (val))
620
621
622
#define tw32_rx_mbox(reg, val)		tp->write32_rx_mbox(tp, reg, val)
#define tw32_tx_mbox(reg, val)		tp->write32_tx_mbox(tp, reg, val)
#define tr32_mailbox(reg)		tp->read32_mbox(tp, reg)
623

624
625
626
627
#define tw32(reg, val)			tp->write32(tp, reg, val)
#define tw32_f(reg, val)		_tw32_flush(tp, (reg), (val), 0)
#define tw32_wait_f(reg, val, us)	_tw32_flush(tp, (reg), (val), (us))
#define tr32(reg)			tp->read32(tp, reg)
Linus Torvalds's avatar
Linus Torvalds committed
628
629
630

static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
{
631
632
	unsigned long flags;

633
	if (tg3_asic_rev(tp) == ASIC_REV_5906 &&
Michael Chan's avatar
Michael Chan committed
634
635
636
	    (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC))
		return;

637
	spin_lock_irqsave(&tp->indirect_lock, flags);
638
	if (tg3_flag(tp, SRAM_USE_CONFIG)) {
639
640
		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
Linus Torvalds's avatar
Linus Torvalds committed
641

642
643
644
645
646
		/* Always leave this as zero. */
		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
	} else {
		tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
		tw32_f(TG3PCI_MEM_WIN_DATA, val);
Michael Chan's avatar
Michael Chan committed
647

648
649
650
651
		/* Always leave this as zero. */
		tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
	}
	spin_unlock_irqrestore(&tp->indirect_lock, flags);
652
653
}

Linus Torvalds's avatar
Linus Torvalds committed
654
655
static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
{
656
657
	unsigned long flags;

658
	if (tg3_asic_rev(tp) == ASIC_REV_5906 &&
Michael Chan's avatar
Michael Chan committed
659
660
661
662
663
	    (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) {
		*val = 0;
		return;
	}

664
	spin_lock_irqsave(&tp->indirect_lock, flags);
665
	if (tg3_flag(tp, SRAM_USE_CONFIG)) {
666
667
		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
		pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
Linus Torvalds's avatar
Linus Torvalds committed
668

669
670
671
672
673
674
675
676
677
		/* Always leave this as zero. */
		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
	} else {
		tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
		*val = tr32(TG3PCI_MEM_WIN_DATA);

		/* Always leave this as zero. */
		tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
	}
678
	spin_unlock_irqrestore(&tp->indirect_lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
679
680
}

Matt Carlson's avatar
Matt Carlson committed
681
682
683
static void tg3_ape_lock_init(struct tg3 *tp)
{
	int i;
684
	u32 regbase, bit;
685

686
	if (tg3_asic_rev(tp) == ASIC_REV_5761)
687
688
689
		regbase = TG3_APE_LOCK_GRANT;
	else
		regbase = TG3_APE_PER_LOCK_GRANT;
Matt Carlson's avatar
Matt Carlson committed
690
691

	/* Make sure the driver hasn't any stale locks. */
Matt Carlson's avatar
Matt Carlson committed
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
	for (i = TG3_APE_LOCK_PHY0; i <= TG3_APE_LOCK_GPIO; i++) {
		switch (i) {
		case TG3_APE_LOCK_PHY0:
		case TG3_APE_LOCK_PHY1:
		case TG3_APE_LOCK_PHY2:
		case TG3_APE_LOCK_PHY3:
			bit = APE_LOCK_GRANT_DRIVER;
			break;
		default:
			if (!tp->pci_fn)
				bit = APE_LOCK_GRANT_DRIVER;
			else
				bit = 1 << tp->pci_fn;
		}
		tg3_ape_write32(tp, regbase + 4 * i, bit);
707
708
	}

Matt Carlson's avatar
Matt Carlson committed
709
710
711
712
713
714
}

static int tg3_ape_lock(struct tg3 *tp, int locknum)
{
	int i, off;
	int ret = 0;
715
	u32 status, req, gnt, bit;
Matt Carlson's avatar
Matt Carlson committed
716

717
	if (!tg3_flag(tp, ENABLE_APE))
Matt Carlson's avatar
Matt Carlson committed
718
719
720
		return 0;

	switch (locknum) {
721
	case TG3_APE_LOCK_GPIO:
722
		if (tg3_asic_rev(tp) == ASIC_REV_5761)
723
			return 0;
724
		/* fall through */
Matt Carlson's avatar
Matt Carlson committed
725
726
	case TG3_APE_LOCK_GRC:
	case TG3_APE_LOCK_MEM:
Matt Carlson's avatar
Matt Carlson committed
727
728
729
730
		if (!tp->pci_fn)
			bit = APE_LOCK_REQ_DRIVER;
		else
			bit = 1 << tp->pci_fn;
Matt Carlson's avatar
Matt Carlson committed
731
		break;
732
733
734
735
736
737
	case TG3_APE_LOCK_PHY0:
	case TG3_APE_LOCK_PHY1:
	case TG3_APE_LOCK_PHY2:
	case TG3_APE_LOCK_PHY3:
		bit = APE_LOCK_REQ_DRIVER;
		break;
Matt Carlson's avatar
Matt Carlson committed
738
739
	default:
		return -EINVAL;
Matt Carlson's avatar
Matt Carlson committed
740
741
	}

742
	if (tg3_asic_rev(tp) == ASIC_REV_5761) {
743
744
745
746
747
748
749
		req = TG3_APE_LOCK_REQ;
		gnt = TG3_APE_LOCK_GRANT;
	} else {
		req = TG3_APE_PER_LOCK_REQ;
		gnt = TG3_APE_PER_LOCK_GRANT;
	}

Matt Carlson's avatar
Matt Carlson committed
750
751
	off = 4 * locknum;

752
	tg3_ape_write32(tp, req + off, bit);
Matt Carlson's avatar
Matt Carlson committed
753
754
755

	/* Wait for up to 1 millisecond to acquire lock. */
	for (i = 0; i < 100; i++) {
756
		status = tg3_ape_read32(tp, gnt + off);
757
		if (status == bit)
Matt Carlson's avatar
Matt Carlson committed
758
			break;
759
760
761
		if (pci_channel_offline(tp->pdev))
			break;

Matt Carlson's avatar
Matt Carlson committed
762
763
764
		udelay(10);
	}

765
	if (status != bit) {
Matt Carlson's avatar
Matt Carlson committed
766
		/* Revoke the lock request. */
767
		tg3_ape_write32(tp, gnt + off, bit);
Matt Carlson's avatar
Matt Carlson committed
768
769
770
771
772
773
774
775
		ret = -EBUSY;
	}

	return ret;
}

static void tg3_ape_unlock(struct tg3 *tp, int locknum)
{
776
	u32 gnt, bit;
Matt Carlson's avatar
Matt Carlson committed
777

778
	if (!tg3_flag(tp, ENABLE_APE))
Matt Carlson's avatar
Matt Carlson committed
779
780
781
		return;

	switch (locknum) {
782
	case TG3_APE_LOCK_GPIO:
783
		if (tg3_asic_rev(tp) == ASIC_REV_5761)
784
			return;
785
		/* fall through */
Matt Carlson's avatar
Matt Carlson committed
786
787
	case TG3_APE_LOCK_GRC:
	case TG3_APE_LOCK_MEM:
Matt Carlson's avatar
Matt Carlson committed
788
789
790
791
		if (!tp->pci_fn)
			bit = APE_LOCK_GRANT_DRIVER;
		else
			bit = 1 << tp->pci_fn;
Matt Carlson's avatar
Matt Carlson committed
792
		break;
793
794
795
796
797
798
	case TG3_APE_LOCK_PHY0:
	case TG3_APE_LOCK_PHY1:
	case TG3_APE_LOCK_PHY2:
	case TG3_APE_LOCK_PHY3:
		bit = APE_LOCK_GRANT_DRIVER;
		break;
Matt Carlson's avatar
Matt Carlson committed
799
800
	default:
		return;
Matt Carlson's avatar
Matt Carlson committed
801
802
	}

803
	if (tg3_asic_rev(tp) == ASIC_REV_5761)
804
805
806
807
		gnt = TG3_APE_LOCK_GRANT;
	else
		gnt = TG3_APE_PER_LOCK_GRANT;

808
	tg3_ape_write32(tp, gnt + 4 * locknum, bit);
Matt Carlson's avatar
Matt Carlson committed
809
810
}

811
static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us)
812
813
814
{
	u32 apedata;

815
816
817
818
819
820
821
822
823
824
	while (timeout_us) {
		if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM))
			return -EBUSY;

		apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);
		if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
			break;

		tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);

825
		udelay(10);
826
827
828
829
830
831
		timeout_us -= (timeout_us > 10) ? 10 : timeout_us;
	}

	return timeout_us ? 0 : -EBUSY;
}

832
#ifdef CONFIG_TIGON3_HWMON
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
static int tg3_ape_wait_for_event(struct tg3 *tp, u32 timeout_us)
{
	u32 i, apedata;

	for (i = 0; i < timeout_us / 10; i++) {
		apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);

		if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
			break;

		udelay(10);
	}

	return i == timeout_us / 10;
}

Michael Chan's avatar
Michael Chan committed
849
850
static int tg3_ape_scratchpad_read(struct tg3 *tp, u32 *data, u32 base_off,
				   u32 len)
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
{
	int err;
	u32 i, bufoff, msgoff, maxlen, apedata;

	if (!tg3_flag(tp, APE_HAS_NCSI))
		return 0;

	apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
	if (apedata != APE_SEG_SIG_MAGIC)
		return -ENODEV;

	apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
	if (!(apedata & APE_FW_STATUS_READY))
		return -EAGAIN;

	bufoff = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_OFF) +
		 TG3_APE_SHMEM_BASE;
	msgoff = bufoff + 2 * sizeof(u32);
	maxlen = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_LEN);

	while (len) {
		u32 length;

		/* Cap xfer sizes to scratchpad limits. */
		length = (len > maxlen) ? maxlen : len;
		len -= length;

		apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
		if (!(apedata & APE_FW_STATUS_READY))
			return -EAGAIN;

		/* Wait for up to 1 msec for APE to service previous event. */
		err = tg3_ape_event_lock(tp, 1000);
		if (err)
			return err;

		apedata = APE_EVENT_STATUS_DRIVER_EVNT |
			  APE_EVENT_STATUS_SCRTCHPD_READ |
			  APE_EVENT_STATUS_EVENT_PENDING;
		tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, apedata);

		tg3_ape_write32(tp, bufoff, base_off);
		tg3_ape_write32(tp, bufoff + sizeof(u32), length);

		tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
		tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);

		base_off += length;

		if (tg3_ape_wait_for_event(tp, 30000))
			return -EAGAIN;

		for (i = 0; length; i += 4, length -= 4) {
			u32 val = tg3_ape_read32(tp, msgoff + i);
			memcpy(data, &val, sizeof(u32));
			data++;
		}
	}

	return 0;
}
912
#endif
913

914
915
916
917
static int tg3_ape_send_event(struct tg3 *tp, u32 event)
{
	int err;
	u32 apedata;
918
919
920

	apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
	if (apedata != APE_SEG_SIG_MAGIC)
921
		return -EAGAIN;
922
923
924

	apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
	if (!(apedata & APE_FW_STATUS_READY))
925
		return -EAGAIN;
926

927
928
	/* Wait for up to 20 millisecond for APE to service previous event. */
	err = tg3_ape_event_lock(tp, 20000);
929
930
	if (err)
		return err;
931

932
933
	tg3_ape_write32(tp, TG3_APE_EVENT_STATUS,
			event | APE_EVENT_STATUS_EVENT_PENDING);
934

935
936
	tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
	tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);
937

938
	return 0;
939
940
941
942
943
944
945
946
947
948
949
950
}

static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
{
	u32 event;
	u32 apedata;

	if (!tg3_flag(tp, ENABLE_APE))
		return;

	switch (kind) {
	case RESET_KIND_INIT:
951
		tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++);
952
953
954
955
956
957
958
959
960
961
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
		tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG,
				APE_HOST_SEG_SIG_MAGIC);
		tg3_ape_write32(tp, TG3_APE_HOST_SEG_LEN,
				APE_HOST_SEG_LEN_MAGIC);
		apedata = tg3_ape_read32(tp, TG3_APE_HOST_INIT_COUNT);
		tg3_ape_write32(tp, TG3_APE_HOST_INIT_COUNT, ++apedata);
		tg3_ape_write32(tp, TG3_APE_HOST_DRIVER_ID,
			APE_HOST_DRIVER_ID_MAGIC(TG3_MAJ_NUM, TG3_MIN_NUM));
		tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR,
				APE_HOST_BEHAV_NO_PHYLOCK);
		tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE,
				    TG3_APE_HOST_DRVR_STATE_START);

		event = APE_EVENT_STATUS_STATE_START;
		break;
	case RESET_KIND_SHUTDOWN:
		if (device_may_wakeup(&tp->pdev->dev) &&
		    tg3_flag(tp, WOL_ENABLE)) {
			tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED,
					    TG3_APE_HOST_WOL_SPEED_AUTO);
			apedata = TG3_APE_HOST_DRVR_STATE_WOL;
		} else
			apedata = TG3_APE_HOST_DRVR_STATE_UNLOAD;

		tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, apedata);

		event = APE_EVENT_STATUS_STATE_UNLOAD;
		break;
	default:
		return;
	}

	event |= APE_EVENT_STATUS_DRIVER_EVNT | APE_EVENT_STATUS_STATE_CHNGE;

	tg3_ape_send_event(tp, event);
}

989
990
991
992
993
994
995
996
997
998
999
1000
static void tg3_send_ape_heartbeat(struct tg3 *tp,
				   unsigned long interval)
{
	/* Check if hb interval has exceeded */
	if (!tg3_flag(tp, ENABLE_APE) ||
	    time_before(jiffies, tp->ape_hb_jiffies + interval))
		return;

	tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++);
	tp->ape_hb_jiffies = jiffies;
}

Linus Torvalds's avatar
Linus Torvalds committed
1001
1002
static void tg3_disable_ints(struct tg3 *tp)
{
1003
1004
	int i;

Linus Torvalds's avatar
Linus Torvalds committed
1005
1006
	tw32(TG3PCI_MISC_HOST_CTRL,
	     (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
1007
1008
	for (i = 0; i < tp->irq_max; i++)
		tw32_mailbox_f(tp->napi[i].int_mbox, 0x00000001);
Linus Torvalds's avatar
Linus Torvalds committed
1009
1010
1011
1012
}

static void tg3_enable_ints(struct tg3 *tp)
{
1013
1014
	int i;

1015
1016
1017
	tp->irq_sync = 0;
	wmb();

Linus Torvalds's avatar
Linus Torvalds committed
1018
1019
	tw32(TG3PCI_MISC_HOST_CTRL,
	     (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
1020

1021
	tp->coal_now = tp->coalesce_mode | HOSTCC_MODE_ENABLE;
1022
1023
	for (i = 0; i < tp->irq_cnt; i++) {
		struct tg3_napi *tnapi = &tp->napi[i];
1024

1025
		tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
1026
		if (tg3_flag(tp, 1SHOT_MSI))
1027
			tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
Matt Carlson's avatar
Matt Carlson committed
1028

1029
		tp->coal_now |= tnapi->coal_now;
1030
	}
Matt Carlson's avatar
Matt Carlson committed
1031
1032

	/* Force an initial interrupt */
1033
	if (!tg3_flag(tp, TAGGED_STATUS) &&
Matt Carlson's avatar
Matt Carlson committed
1034
1035
1036
	    (tp->napi[0].hw_status->status & SD_STATUS_UPDATED))
		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
	else
1037
1038
1039
		tw32(HOSTCC_MODE, tp->coal_now);

	tp->coal_now &= ~(tp->napi[0].coal_now | tp->napi[1].coal_now);
Linus Torvalds's avatar
Linus Torvalds committed
1040
1041
}

1042
static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
Michael Chan's avatar
Michael Chan committed
1043
{
1044
	struct tg3 *tp = tnapi->tp;
1045
	struct tg3_hw_status *sblk = tnapi->hw_status;
Michael Chan's avatar
Michael Chan committed
1046
1047
1048
	unsigned int work_exists = 0;

	/* check for phy events */
1049
	if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) {
Michael Chan's avatar
Michael Chan committed
1050
1051
1052
		if (sblk->status & SD_STATUS_LINK_CHG)
			work_exists = 1;
	}
1053
1054
1055
1056
1057
1058
1059

	/* check for TX work to do */
	if (sblk->idx[0].tx_consumer != tnapi->tx_cons)
		work_exists = 1;

	/* check for RX work to do */
	if (tnapi->rx_rcb_prod_idx &&
1060
	    *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
Michael Chan's avatar
Michael Chan committed
1061
1062
1063
1064
1065
		work_exists = 1;

	return work_exists;
}

1066
/* tg3_int_reenable
Michael Chan's avatar
Michael Chan committed
1067
1068
 *  similar to tg3_enable_ints, but it accurately determines whether there
 *  is new work pending and can return without flushing the PIO write
1069
 *  which reenables interrupts
Linus Torvalds's avatar
Linus Torvalds committed
1070
 */
1071
static void tg3_int_reenable(struct tg3_napi *tnapi)
Linus Torvalds's avatar
Linus Torvalds committed
1072
{
1073
1074
	struct tg3 *tp = tnapi->tp;

1075
	tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
Linus Torvalds's avatar
Linus Torvalds committed
1076

1077
1078
1079
1080
	/* When doing tagged status, this work check is unnecessary.
	 * The last_tag we write above tells the chip which piece of
	 * work we've completed.
	 */
1081
	if (!tg3_flag(tp, TAGGED_STATUS) && tg3_has_work(tnapi))
Michael Chan's avatar
Michael Chan committed
1082
		tw32(HOSTCC_MODE, tp->coalesce_mode |
1083
		     HOSTCC_MODE_ENABLE | tnapi->coal_now);
Linus Torvalds's avatar
Linus Torvalds committed
1084
1085
1086
1087
}

static void tg3_switch_clocks(struct tg3 *tp)
{
Matt Carlson's avatar
Matt Carlson committed
1088
	u32 clock_ctrl;
Linus Torvalds's avatar
Linus Torvalds committed
1089
1090
	u32 orig_clock_ctrl;

1091
	if (tg3_flag(tp, CPMU_PRESENT) || tg3_flag(tp, 5780_CLASS))
Michael Chan's avatar
Michael Chan committed
1092
1093
		return;

Matt Carlson's avatar
Matt Carlson committed
1094
1095
	clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);

Linus Torvalds's avatar
Linus Torvalds committed
1096
1097
1098
1099
1100
1101
	orig_clock_ctrl = clock_ctrl;
	clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN |
		       CLOCK_CTRL_CLKRUN_OENABLE |
		       0x1f);
	tp->pci_clock_ctrl = clock_ctrl;

1102
	if (tg3_flag(tp, 5705_PLUS)) {
Linus Torvalds's avatar
Linus Torvalds committed
1103
		if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) {
1104
1105
			tw32_wait_f(TG3PCI_CLOCK_CTRL,
				    clock_ctrl | CLOCK_CTRL_625_CORE, 40);
Linus Torvalds's avatar
Linus Torvalds committed
1106
1107
		}
	} else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) {
1108
1109
1110
1111
1112
1113
1114
		tw32_wait_f(TG3PCI_CLOCK_CTRL,
			    clock_ctrl |
			    (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK),
			    40);
		tw32_wait_f(TG3PCI_CLOCK_CTRL,
			    clock_ctrl | (CLOCK_CTRL_ALTCLK),
			    40);
Linus Torvalds's avatar
Linus Torvalds committed
1115
	}
1116
	tw32_wait_f(TG3PCI_CLOCK_CTRL, clock_ctrl, 40);
Linus Torvalds's avatar
Linus Torvalds committed
1117
1118
1119
1120
}

#define PHY_BUSY_LOOPS	5000

1121
1122
static int __tg3_readphy(struct tg3 *tp, unsigned int phy_addr, int reg,
			 u32 *val)
Linus Torvalds's avatar
Linus Torvalds committed
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
{
	u32 frame_val;
	unsigned int loops;
	int ret;

	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
		tw32_f(MAC_MI_MODE,
		     (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
		udelay(80);
	}

1134
1135
	tg3_ape_lock(tp, tp->phy_ape_lock);

Linus Torvalds's avatar
Linus Torvalds committed
1136
1137
	*val = 0x0;

1138
	frame_val  = ((phy_addr << MI_COM_PHY_ADDR_SHIFT) &
Linus Torvalds's avatar
Linus Torvalds committed
1139
1140
1141
1142
		      MI_COM_PHY_ADDR_MASK);
	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
		      MI_COM_REG_ADDR_MASK);
	frame_val |= (MI_COM_CMD_READ | MI_COM_START);
1143

Linus Torvalds's avatar
Linus Torvalds committed
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
	tw32_f(MAC_MI_COM, frame_val);

	loops = PHY_BUSY_LOOPS;
	while (loops != 0) {
		udelay(10);
		frame_val = tr32(MAC_MI_COM);

		if ((frame_val & MI_COM_BUSY) == 0) {
			udelay(5);
			frame_val = tr32(MAC_MI_COM);
			break;
		}
		loops -= 1;
	}

	ret = -EBUSY;
	if (loops != 0) {
		*val = frame_val & MI_COM_DATA_MASK;
		ret = 0;
	}

	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
		tw32_f(MAC_MI_MODE, tp->mi_mode);
		udelay(80);
	}

1170
1171
	tg3_ape_unlock(tp, tp->phy_ape_lock);

Linus Torvalds's avatar
Linus Torvalds committed
1172
1173
1174
	return ret;
}

1175
1176
1177
1178
1179
1180
1181
static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
{
	return __tg3_readphy(tp, tp->phy_addr, reg, val);
}

static int __tg3_writephy(struct tg3 *tp, unsigned int phy_addr, int reg,
			  u32 val)
Linus Torvalds's avatar
Linus Torvalds committed
1182
1183
1184
1185
1186
{
	u32 frame_val;
	unsigned int loops;
	int ret;

1187
	if ((tp->phy_flags & TG3_PHYFLG_IS_FET) &&
1188
	    (reg == MII_CTRL1000 || reg == MII_TG3_AUX_CTRL))
Michael Chan's avatar
Michael Chan committed
1189
1190
		return 0;

Linus Torvalds's avatar
Linus Torvalds committed
1191
1192
1193
1194
1195
1196
	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
		tw32_f(MAC_MI_MODE,
		     (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
		udelay(80);
	}

1197
1198
	tg3_ape_lock(tp, tp->phy_ape_lock);

1199
	frame_val  = ((phy_addr << MI_COM_PHY_ADDR_SHIFT) &
Linus Torvalds's avatar
Linus Torvalds committed
1200
1201
1202
1203
1204
		      MI_COM_PHY_ADDR_MASK);
	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
		      MI_COM_REG_ADDR_MASK);
	frame_val |= (val & MI_COM_DATA_MASK);
	frame_val |= (MI_COM_CMD_WRITE | MI_COM_START);
1205

Linus Torvalds's avatar
Linus Torvalds committed
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
	tw32_f(MAC_MI_COM, frame_val);

	loops = PHY_BUSY_LOOPS;
	while (loops != 0) {
		udelay(10);
		frame_val = tr32(MAC_MI_COM);
		if ((frame_val & MI_COM_BUSY) == 0) {
			udelay(5);
			frame_val = tr32(MAC_MI_COM);
			break;
		}
		loops -= 1;
	}

	ret = -EBUSY;
	if (loops != 0)
		ret = 0;

	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
		tw32_f(MAC_MI_MODE, tp->mi_mode);
		udelay(80);
	}

1229
1230
	tg3_ape_unlock(tp, tp->phy_ape_lock);

Linus Torvalds's avatar
Linus Torvalds committed
1231
1232
1233
	return ret;
}

1234
1235
1236
1237
1238
static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
{
	return __tg3_writephy(tp, tp->phy_addr, reg, val);
}

1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
{
	int err;

	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
	if (err)
		goto done;

	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
	if (err)
		goto done;

	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
	if (err)
		goto done;

	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val);

done:
	return err;
}

static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val)
{
	int err;