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