1 /*
2  * Code to dump Marvell SysKonnect registers for skge and sky2 drivers.
3  *
4  * Copyright (C) 2004, 2006
5  *  Stephen Hemminger <shemminger@osdl.org>
6  */
7 
8 #include <stdio.h>
9 
10 #include "internal.h"
11 
dump_addr(int n,const u8 * a)12 static void dump_addr(int n, const u8 *a)
13 {
14 	int i;
15 
16 	printf("Addr %d            ", n);
17 	for (i = 0; i < 6; i++)
18 		printf("%02X%c", a[i], i == 5 ? '\n' : ' ');
19 }
20 
dump_timer(const char * name,const void * p)21 static void dump_timer(const char *name, const void *p)
22 {
23 	const u8 *a = p;
24 	const u32 *r = p;
25 
26 	printf("%s\n", name);
27 	printf("\tInit 0x%08X Value 0x%08X\n", r[0], r[1]);
28 	printf("\tTest 0x%02X       Control 0x%02X\n", a[8], a[9]);
29 }
30 
dump_queue(const char * name,const void * a,int rx)31 static void dump_queue(const char *name, const void *a, int rx)
32 {
33 	struct desc {
34 		u_int32_t		ctl;
35 		u_int32_t		next;
36 		u_int32_t		data_lo;
37 		u_int32_t		data_hi;
38 		u_int32_t		status;
39 		u_int32_t		timestamp;
40 		u_int16_t		csum2;
41 		u_int16_t		csum1;
42 		u_int16_t		csum2_start;
43 		u_int16_t		csum1_start;
44 		u_int32_t		addr_lo;
45 		u_int32_t		addr_hi;
46 		u_int32_t		count_lo;
47 		u_int32_t		count_hi;
48 		u_int32_t               byte_count;
49 		u_int32_t               csr;
50 		u_int32_t               flag;
51 	};
52 	const struct desc *d = a;
53 
54 	/* is reset bit set? */
55 	if (!(d->ctl & 2)) {
56 		printf("\n%s (disabled)\n", name);
57 		return;
58 	}
59 
60 	printf("\n%s\n", name);
61 	printf("---------------\n");
62 	printf("Descriptor Address       0x%08X%08X\n",
63 	       d->addr_hi, d->addr_lo);
64 	printf("Address Counter          0x%08X%08X\n",
65 	       d->count_hi, d->count_lo);
66 	printf("Current Byte Counter             %d\n", d->byte_count);
67 	printf("BMU Control/Status               0x%08X\n", d->csr);
68 	printf("Flag & FIFO Address              0x%08X\n", d->flag);
69 	printf("\n");
70 	printf("Control                          0x%08X\n", d->ctl);
71 	printf("Next                             0x%08X\n", d->next);
72 	printf("Data                     0x%08X%08X\n",
73 	       d->data_hi, d->data_lo);
74 	printf("Status                           0x%08X\n", d->status);
75 	printf("Timestamp                        0x%08X\n", d->timestamp);
76 	if (rx) {
77 		printf("Csum1      Offset %4d Position  %d\n",
78 		       d->csum1, d->csum1_start);
79 		printf("Csum2      Offset %4d Position  %d\n",
80 		       d->csum2, d->csum2_start);
81 	} else
82 		printf("Csum Start 0x%04X Pos %4d Write %d\n",
83 		       d->csum1, d->csum2_start, d->csum1_start);
84 
85 }
86 
dump_ram(const char * name,const void * p)87 static void dump_ram(const char *name, const void *p)
88 {
89 	const u32 *r = p;
90 
91 	if (!(r[10] & 2)) {
92 		printf("\n%s (disabled)\n", name);
93 		return;
94 	}
95 
96 	printf("\n%s\n", name);
97 	printf("---------------\n");
98 	printf("Start Address                    0x%08X\n", r[0]);
99 	printf("End Address                      0x%08X\n", r[1]);
100 	printf("Write Pointer                    0x%08X\n", r[2]);
101 	printf("Read Pointer                     0x%08X\n", r[3]);
102 
103 	if (*name == 'R') { /* Receive only */
104 		printf("Upper Threshold/Pause Packets    0x%08X\n", r[4]);
105 		printf("Lower Threshold/Pause Packets    0x%08X\n", r[5]);
106 		printf("Upper Threshold/High Priority    0x%08X\n", r[6]);
107 		printf("Lower Threshold/High Priority    0x%08X\n", r[7]);
108 	}
109 	printf("Packet Counter                   0x%08X\n", r[8]);
110 	printf("Level                            0x%08X\n", r[9]);
111 	printf("Control                          0x%08X\n", r[10]);
112 }
113 
dump_fifo(const char * name,const void * p)114 static void dump_fifo(const char *name, const void *p)
115 {
116 	const u32 *r = p;
117 
118 	printf("\n%s\n", name);
119 	printf("---------------\n");
120 	printf("End Address                      0x%08X\n", r[0]);
121 	printf("Write Pointer                    0x%08X\n", r[1]);
122 	printf("Read Pointer                     0x%08X\n", r[2]);
123 	printf("Packet Counter                   0x%08X\n", r[3]);
124 	printf("Level                            0x%08X\n", r[4]);
125 	printf("Control                          0x%08X\n", r[5]);
126 	printf("Control/Test                     0x%08X\n", r[6]);
127 	dump_timer("LED", r + 8);
128 }
129 
dump_gmac_fifo(const char * name,const void * p)130 static void dump_gmac_fifo(const char *name, const void *p)
131 {
132 	const u32 *r = p;
133 	int i;
134 	static const char *regs[] = {
135 		"End Address",
136 		"Almost Full Thresh",
137 		"Control/Test",
138 		"FIFO Flush Mask",
139 		"FIFO Flush Threshold",
140 		"Truncation Threshold",
141 		"Upper Pause Threshold",
142 		"Lower Pause Threshold",
143 		"VLAN Tag",
144 		"FIFO Write Pointer",
145 		"FIFO Write Level",
146 		"FIFO Read Pointer",
147 		"FIFO Read Level",
148 	};
149 
150 	printf("\n%s\n", name);
151 	for (i = 0; i < sizeof(regs)/sizeof(regs[0]); ++i)
152 		printf("%-32s 0x%08X\n", regs[i], r[i]);
153 
154 }
155 
dump_mac(const u8 * r)156 static void dump_mac(const u8 *r)
157 {
158 	u8 id;
159 
160 	printf("\nMAC Addresses\n");
161 	printf("---------------\n");
162 	dump_addr(1, r + 0x100);
163 	dump_addr(2, r + 0x108);
164 	dump_addr(3, r + 0x110);
165 	printf("\n");
166 
167 	printf("Connector type               0x%02X (%c)\n",
168 	       r[0x118], (char)r[0x118]);
169 	printf("PMD type                     0x%02X (%c)\n",
170 	       r[0x119], (char)r[0x119]);
171 	printf("PHY type                     0x%02X\n", r[0x11d]);
172 
173 	id = r[0x11b];
174 	printf("Chip Id                      0x%02X ", id);
175 
176 	switch (id) {
177 	case 0x0a:	printf("Genesis");	break;
178 	case 0xb0:	printf("Yukon");	break;
179 	case 0xb1:	printf("Yukon-Lite");	break;
180 	case 0xb2:	printf("Yukon-LP");	break;
181 	case 0xb3:	printf("Yukon-2 XL");	break;
182 	case 0xb5:	printf("Yukon Extreme"); break;
183 	case 0xb4:	printf("Yukon-2 EC Ultra");	break;
184 	case 0xb6:	printf("Yukon-2 EC");	break;
185  	case 0xb7:	printf("Yukon-2 FE");	break;
186 	case 0xb8:	printf("Yukon-2 FE Plus"); break;
187 	case 0xb9:	printf("Yukon Supreme"); break;
188 	case 0xba:	printf("Yukon Ultra 2"); break;
189 	case 0xbc:	printf("Yukon Optima"); break;
190 	default:	printf("(Unknown)");	break;
191 	}
192 
193 	printf(" (rev %d)\n", (r[0x11a] & 0xf0) >> 4);
194 
195 	printf("Ram Buffer                   0x%02X\n", r[0x11c]);
196 
197 }
198 
dump_gma(const char * name,const u8 * r)199 static void dump_gma(const char *name, const u8 *r)
200 {
201 	int i;
202 
203 	printf("%12s address: ", name);
204 	for (i = 0; i < 3; i++) {
205 		u16 a = *(u16 *)(r + i * 4);
206 		printf(" %02X %02X", a & 0xff, (a >> 8) & 0xff);
207 	}
208 	printf("\n");
209 }
210 
dump_gmac(const char * name,const u8 * data)211 static void dump_gmac(const char *name, const u8 *data)
212 {
213 	printf("\n%s\n", name);
214 
215 	printf("Status                       0x%04X\n", *(u16 *) data);
216 	printf("Control                      0x%04X\n", *(u16 *) (data + 4));
217 	printf("Transmit                     0x%04X\n", *(u16 *) (data + 8));
218 	printf("Receive                      0x%04X\n", *(u16 *) (data + 0xc));
219 	printf("Transmit flow control        0x%04X\n", *(u16 *) (data + 0x10));
220 	printf("Transmit parameter           0x%04X\n", *(u16 *) (data + 0x14));
221 	printf("Serial mode                  0x%04X\n", *(u16 *) (data + 0x18));
222 
223 	dump_gma("Source", data + 0x1c);
224 	dump_gma("Physical", data + 0x28);
225 }
226 
dump_pci(const u8 * cfg)227 static void dump_pci(const u8 *cfg)
228 {
229 	int i;
230 
231 	printf("\nPCI config\n----------\n");
232 	for(i = 0; i < 0x80; i++) {
233 		if (!(i & 15))
234 			printf("%02x:", i);
235 		printf(" %02x", cfg[i]);
236 		if ((i & 15) == 15)
237 			putchar('\n');
238 	}
239 	putchar('\n');
240 }
241 
dump_control(u8 * r)242 static void dump_control(u8 *r)
243 {
244 	printf("Control Registers\n");
245 	printf("-----------------\n");
246 
247 	printf("Register Access Port             0x%02X\n", *r);
248 	printf("LED Control/Status               0x%08X\n", *(u32 *) (r + 4));
249 
250 	printf("Interrupt Source                 0x%08X\n", *(u32 *) (r + 8));
251 	printf("Interrupt Mask                   0x%08X\n", *(u32 *) (r + 0xc));
252 	printf("Interrupt Hardware Error Source  0x%08X\n", *(u32 *) (r + 0x10));
253 	printf("Interrupt Hardware Error Mask    0x%08X\n", *(u32 *) (r + 0x14));
254 	printf("Interrupt Control                0x%08X\n", *(u32 *) (r + 0x2c));
255 	printf("Interrupt Moderation Mask        0x%08X\n", *(u32 *) (r + 0x14c));
256 	printf("Hardware Moderation Mask         0x%08X\n", *(u32 *) (r + 0x150));
257 	dump_timer("Moderation Timer", r + 0x140);
258 
259 	printf("General Purpose  I/O             0x%08X\n", *(u32 *) (r + 0x15c));
260 }
261 
skge_dump_regs(struct ethtool_drvinfo * info maybe_unused,struct ethtool_regs * regs)262 int skge_dump_regs(struct ethtool_drvinfo *info maybe_unused,
263 		   struct ethtool_regs *regs)
264 {
265 	const u32 *r = (const u32 *) regs->data;
266 	int dual = !(regs->data[0x11a] & 1);
267 
268 	dump_pci(regs->data + 0x380);
269 
270 	dump_control(regs->data);
271 
272 	printf("\nBus Management Unit\n");
273 	printf("-------------------\n");
274 	printf("CSR Receive Queue 1              0x%08X\n", r[24]);
275 	printf("CSR Sync Queue 1                 0x%08X\n", r[26]);
276 	printf("CSR Async Queue 1                0x%08X\n", r[27]);
277 	if (dual) {
278 		printf("CSR Receive Queue 2              0x%08X\n", r[25]);
279 		printf("CSR Async Queue 2                0x%08X\n", r[29]);
280 		printf("CSR Sync Queue 2                 0x%08X\n", r[28]);
281 	}
282 
283 	dump_mac(regs->data);
284 	dump_gmac("GMAC 1", regs->data + 0x2800);
285 
286 	dump_timer("Timer", regs->data + 0x130);
287 	dump_timer("Blink Source", regs->data +0x170);
288 
289 	dump_queue("Receive Queue 1", regs->data +0x400, 1);
290 	dump_queue("Sync Transmit Queue 1", regs->data +0x600, 0);
291 	dump_queue("Async Transmit Queue 1", regs->data +0x680, 0);
292 
293 	dump_ram("Receive RAMbuffer 1", regs->data+0x800);
294 	dump_ram("Sync Transmit RAMbuffer 1", regs->data+0xa00);
295 	dump_ram("Async Transmit RAMbuffer 1", regs->data+0xa80);
296 
297 	dump_fifo("Receive MAC FIFO 1", regs->data+0xc00);
298 	dump_fifo("Transmit MAC FIFO 1", regs->data+0xd00);
299 	if (dual) {
300 		dump_gmac("GMAC 1", regs->data + 0x2800);
301 
302 		dump_queue("Receive Queue 2", regs->data +0x480, 1);
303 		dump_queue("Async Transmit Queue 2", regs->data +0x780, 0);
304 		dump_queue("Sync Transmit Queue 2", regs->data +0x700, 0);
305 
306 		dump_ram("Receive RAMbuffer 2", regs->data+0x880);
307 		dump_ram("Sync Transmit RAMbuffer 2", regs->data+0xb00);
308 		dump_ram("Async Transmit RAMbuffer 21", regs->data+0xb80);
309 
310 		dump_fifo("Receive MAC FIFO 2", regs->data+0xc80);
311 		dump_fifo("Transmit MAC FIFO 2", regs->data+0xd80);
312 	}
313 
314 	dump_timer("Descriptor Poll", regs->data+0xe00);
315 	return 0;
316 
317 }
318 
dump_queue2(const char * name,void * a,int rx)319 static void dump_queue2(const char *name, void *a, int rx)
320 {
321 	struct sky2_queue {
322 		u16	buf_control;
323 		u16	byte_count;
324 		u32	rss;
325 		u32	addr_lo, addr_hi;
326 		u32	status;
327 		u32	timestamp;
328 		u16	csum1, csum2;
329 		u16	csum1_start, csum2_start;
330 		u16	length;
331 		u16	vlan;
332 		u16	rsvd1;
333 		u16	done;
334 		u32	req_lo, req_hi;
335 		u16	rsvd2;
336 		u16	req_count;
337 		u32	csr;
338 	} *d = a;
339 
340 	printf("\n%s\n", name);
341 	printf("---------------\n");
342 
343 	printf("Buffer control                   0x%04X\n", d->buf_control);
344 
345 	printf("Byte Counter                     %d\n", d->byte_count);
346 	printf("Descriptor Address               0x%08X%08X\n",
347 	       d->addr_hi, d->addr_lo);
348 	printf("Status                           0x%08X\n", d->status);
349 	printf("Timestamp                        0x%08X\n", d->timestamp);
350 	printf("BMU Control/Status               0x%08X\n", d->csr);
351 	printf("Done                             0x%04X\n", d->done);
352 	printf("Request                          0x%08X%08X\n",
353 	       d->req_hi, d->req_lo);
354 	if (rx) {
355 		printf("Csum1      Offset %4d Position  %d\n",
356 		       d->csum1, d->csum1_start);
357 		printf("Csum2      Offset %4d Position  %d\n",
358 		       d->csum2, d->csum2_start);
359 	} else
360 		printf("Csum Start 0x%04X Pos %4d Write %d\n",
361 		       d->csum1, d->csum2_start, d->csum1_start);
362 }
363 
dump_prefetch(const char * name,const void * r)364 static void dump_prefetch(const char *name, const void *r)
365 {
366 	const u32 *reg = r;
367 
368 	printf("\n%s Prefetch\n", name);
369 	printf("Control               0x%08X\n", reg[0]);
370 	printf("Last Index            %u\n", reg[1]);
371 	printf("Start Address         0x%08x%08x\n", reg[3], reg[2]);
372 	if (*name == 'S') { /* Status unit */
373 		printf("TX1 report            %u\n", reg[4]);
374 		printf("TX2 report            %u\n", reg[5]);
375 		printf("TX threshold          %u\n", reg[6]);
376 		printf("Put Index             %u\n", reg[7]);
377 	} else {
378 		printf("Get Index             %u\n", reg[4]);
379 		printf("Put Index             %u\n", reg[5]);
380 	}
381 }
382 
sky2_dump_regs(struct ethtool_drvinfo * info maybe_unused,struct ethtool_regs * regs)383 int sky2_dump_regs(struct ethtool_drvinfo *info maybe_unused,
384 		   struct ethtool_regs *regs)
385 {
386 	const u16 *r16 = (const u16 *) regs->data;
387 	const u32 *r32 = (const u32 *) regs->data;
388 	int dual;
389 
390 	dump_pci(regs->data + 0x1c00);
391 
392 	dump_control(regs->data);
393 
394 	printf("\nBus Management Unit\n");
395 	printf("-------------------\n");
396 	printf("CSR Receive Queue 1              0x%08X\n", r32[24]);
397 	printf("CSR Sync Queue 1                 0x%08X\n", r32[26]);
398 	printf("CSR Async Queue 1                0x%08X\n", r32[27]);
399 
400 	dual = (regs->data[0x11e] & 2) != 0;
401 	if (dual) {
402 		printf("CSR Receive Queue 2              0x%08X\n", r32[25]);
403 		printf("CSR Async Queue 2                0x%08X\n", r32[29]);
404 		printf("CSR Sync Queue 2                 0x%08X\n", r32[28]);
405 	}
406 
407 	dump_mac(regs->data);
408 
409 	dump_prefetch("Status", regs->data + 0xe80);
410 	dump_prefetch("Receive 1", regs->data + 0x450);
411 	dump_prefetch("Transmit 1", regs->data + 0x450 + 0x280);
412 
413 	if (dual) {
414 		dump_prefetch("Receive 2", regs->data + 0x450 + 0x80);
415 		dump_prefetch("Transmit 2", regs->data + 0x450 + 0x380);
416 	}
417 
418 	printf("\nStatus FIFO\n");
419   	printf("\tWrite Pointer            0x%02X\n", regs->data[0xea0]);
420   	printf("\tRead Pointer             0x%02X\n", regs->data[0xea4]);
421   	printf("\tLevel                    0x%02X\n", regs->data[0xea8]);
422   	printf("\tWatermark                0x%02X\n", regs->data[0xeac]);
423   	printf("\tISR Watermark            0x%02X\n", regs->data[0xead]);
424 
425 	dump_timer("Status level", regs->data + 0xeb0);
426 	dump_timer("TX status", regs->data + 0xec0);
427 	dump_timer("ISR", regs->data + 0xed0);
428 
429 	printf("\nGMAC control             0x%04X\n", r32[0xf00 >> 2]);
430 	printf("GPHY control             0x%04X\n", r32[0xf04 >> 2]);
431 	printf("LINK control             0x%02hX\n", r16[0xf10 >> 1]);
432 
433 	dump_gmac("GMAC 1", regs->data + 0x2800);
434 	dump_gmac_fifo("Rx GMAC 1", regs->data + 0xc40);
435 	dump_gmac_fifo("Tx GMAC 1", regs->data + 0xd40);
436 
437 	dump_queue2("Receive Queue 1", regs->data +0x400, 1);
438 	dump_queue("Sync Transmit Queue 1", regs->data +0x600, 0);
439 	dump_queue2("Async Transmit Queue 1", regs->data +0x680, 0);
440 
441 	dump_ram("Receive RAMbuffer 1", regs->data+0x800);
442 	dump_ram("Sync Transmit RAMbuffer 1", regs->data+0xa00);
443 	dump_ram("Async Transmit RAMbuffer 1", regs->data+0xa80);
444 
445 	if (dual) {
446 		dump_ram("Receive RAMbuffer 2", regs->data+0x880);
447 		dump_ram("Sync Transmit RAMbuffer 2", regs->data+0xb00);
448 		dump_ram("Async Transmit RAMbuffer 21", regs->data+0xb80);
449 		dump_gmac("GMAC 2", regs->data + 0x3800);
450 		dump_gmac_fifo("Rx GMAC 2", regs->data + 0xc40 + 128);
451 		dump_gmac_fifo("Tx GMAC 2", regs->data + 0xd40 + 128);
452 	}
453 
454 	return 0;
455 }
456