e1000e: 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>
This commit is contained in:
parent
675ad47375
commit
84f4ee902a
@ -69,6 +69,361 @@ static const struct e1000_info *e1000_info_tbl[] = {
|
|||||||
[board_pchlan] = &e1000_pch_info,
|
[board_pchlan] = &e1000_pch_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct e1000_reg_info {
|
||||||
|
u32 ofs;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */
|
||||||
|
#define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */
|
||||||
|
#define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */
|
||||||
|
#define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */
|
||||||
|
#define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */
|
||||||
|
|
||||||
|
#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
|
||||||
|
#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
|
||||||
|
#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
|
||||||
|
#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */
|
||||||
|
#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */
|
||||||
|
|
||||||
|
static const struct e1000_reg_info e1000_reg_info_tbl[] = {
|
||||||
|
|
||||||
|
/* General Registers */
|
||||||
|
{E1000_CTRL, "CTRL"},
|
||||||
|
{E1000_STATUS, "STATUS"},
|
||||||
|
{E1000_CTRL_EXT, "CTRL_EXT"},
|
||||||
|
|
||||||
|
/* Interrupt Registers */
|
||||||
|
{E1000_ICR, "ICR"},
|
||||||
|
|
||||||
|
/* RX Registers */
|
||||||
|
{E1000_RCTL, "RCTL"},
|
||||||
|
{E1000_RDLEN, "RDLEN"},
|
||||||
|
{E1000_RDH, "RDH"},
|
||||||
|
{E1000_RDT, "RDT"},
|
||||||
|
{E1000_RDTR, "RDTR"},
|
||||||
|
{E1000_RXDCTL(0), "RXDCTL"},
|
||||||
|
{E1000_ERT, "ERT"},
|
||||||
|
{E1000_RDBAL, "RDBAL"},
|
||||||
|
{E1000_RDBAH, "RDBAH"},
|
||||||
|
{E1000_RDFH, "RDFH"},
|
||||||
|
{E1000_RDFT, "RDFT"},
|
||||||
|
{E1000_RDFHS, "RDFHS"},
|
||||||
|
{E1000_RDFTS, "RDFTS"},
|
||||||
|
{E1000_RDFPC, "RDFPC"},
|
||||||
|
|
||||||
|
/* TX Registers */
|
||||||
|
{E1000_TCTL, "TCTL"},
|
||||||
|
{E1000_TDBAL, "TDBAL"},
|
||||||
|
{E1000_TDBAH, "TDBAH"},
|
||||||
|
{E1000_TDLEN, "TDLEN"},
|
||||||
|
{E1000_TDH, "TDH"},
|
||||||
|
{E1000_TDT, "TDT"},
|
||||||
|
{E1000_TIDV, "TIDV"},
|
||||||
|
{E1000_TXDCTL(0), "TXDCTL"},
|
||||||
|
{E1000_TADV, "TADV"},
|
||||||
|
{E1000_TARC(0), "TARC"},
|
||||||
|
{E1000_TDFH, "TDFH"},
|
||||||
|
{E1000_TDFT, "TDFT"},
|
||||||
|
{E1000_TDFHS, "TDFHS"},
|
||||||
|
{E1000_TDFTS, "TDFTS"},
|
||||||
|
{E1000_TDFPC, "TDFPC"},
|
||||||
|
|
||||||
|
/* List Terminator */
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e1000_regdump - register printout routine
|
||||||
|
*/
|
||||||
|
static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
char rname[16];
|
||||||
|
u32 regs[8];
|
||||||
|
|
||||||
|
switch (reginfo->ofs) {
|
||||||
|
case E1000_RXDCTL(0):
|
||||||
|
for (n = 0; n < 2; n++)
|
||||||
|
regs[n] = __er32(hw, E1000_RXDCTL(n));
|
||||||
|
break;
|
||||||
|
case E1000_TXDCTL(0):
|
||||||
|
for (n = 0; n < 2; n++)
|
||||||
|
regs[n] = __er32(hw, E1000_TXDCTL(n));
|
||||||
|
break;
|
||||||
|
case E1000_TARC(0):
|
||||||
|
for (n = 0; n < 2; n++)
|
||||||
|
regs[n] = __er32(hw, E1000_TARC(n));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(KERN_INFO "%-15s %08x\n",
|
||||||
|
reginfo->name, __er32(hw, reginfo->ofs));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]");
|
||||||
|
printk(KERN_INFO "%-15s ", rname);
|
||||||
|
for (n = 0; n < 2; n++)
|
||||||
|
printk(KERN_CONT "%08x ", regs[n]);
|
||||||
|
printk(KERN_CONT "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e1000e_dump - Print registers, tx-ring and rx-ring
|
||||||
|
*/
|
||||||
|
static void e1000e_dump(struct e1000_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct net_device *netdev = adapter->netdev;
|
||||||
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
|
struct e1000_reg_info *reginfo;
|
||||||
|
struct e1000_ring *tx_ring = adapter->tx_ring;
|
||||||
|
struct e1000_tx_desc *tx_desc;
|
||||||
|
struct my_u0 { u64 a; u64 b; } *u0;
|
||||||
|
struct e1000_buffer *buffer_info;
|
||||||
|
struct e1000_ring *rx_ring = adapter->rx_ring;
|
||||||
|
union e1000_rx_desc_packet_split *rx_desc_ps;
|
||||||
|
struct e1000_rx_desc *rx_desc;
|
||||||
|
struct my_u1 { u64 a; u64 b; u64 c; u64 d; } *u1;
|
||||||
|
u32 staterr;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (!netif_msg_hw(adapter))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Print netdevice Info */
|
||||||
|
if (netdev) {
|
||||||
|
dev_info(&adapter->pdev->dev, "Net device Info\n");
|
||||||
|
printk(KERN_INFO "Device Name state "
|
||||||
|
"trans_start last_rx\n");
|
||||||
|
printk(KERN_INFO "%-15s %016lX %016lX %016lX\n",
|
||||||
|
netdev->name,
|
||||||
|
netdev->state,
|
||||||
|
netdev->trans_start,
|
||||||
|
netdev->last_rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print Registers */
|
||||||
|
dev_info(&adapter->pdev->dev, "Register Dump\n");
|
||||||
|
printk(KERN_INFO " Register Name Value\n");
|
||||||
|
for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl;
|
||||||
|
reginfo->name; reginfo++) {
|
||||||
|
e1000_regdump(hw, reginfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print TX Ring Summary */
|
||||||
|
if (!netdev || !netif_running(netdev))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
|
||||||
|
printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ]"
|
||||||
|
" leng ntw timestamp\n");
|
||||||
|
buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
|
||||||
|
printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n",
|
||||||
|
0, tx_ring->next_to_use, tx_ring->next_to_clean,
|
||||||
|
(u64)buffer_info->dma,
|
||||||
|
buffer_info->length,
|
||||||
|
buffer_info->next_to_watch,
|
||||||
|
(u64)buffer_info->time_stamp);
|
||||||
|
|
||||||
|
/* Print TX Rings */
|
||||||
|
if (!netif_msg_tx_done(adapter))
|
||||||
|
goto rx_ring_summary;
|
||||||
|
|
||||||
|
dev_info(&adapter->pdev->dev, "TX Rings Dump\n");
|
||||||
|
|
||||||
|
/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
|
||||||
|
*
|
||||||
|
* Legacy Transmit Descriptor
|
||||||
|
* +--------------------------------------------------------------+
|
||||||
|
* 0 | Buffer Address [63:0] (Reserved on Write Back) |
|
||||||
|
* +--------------------------------------------------------------+
|
||||||
|
* 8 | Special | CSS | Status | CMD | CSO | Length |
|
||||||
|
* +--------------------------------------------------------------+
|
||||||
|
* 63 48 47 36 35 32 31 24 23 16 15 0
|
||||||
|
*
|
||||||
|
* Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
|
||||||
|
* 63 48 47 40 39 32 31 16 15 8 7 0
|
||||||
|
* +----------------------------------------------------------------+
|
||||||
|
* 0 | TUCSE | TUCS0 | TUCSS | IPCSE | IPCS0 | IPCSS |
|
||||||
|
* +----------------------------------------------------------------+
|
||||||
|
* 8 | MSS | HDRLEN | RSV | STA | TUCMD | DTYP | PAYLEN |
|
||||||
|
* +----------------------------------------------------------------+
|
||||||
|
* 63 48 47 40 39 36 35 32 31 24 23 20 19 0
|
||||||
|
*
|
||||||
|
* Extended Data Descriptor (DTYP=0x1)
|
||||||
|
* +----------------------------------------------------------------+
|
||||||
|
* 0 | Buffer Address [63:0] |
|
||||||
|
* +----------------------------------------------------------------+
|
||||||
|
* 8 | VLAN tag | POPTS | Rsvd | Status | Command | DTYP | DTALEN |
|
||||||
|
* +----------------------------------------------------------------+
|
||||||
|
* 63 48 47 40 39 36 35 32 31 24 23 20 19 0
|
||||||
|
*/
|
||||||
|
printk(KERN_INFO "Tl[desc] [address 63:0 ] [SpeCssSCmCsLen]"
|
||||||
|
" [bi->dma ] leng ntw timestamp bi->skb "
|
||||||
|
"<-- Legacy format\n");
|
||||||
|
printk(KERN_INFO "Tc[desc] [Ce CoCsIpceCoS] [MssHlRSCm0Plen]"
|
||||||
|
" [bi->dma ] leng ntw timestamp bi->skb "
|
||||||
|
"<-- Ext Context format\n");
|
||||||
|
printk(KERN_INFO "Td[desc] [address 63:0 ] [VlaPoRSCm1Dlen]"
|
||||||
|
" [bi->dma ] leng ntw timestamp bi->skb "
|
||||||
|
"<-- Ext Data format\n");
|
||||||
|
for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
|
||||||
|
tx_desc = E1000_TX_DESC(*tx_ring, i);
|
||||||
|
buffer_info = &tx_ring->buffer_info[i];
|
||||||
|
u0 = (struct my_u0 *)tx_desc;
|
||||||
|
printk(KERN_INFO "T%c[0x%03X] %016llX %016llX %016llX "
|
||||||
|
"%04X %3X %016llX %p",
|
||||||
|
(!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' :
|
||||||
|
((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), i,
|
||||||
|
le64_to_cpu(u0->a), le64_to_cpu(u0->b),
|
||||||
|
(u64)buffer_info->dma, buffer_info->length,
|
||||||
|
buffer_info->next_to_watch, (u64)buffer_info->time_stamp,
|
||||||
|
buffer_info->skb);
|
||||||
|
if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
|
||||||
|
printk(KERN_CONT " NTC/U\n");
|
||||||
|
else if (i == tx_ring->next_to_use)
|
||||||
|
printk(KERN_CONT " NTU\n");
|
||||||
|
else if (i == tx_ring->next_to_clean)
|
||||||
|
printk(KERN_CONT " NTC\n");
|
||||||
|
else
|
||||||
|
printk(KERN_CONT "\n");
|
||||||
|
|
||||||
|
if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
|
||||||
|
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
|
||||||
|
16, 1, phys_to_virt(buffer_info->dma),
|
||||||
|
buffer_info->length, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print RX Rings Summary */
|
||||||
|
rx_ring_summary:
|
||||||
|
dev_info(&adapter->pdev->dev, "RX Rings Summary\n");
|
||||||
|
printk(KERN_INFO "Queue [NTU] [NTC]\n");
|
||||||
|
printk(KERN_INFO " %5d %5X %5X\n", 0,
|
||||||
|
rx_ring->next_to_use, rx_ring->next_to_clean);
|
||||||
|
|
||||||
|
/* Print RX Rings */
|
||||||
|
if (!netif_msg_rx_status(adapter))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
dev_info(&adapter->pdev->dev, "RX Rings Dump\n");
|
||||||
|
switch (adapter->rx_ps_pages) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
/* [Extended] Packet Split Receive Descriptor Format
|
||||||
|
*
|
||||||
|
* +-----------------------------------------------------+
|
||||||
|
* 0 | Buffer Address 0 [63:0] |
|
||||||
|
* +-----------------------------------------------------+
|
||||||
|
* 8 | Buffer Address 1 [63:0] |
|
||||||
|
* +-----------------------------------------------------+
|
||||||
|
* 16 | Buffer Address 2 [63:0] |
|
||||||
|
* +-----------------------------------------------------+
|
||||||
|
* 24 | Buffer Address 3 [63:0] |
|
||||||
|
* +-----------------------------------------------------+
|
||||||
|
*/
|
||||||
|
printk(KERN_INFO "R [desc] [buffer 0 63:0 ] "
|
||||||
|
"[buffer 1 63:0 ] "
|
||||||
|
"[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma ] "
|
||||||
|
"[bi->skb] <-- Ext Pkt Split format\n");
|
||||||
|
/* [Extended] Receive Descriptor (Write-Back) Format
|
||||||
|
*
|
||||||
|
* 63 48 47 32 31 13 12 8 7 4 3 0
|
||||||
|
* +------------------------------------------------------+
|
||||||
|
* 0 | Packet | IP | Rsvd | MRQ | Rsvd | MRQ RSS |
|
||||||
|
* | Checksum | Ident | | Queue | | Type |
|
||||||
|
* +------------------------------------------------------+
|
||||||
|
* 8 | VLAN Tag | Length | Extended Error | Extended Status |
|
||||||
|
* +------------------------------------------------------+
|
||||||
|
* 63 48 47 32 31 20 19 0
|
||||||
|
*/
|
||||||
|
printk(KERN_INFO "RWB[desc] [ck ipid mrqhsh] "
|
||||||
|
"[vl l0 ee es] "
|
||||||
|
"[ l3 l2 l1 hs] [reserved ] ---------------- "
|
||||||
|
"[bi->skb] <-- Ext Rx Write-Back format\n");
|
||||||
|
for (i = 0; i < rx_ring->count; i++) {
|
||||||
|
buffer_info = &rx_ring->buffer_info[i];
|
||||||
|
rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i);
|
||||||
|
u1 = (struct my_u1 *)rx_desc_ps;
|
||||||
|
staterr =
|
||||||
|
le32_to_cpu(rx_desc_ps->wb.middle.status_error);
|
||||||
|
if (staterr & E1000_RXD_STAT_DD) {
|
||||||
|
/* Descriptor Done */
|
||||||
|
printk(KERN_INFO "RWB[0x%03X] %016llX "
|
||||||
|
"%016llX %016llX %016llX "
|
||||||
|
"---------------- %p", i,
|
||||||
|
le64_to_cpu(u1->a),
|
||||||
|
le64_to_cpu(u1->b),
|
||||||
|
le64_to_cpu(u1->c),
|
||||||
|
le64_to_cpu(u1->d),
|
||||||
|
buffer_info->skb);
|
||||||
|
} else {
|
||||||
|
printk(KERN_INFO "R [0x%03X] %016llX "
|
||||||
|
"%016llX %016llX %016llX %016llX %p", i,
|
||||||
|
le64_to_cpu(u1->a),
|
||||||
|
le64_to_cpu(u1->b),
|
||||||
|
le64_to_cpu(u1->c),
|
||||||
|
le64_to_cpu(u1->d),
|
||||||
|
(u64)buffer_info->dma,
|
||||||
|
buffer_info->skb);
|
||||||
|
|
||||||
|
if (netif_msg_pktdata(adapter))
|
||||||
|
print_hex_dump(KERN_INFO, "",
|
||||||
|
DUMP_PREFIX_ADDRESS, 16, 1,
|
||||||
|
phys_to_virt(buffer_info->dma),
|
||||||
|
adapter->rx_ps_bsize0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == rx_ring->next_to_use)
|
||||||
|
printk(KERN_CONT " NTU\n");
|
||||||
|
else if (i == rx_ring->next_to_clean)
|
||||||
|
printk(KERN_CONT " NTC\n");
|
||||||
|
else
|
||||||
|
printk(KERN_CONT "\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
/* Legacy Receive Descriptor Format
|
||||||
|
*
|
||||||
|
* +-----------------------------------------------------+
|
||||||
|
* | Buffer Address [63:0] |
|
||||||
|
* +-----------------------------------------------------+
|
||||||
|
* | VLAN Tag | Errors | Status 0 | Packet csum | Length |
|
||||||
|
* +-----------------------------------------------------+
|
||||||
|
* 63 48 47 40 39 32 31 16 15 0
|
||||||
|
*/
|
||||||
|
printk(KERN_INFO "Rl[desc] [address 63:0 ] "
|
||||||
|
"[vl er S cks ln] [bi->dma ] [bi->skb] "
|
||||||
|
"<-- Legacy format\n");
|
||||||
|
for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
|
||||||
|
rx_desc = E1000_RX_DESC(*rx_ring, i);
|
||||||
|
buffer_info = &rx_ring->buffer_info[i];
|
||||||
|
u0 = (struct my_u0 *)rx_desc;
|
||||||
|
printk(KERN_INFO "Rl[0x%03X] %016llX %016llX "
|
||||||
|
"%016llX %p",
|
||||||
|
i, le64_to_cpu(u0->a), le64_to_cpu(u0->b),
|
||||||
|
(u64)buffer_info->dma, buffer_info->skb);
|
||||||
|
if (i == rx_ring->next_to_use)
|
||||||
|
printk(KERN_CONT " NTU\n");
|
||||||
|
else if (i == rx_ring->next_to_clean)
|
||||||
|
printk(KERN_CONT " NTC\n");
|
||||||
|
else
|
||||||
|
printk(KERN_CONT "\n");
|
||||||
|
|
||||||
|
if (netif_msg_pktdata(adapter))
|
||||||
|
print_hex_dump(KERN_INFO, "",
|
||||||
|
DUMP_PREFIX_ADDRESS,
|
||||||
|
16, 1, phys_to_virt(buffer_info->dma),
|
||||||
|
adapter->rx_buffer_len, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* e1000_desc_unused - calculate if we have unused descriptors
|
* e1000_desc_unused - calculate if we have unused descriptors
|
||||||
**/
|
**/
|
||||||
@ -4269,6 +4624,8 @@ static void e1000_reset_task(struct work_struct *work)
|
|||||||
struct e1000_adapter *adapter;
|
struct e1000_adapter *adapter;
|
||||||
adapter = container_of(work, struct e1000_adapter, reset_task);
|
adapter = container_of(work, struct e1000_adapter, reset_task);
|
||||||
|
|
||||||
|
e1000e_dump(adapter);
|
||||||
|
e_err("Reset adapter\n");
|
||||||
e1000e_reinit_locked(adapter);
|
e1000e_reinit_locked(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user