1/******************************************************************************/
2/*                                                                            */
3/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom  */
4/* Corporation.                                                               */
5/* All rights reserved.                                                       */
6/*                                                                            */
7/* This program is free software; you can redistribute it and/or modify       */
8/* it under the terms of the GNU General Public License as published by       */
9/* the Free Software Foundation, located in the file LICENSE.                 */
10/*                                                                            */
11/* ethtool -t selftest code.                                                  */
12/*                                                                            */
13/******************************************************************************/
14
15#include "mm.h"
16
17#ifdef NICE_SUPPORT
18#include "nicext.h"
19#endif
20
21#ifdef ETHTOOL_TEST
22
23typedef struct reg_entry
24{
25	LM_UINT16   offset;
26	LM_UINT16   flags;
27#define BCM5705_ONLY		1
28#define NOT_FOR_BCM5705		2
29#define NOT_FOR_BCM5788		4
30	LM_UINT32   read_mask;
31	LM_UINT32   write_mask;
32} reg_entry_t;
33
34typedef struct mem_entry
35{
36	LM_UINT32   offset;
37	LM_UINT32   len;
38} mem_entry_t;
39
40/* Returns 1 on success, 0 on failure */
41int
42b57_test_registers(UM_DEVICE_BLOCK *pUmDevice)
43{
44	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
45	int ret;
46	int i, bcm5705;
47	LM_UINT32 offset, read_mask, write_mask, val, save_val, read_val;
48	static reg_entry_t reg_tbl[] = {
49		/* MAC block */
50		{ 0x0400, 0x0002, 0x00000000, 0x00ef6f8c },
51		{ 0x0400, 0x0001, 0x00000000, 0x01ef6b8c },	/* 5705 */
52		{ 0x0404, 0x0002, 0x03800107, 0x00000000 },
53		{ 0x0404, 0x0001, 0x03800100, 0x00000000 },	/* 5705 */
54		{ 0x0408, 0x0002, 0x00000000, 0x07c01400 },
55		{ 0x0408, 0x0001, 0x00000000, 0x07c01000 },	/* 5705 */
56		{ 0x040c, 0x0000, 0x00000000, 0xfff8007f },
57		{ 0x0410, 0x0000, 0x00000000, 0x0000ffff },
58		{ 0x0414, 0x0000, 0x00000000, 0xffffffff },
59		{ 0x0418, 0x0000, 0x00000000, 0x0000ffff },
60		{ 0x041c, 0x0000, 0x00000000, 0xffffffff },
61		{ 0x0420, 0x0000, 0x00000000, 0x0000ffff },
62		{ 0x0424, 0x0000, 0x00000000, 0xffffffff },
63		{ 0x0428, 0x0000, 0x00000000, 0x0000ffff },
64		{ 0x042c, 0x0000, 0x00000000, 0xffffffff },
65		{ 0x0430, 0x0002, 0x00000000, 0xffffffff },
66		{ 0x0430, 0x0001, 0x00000000, 0x0fff03ff },	/* 5705 */
67		{ 0x0434, 0x0002, 0x00000000, 0x0fffffff },
68		{ 0x0434, 0x0001, 0x00000000, 0x000001ff },	/* 5705 */
69		{ 0x043c, 0x0000, 0x00000000, 0x0000ffff },
70		{ 0x0454, 0x0000, 0x00000000, 0x00000010 },
71		{ 0x045c, 0x0000, 0x00000000, 0x00000070 },
72		{ 0x0464, 0x0000, 0x00000000, 0x00003fff },
73		{ 0x0468, 0x0002, 0x00000000, 0x000007fc },
74		{ 0x0468, 0x0001, 0x00000000, 0x000007dc },	/* 5705 */
75		{ 0x0470, 0x0000, 0x00000000, 0xffffffff },
76		{ 0x0474, 0x0000, 0x00000000, 0xffffffff },
77		{ 0x0478, 0x0000, 0x00000000, 0xffffffff },
78		{ 0x047c, 0x0000, 0x00000000, 0xffffffff },
79		{ 0x0480, 0x0002, 0x00000000, 0xffffffff },
80		{ 0x0480, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
81		{ 0x0484, 0x0000, 0x00000000, 0xffffffff },
82		{ 0x0488, 0x0002, 0x00000000, 0xffffffff },
83		{ 0x0488, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
84		{ 0x048c, 0x0000, 0x00000000, 0xffffffff },
85		{ 0x0490, 0x0002, 0x00000000, 0xffffffff },
86		{ 0x0490, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
87		{ 0x0494, 0x0000, 0x00000000, 0xffffffff },
88		{ 0x0498, 0x0002, 0x00000000, 0xffffffff },
89		{ 0x0498, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
90		{ 0x049c, 0x0000, 0x00000000, 0xffffffff },
91		{ 0x04a0, 0x0002, 0x00000000, 0xffffffff },
92		{ 0x04a0, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
93		{ 0x04a4, 0x0000, 0x00000000, 0xffffffff },
94		{ 0x04a8, 0x0002, 0x00000000, 0xffffffff },
95		{ 0x04a8, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
96		{ 0x04ac, 0x0000, 0x00000000, 0xffffffff },
97		{ 0x04b0, 0x0002, 0x00000000, 0xffffffff },
98		{ 0x04b0, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
99		{ 0x04b4, 0x0000, 0x00000000, 0xffffffff },
100		{ 0x04b8, 0x0002, 0x00000000, 0xffffffff },
101		{ 0x04b8, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
102		{ 0x04bc, 0x0000, 0x00000000, 0xffffffff },
103		{ 0x04c0, 0x0002, 0x00000000, 0xffffffff },
104		{ 0x04c4, 0x0002, 0x00000000, 0xffffffff },
105		{ 0x04c8, 0x0002, 0x00000000, 0xffffffff },
106		{ 0x04cc, 0x0002, 0x00000000, 0xffffffff },
107		{ 0x04d0, 0x0002, 0x00000000, 0xffffffff },
108		{ 0x04d4, 0x0002, 0x00000000, 0xffffffff },
109		{ 0x04d8, 0x0002, 0x00000000, 0xffffffff },
110		{ 0x04dc, 0x0002, 0x00000000, 0xffffffff },
111		{ 0x04e0, 0x0002, 0x00000000, 0xffffffff },
112		{ 0x04e4, 0x0002, 0x00000000, 0xffffffff },
113		{ 0x04e8, 0x0002, 0x00000000, 0xffffffff },
114		{ 0x04ec, 0x0002, 0x00000000, 0xffffffff },
115		{ 0x04f0, 0x0002, 0x00000000, 0xffffffff },
116		{ 0x04f4, 0x0002, 0x00000000, 0xffffffff },
117		{ 0x04f8, 0x0002, 0x00000000, 0xffffffff },
118		{ 0x04fc, 0x0002, 0x00000000, 0xffffffff },
119		{ 0x0500, 0x0002, 0x00000000, 0x000000f8 },
120		{ 0x0500, 0x0001, 0x00000000, 0x00000008 },	/* 5705 */
121
122		/* Send Data Initiator Control Registers */
123		{ 0x0c00, 0x0000, 0x00000000, 0x00000006 },
124		{ 0x0c04, 0x0000, 0x00000004, 0x00000000 },
125		{ 0x0c08, 0x0000, 0x00000000, 0x0000001b },
126		{ 0x0c0c, 0x0002, 0x00000000, 0x00ffffff },
127		{ 0x0c0c, 0x0001, 0x00000000, 0x00000001 },
128		{ 0x0c80, 0x0000, 0x000003ff, 0x00000000 },
129		{ 0x0c84, 0x0002, 0x000003ff, 0x00000000 },
130		{ 0x0c88, 0x0002, 0x000003ff, 0x00000000 },
131		{ 0x0c8c, 0x0002, 0x000003ff, 0x00000000 },
132		{ 0x0c90, 0x0002, 0x000003ff, 0x00000000 },
133		{ 0x0c94, 0x0002, 0x000003ff, 0x00000000 },
134		{ 0x0c98, 0x0002, 0x000003ff, 0x00000000 },
135		{ 0x0c9c, 0x0002, 0x000003ff, 0x00000000 },
136		{ 0x0ca0, 0x0002, 0x000003ff, 0x00000000 },
137		{ 0x0ca4, 0x0002, 0x000003ff, 0x00000000 },
138		{ 0x0ca8, 0x0002, 0x000003ff, 0x00000000 },
139		{ 0x0cac, 0x0002, 0x000003ff, 0x00000000 },
140		{ 0x0cb0, 0x0002, 0x000003ff, 0x00000000 },
141		{ 0x0cb4, 0x0002, 0x000003ff, 0x00000000 },
142		{ 0x0cb8, 0x0002, 0x000003ff, 0x00000000 },
143		{ 0x0cbc, 0x0002, 0x000003ff, 0x00000000 },
144		{ 0x0cc0, 0x0002, 0x000003ff, 0x00000000 },
145		{ 0x0cc4, 0x0002, 0x000003ff, 0x00000000 },
146		{ 0x0cc8, 0x0002, 0x000003ff, 0x00000000 },
147		{ 0x0ccc, 0x0002, 0x000003ff, 0x00000000 },
148		{ 0x0cd0, 0x0002, 0x000003ff, 0x00000000 },
149		{ 0x0cd4, 0x0002, 0x000003ff, 0x00000000 },
150		{ 0x0cd8, 0x0002, 0x000003ff, 0x00000000 },
151		{ 0x0cdc, 0x0002, 0x000003ff, 0x00000000 },
152		{ 0x0ce0, 0x0001, 0x00000000, 0xffffffff },	/* 5705 */
153		{ 0x0ce4, 0x0001, 0x00000000, 0xffffffff },	/* 5705 */
154		{ 0x0ce8, 0x0001, 0x00000000, 0x00ffffff },	/* 5705 */
155		{ 0x0cec, 0x0001, 0x00000000, 0x000efcf7 },	/* 5705 */
156		{ 0x0cf0, 0x0001, 0x00000000, 0x0000ffff },	/* 5705 */
157		{ 0x0cf4, 0x0001, 0x00000000, 0x20000000 },	/* 5705 */
158
159		/* SDC Control Registers */
160		{ 0x1000, 0x0000, 0x00000000, 0x00000002 },
161		{ 0x1008, 0x0001, 0x00000000, 0x40000000 },	/* 5705 */
162
163		/* Send BD Ring Selector Control Registers. */
164		{ 0x1400, 0x0000, 0x00000000, 0x00000006 },
165		{ 0x1404, 0x0000, 0x00000004, 0x00000000 },
166		{ 0x1408, 0x0000, 0x0000ffff, 0x00000000 },
167		{ 0x1440, 0x0000, 0x0000000f, 0x00000000 },
168		{ 0x1444, 0x0002, 0x0000000f, 0x00000000 },
169		{ 0x1448, 0x0002, 0x0000000f, 0x00000000 },
170		{ 0x144c, 0x0002, 0x0000000f, 0x00000000 },
171		{ 0x1450, 0x0002, 0x0000000f, 0x00000000 },
172		{ 0x1454, 0x0002, 0x0000000f, 0x00000000 },
173		{ 0x1458, 0x0002, 0x0000000f, 0x00000000 },
174		{ 0x145c, 0x0002, 0x0000000f, 0x00000000 },
175		{ 0x1460, 0x0002, 0x0000000f, 0x00000000 },
176		{ 0x1464, 0x0002, 0x0000000f, 0x00000000 },
177		{ 0x1468, 0x0002, 0x0000000f, 0x00000000 },
178		{ 0x146c, 0x0002, 0x0000000f, 0x00000000 },
179		{ 0x1470, 0x0002, 0x0000000f, 0x00000000 },
180		{ 0x1474, 0x0002, 0x0000000f, 0x00000000 },
181		{ 0x1478, 0x0002, 0x0000000f, 0x00000000 },
182		{ 0x147c, 0x0002, 0x0000000f, 0x00000000 },
183
184		/* Send BD Inititor Control Registers.*/
185		{ 0x1800, 0x0000, 0x00000000, 0x00000006 },
186		{ 0x1804, 0x0000, 0x00000004, 0x00000000 },
187		{ 0x1808, 0x0000, 0xffffffff, 0x00000000 },
188		{ 0x180c, 0x0002, 0xffffffff, 0x00000000 },
189		{ 0x1810, 0x0002, 0xffffffff, 0x00000000 },
190		{ 0x1814, 0x0002, 0xffffffff, 0x00000000 },
191		{ 0x1818, 0x0002, 0xffffffff, 0x00000000 },
192		{ 0x181c, 0x0002, 0xffffffff, 0x00000000 },
193		{ 0x1820, 0x0002, 0xffffffff, 0x00000000 },
194		{ 0x1824, 0x0002, 0xffffffff, 0x00000000 },
195		{ 0x1828, 0x0002, 0xffffffff, 0x00000000 },
196		{ 0x182c, 0x0002, 0xffffffff, 0x00000000 },
197		{ 0x1830, 0x0002, 0xffffffff, 0x00000000 },
198		{ 0x1834, 0x0002, 0xffffffff, 0x00000000 },
199		{ 0x1838, 0x0002, 0xffffffff, 0x00000000 },
200		{ 0x183c, 0x0002, 0xffffffff, 0x00000000 },
201		{ 0x1840, 0x0002, 0xffffffff, 0x00000000 },
202		{ 0x1844, 0x0002, 0xffffffff, 0x00000000 },
203
204		/* Send BD Completion Control Registers */
205		{ 0x1c00, 0x0000, 0x00000000, 0x00000002 },
206
207		/* Receive List Placement Control Registers. */
208		{ 0x2000, 0x0000, 0x00000000, 0x0000001e },
209		{ 0x2004, 0x0000, 0x0000001c, 0x00000000 },
210		{ 0x2010, 0x0002, 0x00000000, 0x00007fff },
211		{ 0x2010, 0x0001, 0x00000000, 0x000060ff },	/* 5705 */
212		{ 0x2014, 0x0000, 0x00000000, 0x00000001 },
213		{ 0x2200, 0x0000, 0x000003ff, 0x00000000 },
214		{ 0x2204, 0x0002, 0x000003ff, 0x00000000 },
215		{ 0x2208, 0x0002, 0x000003ff, 0x00000000 },
216		{ 0x220c, 0x0002, 0x000003ff, 0x00000000 },
217		{ 0x2210, 0x0002, 0x000003ff, 0x00000000 },
218		{ 0x2214, 0x0002, 0x000003ff, 0x00000000 },
219		{ 0x2218, 0x0002, 0x000003ff, 0x00000000 },
220		{ 0x221c, 0x0002, 0x000003ff, 0x00000000 },
221		{ 0x2220, 0x0002, 0x000003ff, 0x00000000 },
222		{ 0x2224, 0x0002, 0x000003ff, 0x00000000 },
223		{ 0x2228, 0x0002, 0x000003ff, 0x00000000 },
224		{ 0x222c, 0x0002, 0x000003ff, 0x00000000 },
225		{ 0x2230, 0x0002, 0x000003ff, 0x00000000 },
226		{ 0x2234, 0x0002, 0x000003ff, 0x00000000 },
227		{ 0x2238, 0x0002, 0x000003ff, 0x00000000 },
228		{ 0x223c, 0x0002, 0x000003ff, 0x00000000 },
229		{ 0x2240, 0x0002, 0x000003ff, 0x00000000 },
230		{ 0x2244, 0x0002, 0x000003ff, 0x00000000 },
231		{ 0x2248, 0x0002, 0x000003ff, 0x00000000 },
232		{ 0x224c, 0x0000, 0x000003ff, 0x00000000 },
233		{ 0x2250, 0x0000, 0x000003ff, 0x00000000 },
234		{ 0x2254, 0x0000, 0x000003ff, 0x00000000 },
235		{ 0x2258, 0x0002, 0x000003ff, 0x00000000 },
236
237		/* Receive Data and Receive BD Initiator Control Registers. */
238		{ 0x2400, 0x0002, 0x00000000, 0x0000001e },
239		{ 0x2400, 0x0001, 0x00000000, 0x0000001a },	/* 5705 */
240		{ 0x2404, 0x0000, 0x0000001c, 0x00000000 },
241		{ 0x2408, 0x0002, 0x00000000, 0x0000ffff },
242		{ 0x2440, 0x0002, 0x00000000, 0xffffffff },
243		{ 0x2444, 0x0002, 0x00000000, 0xffffffff },
244		{ 0x2448, 0x0002, 0x00000000, 0x00000003 },
245		{ 0x244c, 0x0002, 0x00000000, 0xffffffff },
246		{ 0x2450, 0x0000, 0x00000000, 0xffffffff },
247		{ 0x2454, 0x0000, 0x00000000, 0xffffffff },
248		{ 0x2458, 0x0000, 0x00000000, 0xffff0002 },
249		{ 0x245c, 0x0000, 0x00000000, 0xffffffff },
250		{ 0x2470, 0x0002, 0xffffffff, 0x00000000 },
251		{ 0x2474, 0x0000, 0xffffffff, 0x00000000 },
252		{ 0x2478, 0x0002, 0xffffffff, 0x00000000 },
253		{ 0x2480, 0x0000, 0xffffffff, 0x00000000 },
254		{ 0x2484, 0x0002, 0xffffffff, 0x00000000 },
255		{ 0x2488, 0x0002, 0xffffffff, 0x00000000 },
256		{ 0x248c, 0x0002, 0xffffffff, 0x00000000 },
257		{ 0x2490, 0x0002, 0xffffffff, 0x00000000 },
258		{ 0x2494, 0x0002, 0xffffffff, 0x00000000 },
259		{ 0x2498, 0x0002, 0xffffffff, 0x00000000 },
260		{ 0x249c, 0x0002, 0xffffffff, 0x00000000 },
261		{ 0x24a0, 0x0002, 0xffffffff, 0x00000000 },
262		{ 0x24a4, 0x0002, 0xffffffff, 0x00000000 },
263		{ 0x24a8, 0x0002, 0xffffffff, 0x00000000 },
264		{ 0x24ac, 0x0002, 0xffffffff, 0x00000000 },
265		{ 0x24b0, 0x0002, 0xffffffff, 0x00000000 },
266		{ 0x24b4, 0x0002, 0xffffffff, 0x00000000 },
267		{ 0x24b8, 0x0002, 0xffffffff, 0x00000000 },
268		{ 0x24bc, 0x0002, 0xffffffff, 0x00000000 },
269		{ 0x24c0, 0x0000, 0xffffffff, 0x00000000 },
270
271		/* Receive Data Completion Control Registers */
272		{ 0x2800, 0x0000, 0x00000000, 0x00000002 },
273
274		/* Receive BD Initiator Control Registers. */
275		{ 0x2c00, 0x0000, 0x00000000, 0x00000006 },
276		{ 0x2c04, 0x0000, 0x00000004, 0x00000000 },
277		{ 0x2c18, 0x0002, 0x00000000, 0xffffffff },
278		{ 0x2c18, 0x0001, 0x00000000, 0x000003ff },	/* 5705 */
279		{ 0x2c1c, 0x0002, 0x00000000, 0xffffffff },
280
281		/* Receive BD Completion Control Registers. */
282		{ 0x3000, 0x0000, 0x00000000, 0x00000006 },
283		{ 0x3004, 0x0000, 0x00000004, 0x00000000 },
284		{ 0x3008, 0x0002, 0x00000000, 0x000000ff },
285		{ 0x300c, 0x0000, 0x00000000, 0x000001ff },
286
287		/* Host Coalescing Control Registers. */
288		{ 0x3c00, 0x0002, 0x00000000, 0x00000004 },
289		{ 0x3c00, 0x0001, 0x00000000, 0x000000f6 },	/* 5705 */
290		{ 0x3c04, 0x0000, 0x00000004, 0x00000000 },
291		{ 0x3c08, 0x0002, 0x00000000, 0xffffffff },
292		{ 0x3c08, 0x0001, 0x00000000, 0x000003ff },	/* 5705 */
293		{ 0x3c0c, 0x0002, 0x00000000, 0xffffffff },
294		{ 0x3c0c, 0x0001, 0x00000000, 0x000003ff },	/* 5705 */
295		{ 0x3c10, 0x0002, 0x00000000, 0xffffffff },
296		{ 0x3c10, 0x0005, 0x00000000, 0x000000ff },	/* 5705 */
297		{ 0x3c14, 0x0002, 0x00000000, 0xffffffff },
298		{ 0x3c14, 0x0005, 0x00000000, 0x000000ff },	/* 5705 */
299		{ 0x3c18, 0x0002, 0x00000000, 0xffffffff },
300		{ 0x3c1c, 0x0002, 0x00000000, 0xffffffff },
301		{ 0x3c20, 0x0002, 0x00000000, 0xffffffff },
302		{ 0x3c20, 0x0005, 0x00000000, 0x000000ff },	/* 5705 */
303		{ 0x3c24, 0x0002, 0x00000000, 0xffffffff },
304		{ 0x3c24, 0x0005, 0x00000000, 0x000000ff },	/* 5705 */
305		{ 0x3c28, 0x0002, 0x00000000, 0xffffffff },
306		{ 0x3c30, 0x0002, 0x00000000, 0xffffffff },
307		{ 0x3c34, 0x0002, 0x00000000, 0xffffffff },
308		{ 0x3c38, 0x0000, 0x00000000, 0xffffffff },
309		{ 0x3c3c, 0x0000, 0x00000000, 0xffffffff },
310		{ 0x3c40, 0x0000, 0xffffffff, 0x00000000 },
311		{ 0x3c44, 0x0000, 0xffffffff, 0x00000000 },
312		{ 0x3c50, 0x0002, 0x00000000, 0x000000ff },
313		{ 0x3c54, 0x0000, 0x00000000, 0x000000ff },
314		{ 0x3c80, 0x0002, 0x00000000, 0x000007ff },
315		{ 0x3c80, 0x0001, 0x00000000, 0x000001ff },	/* 5705 */
316		{ 0x3c84, 0x0002, 0x00000000, 0x000007ff },
317		{ 0x3c88, 0x0002, 0x00000000, 0x000007ff },
318		{ 0x3c8c, 0x0002, 0x00000000, 0x000007ff },
319		{ 0x3c90, 0x0002, 0x00000000, 0x000007ff },
320		{ 0x3c94, 0x0002, 0x00000000, 0x000007ff },
321		{ 0x3c98, 0x0002, 0x00000000, 0x000007ff },
322		{ 0x3c9c, 0x0002, 0x00000000, 0x000007ff },
323		{ 0x3ca0, 0x0002, 0x00000000, 0x000007ff },
324		{ 0x3ca4, 0x0002, 0x00000000, 0x000007ff },
325		{ 0x3ca8, 0x0002, 0x00000000, 0x000007ff },
326		{ 0x3cac, 0x0002, 0x00000000, 0x000007ff },
327		{ 0x3cb0, 0x0002, 0x00000000, 0x000007ff },
328		{ 0x3cb4, 0x0002, 0x00000000, 0x000007ff },
329		{ 0x3cb8, 0x0002, 0x00000000, 0x000007ff },
330		{ 0x3cbc, 0x0002, 0x00000000, 0x000007ff },
331		{ 0x3cc0, 0x0000, 0x00000000, 0x000001ff },
332		{ 0x3cc4, 0x0002, 0x00000000, 0x000001ff },
333		{ 0x3cc8, 0x0002, 0x00000000, 0x000001ff },
334		{ 0x3ccc, 0x0002, 0x00000000, 0x000001ff },
335		{ 0x3cd0, 0x0002, 0x00000000, 0x000001ff },
336		{ 0x3cd4, 0x0002, 0x00000000, 0x000001ff },
337		{ 0x3cd8, 0x0002, 0x00000000, 0x000001ff },
338		{ 0x3cdc, 0x0002, 0x00000000, 0x000001ff },
339		{ 0x3ce0, 0x0002, 0x00000000, 0x000001ff },
340		{ 0x3ce4, 0x0002, 0x00000000, 0x000001ff },
341		{ 0x3ce8, 0x0002, 0x00000000, 0x000001ff },
342		{ 0x3cec, 0x0002, 0x00000000, 0x000001ff },
343		{ 0x3cf0, 0x0002, 0x00000000, 0x000001ff },
344		{ 0x3cf4, 0x0002, 0x00000000, 0x000001ff },
345		{ 0x3cf8, 0x0002, 0x00000000, 0x000001ff },
346		{ 0x3cfc, 0x0002, 0x00000000, 0x000001ff },
347
348		/* Memory Arbiter Registers */
349		{ 0x4000, 0x0002, 0x00000000, 0x001ffffe },
350		{ 0x4000, 0x0001, 0x00000000, 0x38111e7e },
351		{ 0x4004, 0x0002, 0x001ffffc, 0x00000000 },
352		{ 0x4004, 0x0002, 0x00111dfc, 0x00000000 },
353		{ 0x4008, 0x0000, 0x00000000, 0x001fffff },
354		{ 0x400c, 0x0000, 0x00000000, 0x001fffff },
355
356		/* Buffer Manager Control Registers. */
357		{ 0x4400, 0x0000, 0x00000000, 0x0000001c },
358		{ 0x4404, 0x0000, 0x00000014, 0x00000000 },
359		{ 0x4408, 0x0000, 0x00000000, 0x007fff80 },
360		{ 0x440c, 0x0000, 0x00000000, 0x007fffff },
361		{ 0x4410, 0x0000, 0x00000000, 0x0000003f },
362		{ 0x4414, 0x0000, 0x00000000, 0x000001ff },
363		{ 0x4418, 0x0000, 0x00000000, 0x000001ff },
364		{ 0x4420, 0x0000, 0xffffffff, 0x00000000 },
365		{ 0x4428, 0x0002, 0xffffffff, 0x00000000 },
366		{ 0x442c, 0x0002, 0xffffffff, 0x00000000 },
367		{ 0x4430, 0x0002, 0xffffffff, 0x00000000 },
368		{ 0x4440, 0x0002, 0xffffffff, 0x00000000 },
369		{ 0x4448, 0x0002, 0xffffffff, 0x00000000 },
370		{ 0x444c, 0x0000, 0xffffffff, 0x00000000 },
371		{ 0x4450, 0x0000, 0xffffffff, 0x00000000 },
372		{ 0x4454, 0x0000, 0xffffffff, 0x00000000 },
373		{ 0x4458, 0x0001, 0x00000000, 0x000001ff },	/* 5705 */
374
375		{ 0x4800, 0x0002, 0x00000000, 0x000003fe },
376		{ 0x4800, 0x0001, 0x00000000, 0xc00003fe },	/* 5705 */
377		{ 0x4804, 0x0000, 0x000003fc, 0x00000000 },
378		{ 0x4c00, 0x0002, 0x00000000, 0x000003fc },
379		{ 0x4c00, 0x0001, 0x00000000, 0x000007fc },	/* 5705 */
380		{ 0x4c04, 0x0000, 0x000003fc, 0x00000000 },
381
382		/* Mailbox Registers */
383		{ 0x5804, 0x0000, 0x00000000, 0xffffffff },
384		{ 0x586c, 0x0000, 0x00000000, 0x000001ff },
385		{ 0x5874, 0x0002, 0x00000000, 0x000001ff },
386		{ 0x5884, 0x0000, 0x00000000, 0x000007ff },
387		{ 0x5904, 0x0000, 0x00000000, 0x000001ff },
388		{ 0x5984, 0x0002, 0x00000000, 0x000001ff },
389		{ 0x5a04, 0x0000, 0x00000000, 0xffffffff },
390		{ 0x5a0c, 0x0000, 0x00000000, 0xffffffff },
391
392		/* Flow Through Queues. */
393		{ 0x5c14, 0x0002, 0xffffffff, 0x00000000 },
394		{ 0x5c24, 0x0002, 0xffffffff, 0x00000000 },
395		{ 0x5c34, 0x0002, 0xffffffff, 0x00000000 },
396		{ 0x5c44, 0x0002, 0xffffffff, 0x00000000 },
397		{ 0x5c54, 0x0002, 0xffffffff, 0x00000000 },
398		{ 0x5c64, 0x0002, 0xffffffff, 0x00000000 },
399		{ 0x5c74, 0x0002, 0xffffffff, 0x00000000 },
400		{ 0x5c84, 0x0002, 0xffffffff, 0x00000000 },
401		{ 0x5c94, 0x0002, 0xffffffff, 0x00000000 },
402		{ 0x5ca4, 0x0002, 0xffffffff, 0x00000000 },
403		{ 0x5cb4, 0x0002, 0xffffffff, 0x00000000 },
404		{ 0x5cc4, 0x0002, 0xffffffff, 0x00000000 },
405		{ 0x5cd4, 0x0002, 0xffffffff, 0x00000000 },
406		{ 0x5ce4, 0x0002, 0xffffffff, 0x00000000 },
407		{ 0x5cf4, 0x0002, 0xffffffff, 0x00000000 },
408		{ 0x5d04, 0x0002, 0xffffffff, 0x00000000 },
409		{ 0x5d14, 0x0002, 0xffffffff, 0x00000000 },
410		{ 0xffff, 0x0000, 0x00000000, 0x00000000 },
411	};
412
413    if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId)){
414		bcm5705 = 1;
415	}
416	else {
417		bcm5705 = 0;
418	}
419
420	ret = 1;
421	for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
422		if (bcm5705 && (reg_tbl[i].flags & NOT_FOR_BCM5705))
423			continue;
424		if (!bcm5705 && (reg_tbl[i].flags & BCM5705_ONLY))
425			continue;
426		if ((pDevice->Flags & BCM5788_FLAG) &&
427			(reg_tbl[i].flags & NOT_FOR_BCM5788))
428			continue;
429		offset = (LM_UINT32) reg_tbl[i].offset;
430		read_mask = reg_tbl[i].read_mask;
431		write_mask = reg_tbl[i].write_mask;
432
433		/* Save the original register content */
434		save_val = LM_RegRd(pDevice, offset);
435
436		/* Determine the read-only value. */
437		read_val = save_val & read_mask;
438
439		/* Write zero to the register, then make sure the read-only bits
440		   are not changed and the read/write bits are all zeros. */
441		LM_RegWr(pDevice, offset, 0, FALSE);
442
443		val = LM_RegRd(pDevice, offset);
444
445		/* Test the read-only and read/write bits. */
446		if (((val & read_mask) != read_val) ||
447			(val & write_mask)) {
448
449	                ret = 0;
450			LM_RegWr(pDevice, offset, save_val, FALSE);
451			break;
452		}
453
454
455		/* Write ones to all the bits defined by RdMask and WrMask, then
456		   make sure the read-only bits are not changed and the
457		   read/write bits are all ones. */
458		LM_RegWr(pDevice, offset, read_mask | write_mask, FALSE);
459
460		val = LM_RegRd(pDevice, offset);
461
462		/* Test the read-only bits. */
463		if ((val & read_mask) != read_val) {
464	                ret = 0;
465			LM_RegWr(pDevice, offset, save_val, FALSE);
466			break;
467		}
468
469		/* Test the read/write bits. */
470		if ((val & write_mask) != write_mask) {
471	                ret = 0;
472			LM_RegWr(pDevice, offset, save_val, FALSE);
473			break;
474		}
475
476		LM_RegWr(pDevice, offset, save_val, FALSE);
477	}
478
479	return ret;
480}
481
482
483/* Returns 1 on success, 0 on failure */
484int
485b57_do_memory_test(LM_DEVICE_BLOCK *pDevice, LM_UINT32 start, LM_UINT32 size)
486{
487	const LM_UINT32 test_pattern[] = { 0x00000000, 0xffffffff, 0x55555555,
488		0xaaaaaaaa , 0xaa55aa55, 0x55aa55aa };
489	LM_UINT32 offset;
490	int i;
491
492	for (i = 0; i < sizeof(test_pattern)/sizeof(LM_UINT32); i++) {
493		for (offset = 0; offset < size; offset += 4) {
494
495			LM_MemWrInd(pDevice, start + offset, test_pattern[i]);
496
497			if (LM_MemRdInd(pDevice, start + offset) !=
498				test_pattern[i]) {
499				return 0;
500			}
501		}
502	}
503	return 1;
504}
505
506/* Returns 1 on success, 0 on failure */
507int
508b57_test_memory(UM_DEVICE_BLOCK *pUmDevice)
509{
510	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
511	int ret = 0;
512	int i;
513	mem_entry_t *mem_tbl;
514
515	static mem_entry_t mem_tbl_570x[] = {
516		{ 0x00000000, 0x01000},
517		{ 0x00002000, 0x1c000},
518		{ 0xffffffff, 0x00000}
519	};
520	static mem_entry_t mem_tbl_5705[] = {
521		{ 0x00000100, 0x0000c},
522		{ 0x00000200, 0x00008},
523		{ 0x00000b50, 0x00400},
524		{ 0x00004000, 0x00800},
525		{ 0x00006000, 0x01000},
526		{ 0x00008000, 0x02000},
527		{ 0x00010000, 0x0e000},
528		{ 0xffffffff, 0x00000}
529	};
530
531    if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId)){
532		mem_tbl = mem_tbl_5705;
533	}
534	else {
535		mem_tbl = mem_tbl_570x;
536	}
537	for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
538		if ((ret = b57_do_memory_test(pDevice, mem_tbl[i].offset,
539			mem_tbl[i].len)) == 0) {
540			return ret;
541		}
542	}
543
544	return ret;
545}
546
547#define EEPROM_SIZE 0x100
548
549/* Returns 1 on success, 0 on failure */
550int
551b57_test_nvram(UM_DEVICE_BLOCK *pUmDevice)
552{
553	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
554	LM_UINT32 buf[EEPROM_SIZE/4];
555	LM_UINT8 *pdata = (LM_UINT8 *) buf;
556	int i;
557	LM_UINT32 magic, csum;
558
559	for (i = 0; i < EEPROM_SIZE; i += 4) {
560		if (LM_NvramRead(pDevice, i, (LM_UINT32 *) (pdata + i)) !=
561			LM_STATUS_SUCCESS) {
562			break;
563		}
564	}
565	if (i < EEPROM_SIZE) {
566		return 0;
567	}
568
569        magic = MM_SWAP_BE32(buf[0]);
570	if (magic != 0x669955aa) {
571		return 0;
572	}
573
574	csum = ComputeCrc32(pdata, 16);
575	if(csum != MM_SWAP_LE32(buf[0x10/4])) {
576		return 0;
577	}
578
579	csum = ComputeCrc32(&pdata[0x74], 136);
580	if (csum != MM_SWAP_LE32(buf[0xfc/4])) {
581		return 0;
582	}
583
584	return 1;
585}
586
587/* Returns 1 on success, 0 on failure */
588int
589b57_test_link(UM_DEVICE_BLOCK *pUmDevice)
590{
591	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
592	LM_UINT32 phy_reg;
593
594	if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
595		if (REG_RD(pDevice, MacCtrl.Status) &
596			(MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED)) {
597			return 1;
598		}
599		return 0;
600	}
601	LM_ReadPhy(pDevice, PHY_STATUS_REG, &phy_reg);
602	LM_ReadPhy(pDevice, PHY_STATUS_REG, &phy_reg);
603	if (phy_reg & PHY_STATUS_LINK_PASS)
604		return 1;
605	return 0;
606}
607
608#endif
609
610#if defined(ETHTOOL_TEST) || defined(NICE_SUPPORT)
611
612#if (LINUX_VERSION_CODE < 0x020605)
613#define pci_dma_sync_single_for_cpu pci_dma_sync_single
614#endif
615
616/* Returns 1 on success, 0 on failure */
617int
618b57_test_loopback(UM_DEVICE_BLOCK *pUmDevice, int testtype, int linespeed)
619{
620	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
621	struct sk_buff *skb, *rx_skb;
622	unsigned char *packet;
623	dma_addr_t map;
624	LM_UINT32 value32;
625	LM_UINT32 send_idx, rx_start_idx, rx_idx;
626	int num_pkts, pkt_size, i, ret;
627	LM_PACKET *pPacket;
628	UM_PACKET *pUmPacket;
629	T3_SND_BD *pSendBd;
630	T3_RCV_BD *pRcvBd;
631
632	ret = 0;
633	if (!pUmDevice->opened)
634		return ret;
635	LM_ResetAdapter(pDevice);
636	LM_HaltCpu(pDevice,T3_RX_CPU_ID | T3_TX_CPU_ID);
637	switch (testtype) {
638		case NICE_LOOPBACK_TESTTYPE_MAC:
639			LM_EnableMacLoopBack(pDevice);
640			break;
641		case NICE_LOOPBACK_TESTTYPE_PHY:
642			LM_EnablePhyLoopBack(pDevice);
643			break;
644		case NICE_LOOPBACK_TESTTYPE_EXT:
645			LM_EnableExtLoopBack(pDevice, linespeed);
646
647			/* Wait 4 seconds for link to come up. */
648			for (i = 0; i < 4; i++) {
649				LM_ReadPhy(pDevice, PHY_STATUS_REG, &value32);
650				LM_ReadPhy(pDevice, PHY_STATUS_REG, &value32);
651				if (value32 & PHY_STATUS_LINK_PASS) {
652					LM_SetupPhy(pDevice);
653					break;
654				}
655				MM_Sleep(pDevice,1000);
656			}
657			if (!(value32 & PHY_STATUS_LINK_PASS))
658				return ret;
659	}
660	pkt_size = 1514;
661	skb = dev_alloc_skb(pkt_size);
662	packet = skb_put(skb, pkt_size);
663	memcpy(packet, pDevice->NodeAddress, 6);
664	memset(packet + 6, 0x0, 8);
665
666	for (i = 14; i < pkt_size; i++)
667		packet[i] = (unsigned char) (i & 0xff);
668
669	map = pci_map_single(pUmDevice->pdev, skb->data, pkt_size,
670		PCI_DMA_TODEVICE);
671
672	REG_WR(pDevice, HostCoalesce.Mode,
673		pDevice->CoalesceMode | HOST_COALESCE_ENABLE |
674			HOST_COALESCE_NOW);
675	MM_Wait(10);
676	rx_start_idx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
677
678	send_idx = 0;
679	num_pkts = 0;
680	pSendBd = &pDevice->pSendBdVirt[send_idx];
681	if (pDevice->Flags & NIC_SEND_BD_FLAG) {
682		T3_64BIT_HOST_ADDR HostAddr;
683
684		MM_SetT3Addr(&HostAddr, map);
685		MM_MEMWRITEL(&(pSendBd->HostAddr.High), HostAddr.High);
686		MM_MEMWRITEL(&(pSendBd->HostAddr.Low), HostAddr.Low);
687		MM_MEMWRITEL(&(pSendBd->u1.Len_Flags),
688		             (pkt_size << 16) | SND_BD_FLAG_END);
689		send_idx++;
690		num_pkts++;
691		MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, send_idx);
692		if (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
693			MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low,
694				send_idx);
695		}
696		MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
697	}
698	else {
699		MM_SetT3Addr(&pSendBd->HostAddr, map);
700                pSendBd->u1.Len_Flags = (pkt_size << 16) | SND_BD_FLAG_END;
701		MM_WMB();
702		send_idx++;
703		num_pkts++;
704	        MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, send_idx);
705		if (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
706			MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low,
707				send_idx);
708		}
709	        MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
710	}
711
712	MM_Wait(100);
713
714	REG_WR(pDevice, HostCoalesce.Mode,
715		pDevice->CoalesceMode | HOST_COALESCE_ENABLE |
716			HOST_COALESCE_NOW);
717
718	MM_Sleep(pDevice, 1000);
719
720	pci_unmap_single(pUmDevice->pdev, map, pkt_size, PCI_DMA_TODEVICE);
721	dev_kfree_skb_irq(skb);
722
723	if (pDevice->pStatusBlkVirt->Idx[0].SendConIdx != send_idx) {
724		goto loopback_test_done;
725	}
726
727	rx_idx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
728	if (rx_idx != rx_start_idx + num_pkts) {
729		goto loopback_test_done;
730	}
731
732	pRcvBd = &pDevice->pRcvRetBdVirt[rx_start_idx];
733	pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
734		MM_UINT_PTR(pRcvBd->Opaque));
735
736	pUmPacket = (UM_PACKET *) pPacket;
737
738	if (pRcvBd->ErrorFlag &&
739		pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
740		goto loopback_test_done;
741	}
742	if ((pRcvBd->Len - 4) != pkt_size) {
743		goto loopback_test_done;
744	}
745	rx_skb = pUmPacket->skbuff;
746
747	pci_dma_sync_single_for_cpu(pUmDevice->pdev,
748		pci_unmap_addr(pUmPacket, map[0]),
749		pPacket->u.Rx.RxBufferSize,
750		PCI_DMA_FROMDEVICE);
751
752	for (i = 14; i < pkt_size; i++) {
753		if (*(rx_skb->data + i) != (unsigned char) (i & 0xff)) {
754			goto loopback_test_done;
755		}
756	}
757	ret = 1;
758
759loopback_test_done:
760	switch (testtype) {
761		case NICE_LOOPBACK_TESTTYPE_MAC:
762			LM_DisableMacLoopBack(pDevice);
763			break;
764		case NICE_LOOPBACK_TESTTYPE_PHY:
765			LM_DisablePhyLoopBack(pDevice);
766			break;
767		case NICE_LOOPBACK_TESTTYPE_EXT:
768			LM_DisableExtLoopBack(pDevice);
769			break;
770	}
771	return ret;
772}
773#endif
774
775