diff options
author | Tushar Dave <tushar.n.dave@intel.com> | 2012-01-27 04:00:46 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-02-07 07:01:46 -0500 |
commit | b04e36bac5075ceeacf11b639fbf0cb69aa68996 (patch) | |
tree | fb42cc78c07a58628a7e485d24eff440fed499ac | |
parent | ab50a2a430693b0961dc7b7d9fe2a4bd77d11ea6 (diff) |
e1000: Adding e1000_dump function
When TX hang occurs e1000_dump prints TX ring, RX ring and Device registers.
Signed-off-by: Tushar Dave <tushar.n.dave@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_hw.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_main.c | 224 |
3 files changed, 235 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 1e1596990b5c..2b6cd02bfba0 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h | |||
@@ -254,6 +254,7 @@ struct e1000_adapter { | |||
254 | atomic_t tx_fifo_stall; | 254 | atomic_t tx_fifo_stall; |
255 | bool pcix_82544; | 255 | bool pcix_82544; |
256 | bool detect_tx_hung; | 256 | bool detect_tx_hung; |
257 | bool dump_buffers; | ||
257 | 258 | ||
258 | /* RX */ | 259 | /* RX */ |
259 | bool (*clean_rx)(struct e1000_adapter *adapter, | 260 | bool (*clean_rx)(struct e1000_adapter *adapter, |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.h b/drivers/net/ethernet/intel/e1000/e1000_hw.h index f6c4d7e2560c..11578c8978db 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_hw.h +++ b/drivers/net/ethernet/intel/e1000/e1000_hw.h | |||
@@ -895,6 +895,11 @@ struct e1000_ffvt_entry { | |||
895 | #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ | 895 | #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ |
896 | #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ | 896 | #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ |
897 | #define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ | 897 | #define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ |
898 | #define E1000_RDFH 0x02410 /* RX Data FIFO Head - RW */ | ||
899 | #define E1000_RDFT 0x02418 /* RX Data FIFO Tail - RW */ | ||
900 | #define E1000_RDFHS 0x02420 /* RX Data FIFO Head Saved - RW */ | ||
901 | #define E1000_RDFTS 0x02428 /* RX Data FIFO Tail Saved - RW */ | ||
902 | #define E1000_RDFPC 0x02430 /* RX Data FIFO Packet Count - RW */ | ||
898 | #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ | 903 | #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ |
899 | #define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ | 904 | #define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ |
900 | #define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ | 905 | #define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ |
@@ -1074,6 +1079,11 @@ struct e1000_ffvt_entry { | |||
1074 | #define E1000_82542_IMC E1000_IMC | 1079 | #define E1000_82542_IMC E1000_IMC |
1075 | #define E1000_82542_RCTL E1000_RCTL | 1080 | #define E1000_82542_RCTL E1000_RCTL |
1076 | #define E1000_82542_RDTR 0x00108 | 1081 | #define E1000_82542_RDTR 0x00108 |
1082 | #define E1000_82542_RDFH E1000_RDFH | ||
1083 | #define E1000_82542_RDFT E1000_RDFT | ||
1084 | #define E1000_82542_RDFHS E1000_RDFHS | ||
1085 | #define E1000_82542_RDFTS E1000_RDFTS | ||
1086 | #define E1000_82542_RDFPC E1000_RDFPC | ||
1077 | #define E1000_82542_RDBAL 0x00110 | 1087 | #define E1000_82542_RDBAL 0x00110 |
1078 | #define E1000_82542_RDBAH 0x00114 | 1088 | #define E1000_82542_RDBAH 0x00114 |
1079 | #define E1000_82542_RDLEN 0x00118 | 1089 | #define E1000_82542_RDLEN 0x00118 |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 363fd395c75b..1f86a70b88af 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
@@ -3239,6 +3239,228 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
3239 | return NETDEV_TX_OK; | 3239 | return NETDEV_TX_OK; |
3240 | } | 3240 | } |
3241 | 3241 | ||
3242 | #define NUM_REGS 38 /* 1 based count */ | ||
3243 | static void e1000_regdump(struct e1000_adapter *adapter) | ||
3244 | { | ||
3245 | struct e1000_hw *hw = &adapter->hw; | ||
3246 | u32 regs[NUM_REGS]; | ||
3247 | u32 *regs_buff = regs; | ||
3248 | int i = 0; | ||
3249 | |||
3250 | char *reg_name[] = { | ||
3251 | "CTRL", "STATUS", | ||
3252 | "RCTL", "RDLEN", "RDH", "RDT", "RDTR", | ||
3253 | "TCTL", "TDBAL", "TDBAH", "TDLEN", "TDH", "TDT", | ||
3254 | "TIDV", "TXDCTL", "TADV", "TARC0", | ||
3255 | "TDBAL1", "TDBAH1", "TDLEN1", "TDH1", "TDT1", | ||
3256 | "TXDCTL1", "TARC1", | ||
3257 | "CTRL_EXT", "ERT", "RDBAL", "RDBAH", | ||
3258 | "TDFH", "TDFT", "TDFHS", "TDFTS", "TDFPC", | ||
3259 | "RDFH", "RDFT", "RDFHS", "RDFTS", "RDFPC" | ||
3260 | }; | ||
3261 | |||
3262 | regs_buff[0] = er32(CTRL); | ||
3263 | regs_buff[1] = er32(STATUS); | ||
3264 | |||
3265 | regs_buff[2] = er32(RCTL); | ||
3266 | regs_buff[3] = er32(RDLEN); | ||
3267 | regs_buff[4] = er32(RDH); | ||
3268 | regs_buff[5] = er32(RDT); | ||
3269 | regs_buff[6] = er32(RDTR); | ||
3270 | |||
3271 | regs_buff[7] = er32(TCTL); | ||
3272 | regs_buff[8] = er32(TDBAL); | ||
3273 | regs_buff[9] = er32(TDBAH); | ||
3274 | regs_buff[10] = er32(TDLEN); | ||
3275 | regs_buff[11] = er32(TDH); | ||
3276 | regs_buff[12] = er32(TDT); | ||
3277 | regs_buff[13] = er32(TIDV); | ||
3278 | regs_buff[14] = er32(TXDCTL); | ||
3279 | regs_buff[15] = er32(TADV); | ||
3280 | regs_buff[16] = er32(TARC0); | ||
3281 | |||
3282 | regs_buff[17] = er32(TDBAL1); | ||
3283 | regs_buff[18] = er32(TDBAH1); | ||
3284 | regs_buff[19] = er32(TDLEN1); | ||
3285 | regs_buff[20] = er32(TDH1); | ||
3286 | regs_buff[21] = er32(TDT1); | ||
3287 | regs_buff[22] = er32(TXDCTL1); | ||
3288 | regs_buff[23] = er32(TARC1); | ||
3289 | regs_buff[24] = er32(CTRL_EXT); | ||
3290 | regs_buff[25] = er32(ERT); | ||
3291 | regs_buff[26] = er32(RDBAL0); | ||
3292 | regs_buff[27] = er32(RDBAH0); | ||
3293 | regs_buff[28] = er32(TDFH); | ||
3294 | regs_buff[29] = er32(TDFT); | ||
3295 | regs_buff[30] = er32(TDFHS); | ||
3296 | regs_buff[31] = er32(TDFTS); | ||
3297 | regs_buff[32] = er32(TDFPC); | ||
3298 | regs_buff[33] = er32(RDFH); | ||
3299 | regs_buff[34] = er32(RDFT); | ||
3300 | regs_buff[35] = er32(RDFHS); | ||
3301 | regs_buff[36] = er32(RDFTS); | ||
3302 | regs_buff[37] = er32(RDFPC); | ||
3303 | |||
3304 | pr_info("Register dump\n"); | ||
3305 | for (i = 0; i < NUM_REGS; i++) { | ||
3306 | printk(KERN_INFO "%-15s %08x\n", | ||
3307 | reg_name[i], regs_buff[i]); | ||
3308 | } | ||
3309 | } | ||
3310 | |||
3311 | /* | ||
3312 | * e1000_dump: Print registers, tx ring and rx ring | ||
3313 | */ | ||
3314 | static void e1000_dump(struct e1000_adapter *adapter) | ||
3315 | { | ||
3316 | /* this code doesn't handle multiple rings */ | ||
3317 | struct e1000_tx_ring *tx_ring = adapter->tx_ring; | ||
3318 | struct e1000_rx_ring *rx_ring = adapter->rx_ring; | ||
3319 | int i; | ||
3320 | |||
3321 | if (!netif_msg_hw(adapter)) | ||
3322 | return; | ||
3323 | |||
3324 | /* Print Registers */ | ||
3325 | e1000_regdump(adapter); | ||
3326 | |||
3327 | /* | ||
3328 | * transmit dump | ||
3329 | */ | ||
3330 | pr_info("TX Desc ring0 dump\n"); | ||
3331 | |||
3332 | /* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended) | ||
3333 | * | ||
3334 | * Legacy Transmit Descriptor | ||
3335 | * +--------------------------------------------------------------+ | ||
3336 | * 0 | Buffer Address [63:0] (Reserved on Write Back) | | ||
3337 | * +--------------------------------------------------------------+ | ||
3338 | * 8 | Special | CSS | Status | CMD | CSO | Length | | ||
3339 | * +--------------------------------------------------------------+ | ||
3340 | * 63 48 47 36 35 32 31 24 23 16 15 0 | ||
3341 | * | ||
3342 | * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload | ||
3343 | * 63 48 47 40 39 32 31 16 15 8 7 0 | ||
3344 | * +----------------------------------------------------------------+ | ||
3345 | * 0 | TUCSE | TUCS0 | TUCSS | IPCSE | IPCS0 | IPCSS | | ||
3346 | * +----------------------------------------------------------------+ | ||
3347 | * 8 | MSS | HDRLEN | RSV | STA | TUCMD | DTYP | PAYLEN | | ||
3348 | * +----------------------------------------------------------------+ | ||
3349 | * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 | ||
3350 | * | ||
3351 | * Extended Data Descriptor (DTYP=0x1) | ||
3352 | * +----------------------------------------------------------------+ | ||
3353 | * 0 | Buffer Address [63:0] | | ||
3354 | * +----------------------------------------------------------------+ | ||
3355 | * 8 | VLAN tag | POPTS | Rsvd | Status | Command | DTYP | DTALEN | | ||
3356 | * +----------------------------------------------------------------+ | ||
3357 | * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 | ||
3358 | */ | ||
3359 | printk(KERN_INFO "Tc[desc] [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma ]" | ||
3360 | " leng ntw timestmp bi->skb\n"); | ||
3361 | printk(KERN_INFO "Td[desc] [address 63:0 ] [VlaPoRSCm1Dlen] [bi->dma ]" | ||
3362 | " leng ntw timestmp bi->skb\n"); | ||
3363 | |||
3364 | if (!netif_msg_tx_done(adapter)) | ||
3365 | goto rx_ring_summary; | ||
3366 | |||
3367 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { | ||
3368 | struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i); | ||
3369 | struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i]; | ||
3370 | struct my_u { u64 a; u64 b; }; | ||
3371 | struct my_u *u = (struct my_u *)tx_desc; | ||
3372 | printk(KERN_INFO "T%c[0x%03X] %016llX %016llX %016llX %04X %3X " | ||
3373 | "%016llX %p", | ||
3374 | ((le64_to_cpu(u->b) & (1<<20)) ? 'd' : 'c'), i, | ||
3375 | le64_to_cpu(u->a), le64_to_cpu(u->b), | ||
3376 | (u64)buffer_info->dma, buffer_info->length, | ||
3377 | buffer_info->next_to_watch, (u64)buffer_info->time_stamp, | ||
3378 | buffer_info->skb); | ||
3379 | if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean) | ||
3380 | printk(KERN_CONT" NTC/U\n"); | ||
3381 | else if (i == tx_ring->next_to_use) | ||
3382 | printk(KERN_CONT " NTU\n"); | ||
3383 | else if (i == tx_ring->next_to_clean) | ||
3384 | printk(KERN_CONT " NTC\n"); | ||
3385 | else | ||
3386 | printk(KERN_CONT "\n"); | ||
3387 | |||
3388 | |||
3389 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | ||
3390 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, | ||
3391 | 16, 1, phys_to_virt(buffer_info->dma), | ||
3392 | buffer_info->length, true); | ||
3393 | } | ||
3394 | |||
3395 | rx_ring_summary: | ||
3396 | /* | ||
3397 | * receive dump | ||
3398 | */ | ||
3399 | pr_info("\nRX Desc ring dump\n"); | ||
3400 | |||
3401 | /* Legacy Receive Descriptor Format | ||
3402 | * | ||
3403 | * +-----------------------------------------------------+ | ||
3404 | * | Buffer Address [63:0] | | ||
3405 | * +-----------------------------------------------------+ | ||
3406 | * | VLAN Tag | Errors | Status 0 | Packet csum | Length | | ||
3407 | * +-----------------------------------------------------+ | ||
3408 | * 63 48 47 40 39 32 31 16 15 0 | ||
3409 | */ | ||
3410 | printk(KERN_INFO "R[desc] [address 63:0 ] [vl er S cks ln] " | ||
3411 | "[bi->dma ] [bi->skb]\n"); | ||
3412 | |||
3413 | if (!netif_msg_rx_status(adapter)) | ||
3414 | goto exit; | ||
3415 | |||
3416 | for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) { | ||
3417 | struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i); | ||
3418 | struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i]; | ||
3419 | struct my_u { u64 a; u64 b; }; | ||
3420 | struct my_u *u = (struct my_u *)rx_desc; | ||
3421 | printk(KERN_INFO "R[0x%03X] %016llX %016llX %016llX %p", | ||
3422 | i, le64_to_cpu(u->a), le64_to_cpu(u->b), | ||
3423 | (u64)buffer_info->dma, buffer_info->skb); | ||
3424 | if (i == rx_ring->next_to_use) | ||
3425 | printk(KERN_CONT " NTU\n"); | ||
3426 | else if (i == rx_ring->next_to_clean) | ||
3427 | printk(KERN_CONT " NTC\n"); | ||
3428 | else | ||
3429 | printk(KERN_CONT "\n"); | ||
3430 | |||
3431 | if (netif_msg_pktdata(adapter)) | ||
3432 | print_hex_dump(KERN_INFO, "", | ||
3433 | DUMP_PREFIX_ADDRESS, 16, 1, | ||
3434 | phys_to_virt(buffer_info->dma), | ||
3435 | buffer_info->length, true); | ||
3436 | |||
3437 | } /* for */ | ||
3438 | |||
3439 | /* dump the descriptor caches */ | ||
3440 | /* rx */ | ||
3441 | printk(KERN_INFO "e1000: Rx descriptor cache in 64bit format\n"); | ||
3442 | for (i = 0x6000; i <= 0x63FF ; i += 0x10) { | ||
3443 | printk(KERN_INFO "R%04X: %08X|%08X %08X|%08X\n", | ||
3444 | i, | ||
3445 | readl(adapter->hw.hw_addr + i+4), | ||
3446 | readl(adapter->hw.hw_addr + i), | ||
3447 | readl(adapter->hw.hw_addr + i+12), | ||
3448 | readl(adapter->hw.hw_addr + i+8)); | ||
3449 | } | ||
3450 | /* tx */ | ||
3451 | printk(KERN_INFO "e1000: Tx descriptor cache in 64bit format\n"); | ||
3452 | for (i = 0x7000; i <= 0x73FF ; i += 0x10) { | ||
3453 | printk(KERN_INFO "T%04X: %08X|%08X %08X|%08X\n", | ||
3454 | i, | ||
3455 | readl(adapter->hw.hw_addr + i+4), | ||
3456 | readl(adapter->hw.hw_addr + i), | ||
3457 | readl(adapter->hw.hw_addr + i+12), | ||
3458 | readl(adapter->hw.hw_addr + i+8)); | ||
3459 | } | ||
3460 | exit: | ||
3461 | return; | ||
3462 | } | ||
3463 | |||
3242 | /** | 3464 | /** |
3243 | * e1000_tx_timeout - Respond to a Tx Hang | 3465 | * e1000_tx_timeout - Respond to a Tx Hang |
3244 | * @netdev: network interface device structure | 3466 | * @netdev: network interface device structure |
@@ -3260,6 +3482,7 @@ static void e1000_reset_task(struct work_struct *work) | |||
3260 | 3482 | ||
3261 | if (test_bit(__E1000_DOWN, &adapter->flags)) | 3483 | if (test_bit(__E1000_DOWN, &adapter->flags)) |
3262 | return; | 3484 | return; |
3485 | e_err(drv, "Reset adapter\n"); | ||
3263 | e1000_reinit_safe(adapter); | 3486 | e1000_reinit_safe(adapter); |
3264 | } | 3487 | } |
3265 | 3488 | ||
@@ -3677,6 +3900,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3677 | eop, | 3900 | eop, |
3678 | jiffies, | 3901 | jiffies, |
3679 | eop_desc->upper.fields.status); | 3902 | eop_desc->upper.fields.status); |
3903 | e1000_dump(adapter); | ||
3680 | netif_stop_queue(netdev); | 3904 | netif_stop_queue(netdev); |
3681 | } | 3905 | } |
3682 | } | 3906 | } |