diff options
author | Taku Izumi <izumi.taku@jp.fujitsu.com> | 2010-04-27 10:39:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-27 20:46:56 -0400 |
commit | c97ec42a7a35d214e0c715f77e2ccdfe8ac5bf7c (patch) | |
tree | d0594c2e461ccfa5654e6881e5032c89d2322fa1 /drivers/net/igb/igb_main.c | |
parent | 84f4ee902ad3ee964b7b3a13d5b7cf9c086e9916 (diff) |
igb: add registers etc. printout code just before resetting adapters
This patch adds registers (,tx/rx rings' status and so on) printout
code just before resetting adapters. This will be helpful for detecting
the root cause of adapters reset.
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb/igb_main.c')
-rw-r--r-- | drivers/net/igb/igb_main.c | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 9d042fe299ce..438737d58688 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -201,6 +201,336 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver"); | |||
201 | MODULE_LICENSE("GPL"); | 201 | MODULE_LICENSE("GPL"); |
202 | MODULE_VERSION(DRV_VERSION); | 202 | MODULE_VERSION(DRV_VERSION); |
203 | 203 | ||
204 | struct igb_reg_info { | ||
205 | u32 ofs; | ||
206 | char *name; | ||
207 | }; | ||
208 | |||
209 | static const struct igb_reg_info igb_reg_info_tbl[] = { | ||
210 | |||
211 | /* General Registers */ | ||
212 | {E1000_CTRL, "CTRL"}, | ||
213 | {E1000_STATUS, "STATUS"}, | ||
214 | {E1000_CTRL_EXT, "CTRL_EXT"}, | ||
215 | |||
216 | /* Interrupt Registers */ | ||
217 | {E1000_ICR, "ICR"}, | ||
218 | |||
219 | /* RX Registers */ | ||
220 | {E1000_RCTL, "RCTL"}, | ||
221 | {E1000_RDLEN(0), "RDLEN"}, | ||
222 | {E1000_RDH(0), "RDH"}, | ||
223 | {E1000_RDT(0), "RDT"}, | ||
224 | {E1000_RXDCTL(0), "RXDCTL"}, | ||
225 | {E1000_RDBAL(0), "RDBAL"}, | ||
226 | {E1000_RDBAH(0), "RDBAH"}, | ||
227 | |||
228 | /* TX Registers */ | ||
229 | {E1000_TCTL, "TCTL"}, | ||
230 | {E1000_TDBAL(0), "TDBAL"}, | ||
231 | {E1000_TDBAH(0), "TDBAH"}, | ||
232 | {E1000_TDLEN(0), "TDLEN"}, | ||
233 | {E1000_TDH(0), "TDH"}, | ||
234 | {E1000_TDT(0), "TDT"}, | ||
235 | {E1000_TXDCTL(0), "TXDCTL"}, | ||
236 | {E1000_TDFH, "TDFH"}, | ||
237 | {E1000_TDFT, "TDFT"}, | ||
238 | {E1000_TDFHS, "TDFHS"}, | ||
239 | {E1000_TDFPC, "TDFPC"}, | ||
240 | |||
241 | /* List Terminator */ | ||
242 | {} | ||
243 | }; | ||
244 | |||
245 | /* | ||
246 | * igb_regdump - register printout routine | ||
247 | */ | ||
248 | static void igb_regdump(struct e1000_hw *hw, struct igb_reg_info *reginfo) | ||
249 | { | ||
250 | int n = 0; | ||
251 | char rname[16]; | ||
252 | u32 regs[8]; | ||
253 | |||
254 | switch (reginfo->ofs) { | ||
255 | case E1000_RDLEN(0): | ||
256 | for (n = 0; n < 4; n++) | ||
257 | regs[n] = rd32(E1000_RDLEN(n)); | ||
258 | break; | ||
259 | case E1000_RDH(0): | ||
260 | for (n = 0; n < 4; n++) | ||
261 | regs[n] = rd32(E1000_RDH(n)); | ||
262 | break; | ||
263 | case E1000_RDT(0): | ||
264 | for (n = 0; n < 4; n++) | ||
265 | regs[n] = rd32(E1000_RDT(n)); | ||
266 | break; | ||
267 | case E1000_RXDCTL(0): | ||
268 | for (n = 0; n < 4; n++) | ||
269 | regs[n] = rd32(E1000_RXDCTL(n)); | ||
270 | break; | ||
271 | case E1000_RDBAL(0): | ||
272 | for (n = 0; n < 4; n++) | ||
273 | regs[n] = rd32(E1000_RDBAL(n)); | ||
274 | break; | ||
275 | case E1000_RDBAH(0): | ||
276 | for (n = 0; n < 4; n++) | ||
277 | regs[n] = rd32(E1000_RDBAH(n)); | ||
278 | break; | ||
279 | case E1000_TDBAL(0): | ||
280 | for (n = 0; n < 4; n++) | ||
281 | regs[n] = rd32(E1000_RDBAL(n)); | ||
282 | break; | ||
283 | case E1000_TDBAH(0): | ||
284 | for (n = 0; n < 4; n++) | ||
285 | regs[n] = rd32(E1000_TDBAH(n)); | ||
286 | break; | ||
287 | case E1000_TDLEN(0): | ||
288 | for (n = 0; n < 4; n++) | ||
289 | regs[n] = rd32(E1000_TDLEN(n)); | ||
290 | break; | ||
291 | case E1000_TDH(0): | ||
292 | for (n = 0; n < 4; n++) | ||
293 | regs[n] = rd32(E1000_TDH(n)); | ||
294 | break; | ||
295 | case E1000_TDT(0): | ||
296 | for (n = 0; n < 4; n++) | ||
297 | regs[n] = rd32(E1000_TDT(n)); | ||
298 | break; | ||
299 | case E1000_TXDCTL(0): | ||
300 | for (n = 0; n < 4; n++) | ||
301 | regs[n] = rd32(E1000_TXDCTL(n)); | ||
302 | break; | ||
303 | default: | ||
304 | printk(KERN_INFO "%-15s %08x\n", | ||
305 | reginfo->name, rd32(reginfo->ofs)); | ||
306 | return; | ||
307 | } | ||
308 | |||
309 | snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]"); | ||
310 | printk(KERN_INFO "%-15s ", rname); | ||
311 | for (n = 0; n < 4; n++) | ||
312 | printk(KERN_CONT "%08x ", regs[n]); | ||
313 | printk(KERN_CONT "\n"); | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * igb_dump - Print registers, tx-rings and rx-rings | ||
318 | */ | ||
319 | static void igb_dump(struct igb_adapter *adapter) | ||
320 | { | ||
321 | struct net_device *netdev = adapter->netdev; | ||
322 | struct e1000_hw *hw = &adapter->hw; | ||
323 | struct igb_reg_info *reginfo; | ||
324 | int n = 0; | ||
325 | struct igb_ring *tx_ring; | ||
326 | union e1000_adv_tx_desc *tx_desc; | ||
327 | struct my_u0 { u64 a; u64 b; } *u0; | ||
328 | struct igb_buffer *buffer_info; | ||
329 | struct igb_ring *rx_ring; | ||
330 | union e1000_adv_rx_desc *rx_desc; | ||
331 | u32 staterr; | ||
332 | int i = 0; | ||
333 | |||
334 | if (!netif_msg_hw(adapter)) | ||
335 | return; | ||
336 | |||
337 | /* Print netdevice Info */ | ||
338 | if (netdev) { | ||
339 | dev_info(&adapter->pdev->dev, "Net device Info\n"); | ||
340 | printk(KERN_INFO "Device Name state " | ||
341 | "trans_start last_rx\n"); | ||
342 | printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", | ||
343 | netdev->name, | ||
344 | netdev->state, | ||
345 | netdev->trans_start, | ||
346 | netdev->last_rx); | ||
347 | } | ||
348 | |||
349 | /* Print Registers */ | ||
350 | dev_info(&adapter->pdev->dev, "Register Dump\n"); | ||
351 | printk(KERN_INFO " Register Name Value\n"); | ||
352 | for (reginfo = (struct igb_reg_info *)igb_reg_info_tbl; | ||
353 | reginfo->name; reginfo++) { | ||
354 | igb_regdump(hw, reginfo); | ||
355 | } | ||
356 | |||
357 | /* Print TX Ring Summary */ | ||
358 | if (!netdev || !netif_running(netdev)) | ||
359 | goto exit; | ||
360 | |||
361 | dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); | ||
362 | printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ]" | ||
363 | " leng ntw timestamp\n"); | ||
364 | for (n = 0; n < adapter->num_tx_queues; n++) { | ||
365 | tx_ring = adapter->tx_ring[n]; | ||
366 | buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean]; | ||
367 | printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n", | ||
368 | n, tx_ring->next_to_use, tx_ring->next_to_clean, | ||
369 | (u64)buffer_info->dma, | ||
370 | buffer_info->length, | ||
371 | buffer_info->next_to_watch, | ||
372 | (u64)buffer_info->time_stamp); | ||
373 | } | ||
374 | |||
375 | /* Print TX Rings */ | ||
376 | if (!netif_msg_tx_done(adapter)) | ||
377 | goto rx_ring_summary; | ||
378 | |||
379 | dev_info(&adapter->pdev->dev, "TX Rings Dump\n"); | ||
380 | |||
381 | /* Transmit Descriptor Formats | ||
382 | * | ||
383 | * Advanced Transmit Descriptor | ||
384 | * +--------------------------------------------------------------+ | ||
385 | * 0 | Buffer Address [63:0] | | ||
386 | * +--------------------------------------------------------------+ | ||
387 | * 8 | PAYLEN | PORTS |CC|IDX | STA | DCMD |DTYP|MAC|RSV| DTALEN | | ||
388 | * +--------------------------------------------------------------+ | ||
389 | * 63 46 45 40 39 38 36 35 32 31 24 15 0 | ||
390 | */ | ||
391 | |||
392 | for (n = 0; n < adapter->num_tx_queues; n++) { | ||
393 | tx_ring = adapter->tx_ring[n]; | ||
394 | printk(KERN_INFO "------------------------------------\n"); | ||
395 | printk(KERN_INFO "TX QUEUE INDEX = %d\n", tx_ring->queue_index); | ||
396 | printk(KERN_INFO "------------------------------------\n"); | ||
397 | printk(KERN_INFO "T [desc] [address 63:0 ] " | ||
398 | "[PlPOCIStDDM Ln] [bi->dma ] " | ||
399 | "leng ntw timestamp bi->skb\n"); | ||
400 | |||
401 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { | ||
402 | tx_desc = E1000_TX_DESC_ADV(*tx_ring, i); | ||
403 | buffer_info = &tx_ring->buffer_info[i]; | ||
404 | u0 = (struct my_u0 *)tx_desc; | ||
405 | printk(KERN_INFO "T [0x%03X] %016llX %016llX %016llX" | ||
406 | " %04X %3X %016llX %p", i, | ||
407 | le64_to_cpu(u0->a), | ||
408 | le64_to_cpu(u0->b), | ||
409 | (u64)buffer_info->dma, | ||
410 | buffer_info->length, | ||
411 | buffer_info->next_to_watch, | ||
412 | (u64)buffer_info->time_stamp, | ||
413 | buffer_info->skb); | ||
414 | if (i == tx_ring->next_to_use && | ||
415 | i == tx_ring->next_to_clean) | ||
416 | printk(KERN_CONT " NTC/U\n"); | ||
417 | else if (i == tx_ring->next_to_use) | ||
418 | printk(KERN_CONT " NTU\n"); | ||
419 | else if (i == tx_ring->next_to_clean) | ||
420 | printk(KERN_CONT " NTC\n"); | ||
421 | else | ||
422 | printk(KERN_CONT "\n"); | ||
423 | |||
424 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | ||
425 | print_hex_dump(KERN_INFO, "", | ||
426 | DUMP_PREFIX_ADDRESS, | ||
427 | 16, 1, phys_to_virt(buffer_info->dma), | ||
428 | buffer_info->length, true); | ||
429 | } | ||
430 | } | ||
431 | |||
432 | /* Print RX Rings Summary */ | ||
433 | rx_ring_summary: | ||
434 | dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); | ||
435 | printk(KERN_INFO "Queue [NTU] [NTC]\n"); | ||
436 | for (n = 0; n < adapter->num_rx_queues; n++) { | ||
437 | rx_ring = adapter->rx_ring[n]; | ||
438 | printk(KERN_INFO " %5d %5X %5X\n", n, | ||
439 | rx_ring->next_to_use, rx_ring->next_to_clean); | ||
440 | } | ||
441 | |||
442 | /* Print RX Rings */ | ||
443 | if (!netif_msg_rx_status(adapter)) | ||
444 | goto exit; | ||
445 | |||
446 | dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); | ||
447 | |||
448 | /* Advanced Receive Descriptor (Read) Format | ||
449 | * 63 1 0 | ||
450 | * +-----------------------------------------------------+ | ||
451 | * 0 | Packet Buffer Address [63:1] |A0/NSE| | ||
452 | * +----------------------------------------------+------+ | ||
453 | * 8 | Header Buffer Address [63:1] | DD | | ||
454 | * +-----------------------------------------------------+ | ||
455 | * | ||
456 | * | ||
457 | * Advanced Receive Descriptor (Write-Back) Format | ||
458 | * | ||
459 | * 63 48 47 32 31 30 21 20 17 16 4 3 0 | ||
460 | * +------------------------------------------------------+ | ||
461 | * 0 | Packet IP |SPH| HDR_LEN | RSV|Packet| RSS | | ||
462 | * | Checksum Ident | | | | Type | Type | | ||
463 | * +------------------------------------------------------+ | ||
464 | * 8 | VLAN Tag | Length | Extended Error | Extended Status | | ||
465 | * +------------------------------------------------------+ | ||
466 | * 63 48 47 32 31 20 19 0 | ||
467 | */ | ||
468 | |||
469 | for (n = 0; n < adapter->num_rx_queues; n++) { | ||
470 | rx_ring = adapter->rx_ring[n]; | ||
471 | printk(KERN_INFO "------------------------------------\n"); | ||
472 | printk(KERN_INFO "RX QUEUE INDEX = %d\n", rx_ring->queue_index); | ||
473 | printk(KERN_INFO "------------------------------------\n"); | ||
474 | printk(KERN_INFO "R [desc] [ PktBuf A0] " | ||
475 | "[ HeadBuf DD] [bi->dma ] [bi->skb] " | ||
476 | "<-- Adv Rx Read format\n"); | ||
477 | printk(KERN_INFO "RWB[desc] [PcsmIpSHl PtRs] " | ||
478 | "[vl er S cks ln] ---------------- [bi->skb] " | ||
479 | "<-- Adv Rx Write-Back format\n"); | ||
480 | |||
481 | for (i = 0; i < rx_ring->count; i++) { | ||
482 | buffer_info = &rx_ring->buffer_info[i]; | ||
483 | rx_desc = E1000_RX_DESC_ADV(*rx_ring, i); | ||
484 | u0 = (struct my_u0 *)rx_desc; | ||
485 | staterr = le32_to_cpu(rx_desc->wb.upper.status_error); | ||
486 | if (staterr & E1000_RXD_STAT_DD) { | ||
487 | /* Descriptor Done */ | ||
488 | printk(KERN_INFO "RWB[0x%03X] %016llX " | ||
489 | "%016llX ---------------- %p", i, | ||
490 | le64_to_cpu(u0->a), | ||
491 | le64_to_cpu(u0->b), | ||
492 | buffer_info->skb); | ||
493 | } else { | ||
494 | printk(KERN_INFO "R [0x%03X] %016llX " | ||
495 | "%016llX %016llX %p", i, | ||
496 | le64_to_cpu(u0->a), | ||
497 | le64_to_cpu(u0->b), | ||
498 | (u64)buffer_info->dma, | ||
499 | buffer_info->skb); | ||
500 | |||
501 | if (netif_msg_pktdata(adapter)) { | ||
502 | print_hex_dump(KERN_INFO, "", | ||
503 | DUMP_PREFIX_ADDRESS, | ||
504 | 16, 1, | ||
505 | phys_to_virt(buffer_info->dma), | ||
506 | rx_ring->rx_buffer_len, true); | ||
507 | if (rx_ring->rx_buffer_len | ||
508 | < IGB_RXBUFFER_1024) | ||
509 | print_hex_dump(KERN_INFO, "", | ||
510 | DUMP_PREFIX_ADDRESS, | ||
511 | 16, 1, | ||
512 | phys_to_virt( | ||
513 | buffer_info->page_dma + | ||
514 | buffer_info->page_offset), | ||
515 | PAGE_SIZE/2, true); | ||
516 | } | ||
517 | } | ||
518 | |||
519 | if (i == rx_ring->next_to_use) | ||
520 | printk(KERN_CONT " NTU\n"); | ||
521 | else if (i == rx_ring->next_to_clean) | ||
522 | printk(KERN_CONT " NTC\n"); | ||
523 | else | ||
524 | printk(KERN_CONT "\n"); | ||
525 | |||
526 | } | ||
527 | } | ||
528 | |||
529 | exit: | ||
530 | return; | ||
531 | } | ||
532 | |||
533 | |||
204 | /** | 534 | /** |
205 | * igb_read_clock - read raw cycle counter (to be used by time counter) | 535 | * igb_read_clock - read raw cycle counter (to be used by time counter) |
206 | */ | 536 | */ |
@@ -3858,6 +4188,8 @@ static void igb_reset_task(struct work_struct *work) | |||
3858 | struct igb_adapter *adapter; | 4188 | struct igb_adapter *adapter; |
3859 | adapter = container_of(work, struct igb_adapter, reset_task); | 4189 | adapter = container_of(work, struct igb_adapter, reset_task); |
3860 | 4190 | ||
4191 | igb_dump(adapter); | ||
4192 | netdev_err(adapter->netdev, "Reset adapter\n"); | ||
3861 | igb_reinit_locked(adapter); | 4193 | igb_reinit_locked(adapter); |
3862 | } | 4194 | } |
3863 | 4195 | ||