netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] e1000e,igb,ixgbe: add registers etc. printout code just before resetting adapters
@ 2010-01-07 10:47 Taku Izumi
  2010-01-07 11:01 ` [PATCH 1/3] e1000e: " Taku Izumi
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Taku Izumi @ 2010-01-07 10:47 UTC (permalink / raw)
  To: netdev, Bruce Allan, David S. Miller, Jesse Brandeburg,
	John Ronciak
  Cc: Koki Sanagi, Kenji Kaneshige


This patchset adds registers etc. printout code just before resetting adapters
to e1000e, igb, ixgbe modules. The registers, tx/rx rings status, descriptors,
and buffer info will be helpful for detecting the root cause of adapters reset.

This patchset is based on the following Jesse's debug patch of e1000e module.
 http://marc.info/?l=linux-netdev&m=121446492912285&w=2
I think that code is very useful, and should be comitted to upstream.

The main difference between Jesse's patch and mine is as follows:
  - the function which invokes xxx_dump function. (xxx_clean_tx_irq -> xxx_reset_task)
  - add the "dump_flag" module option to select category of printout

The default output is netdevice status (transstart, last_rx), registers,
and tx/rx rings' simple information. TX/RX descriptors information and
buffer_info  can be output by changing the dump_flag module option, but,
of course, the amount of output becomes quite large.

  *[PATCH 1/3] e1000e: add registers etc. printout code just before resetting adapters
  *[PATCH 2/3] igb: add registers etc. printout code just before resetting adapters
  *[PATCH 3/3] ixgbe: add registers etc. printout code just before resetting adapters

Best regards,
Taku Izumi <izumi.taku@jp.fujitsu.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] e1000e: add registers etc. printout code just before resetting adapters
  2010-01-07 10:47 [PATCH 0/3] e1000e,igb,ixgbe: add registers etc. printout code just before resetting adapters Taku Izumi
@ 2010-01-07 11:01 ` Taku Izumi
  2010-01-07 19:00   ` Laurent Chavey
  2010-01-07 11:01 ` [PATCH 2/3] igb: " Taku Izumi
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Taku Izumi @ 2010-01-07 11:01 UTC (permalink / raw)
  To: netdev, Bruce Allan, David S. Miller, Jesse Brandeburg,
	John Ronciak
  Cc: Koki Sanagi, Kenji Kaneshige


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.

The default output is netdevice status (transstart, last_rx), registers,
and tx/rx rings' simple information. TX/RX descriptors information and
buffer_info  can be output by changing the dump_flag module option, but,
of course, the amount of output becomes quite large.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
---
 drivers/net/e1000e/netdev.c |  386 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 386 insertions(+)
Index: net-next-2.6/drivers/net/e1000e/netdev.c
===================================================================
--- net-next-2.6.orig/drivers/net/e1000e/netdev.c
+++ net-next-2.6/drivers/net/e1000e/netdev.c
@@ -52,6 +52,14 @@
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;

+static unsigned int dump_flag = 1;
+module_param(dump_flag, uint, 0644);
+MODULE_PARM_DESC(dump_flag, "Dump Flag");
+#define E1000_DUMP_REGS		(1 << 0)
+#define E1000_DUMP_TX_RINGS	(1 << 1)
+#define E1000_DUMP_RX_RINGS	(1 << 2)
+#define E1000_DUMP_BUFFERS	(1 << 3)
+
 static const struct e1000_info *e1000_info_tbl[] = {
 	[board_82571]		= &e1000_82571_info,
 	[board_82572]		= &e1000_82572_info,
@@ -65,6 +73,383 @@ static const struct e1000_info *e1000_in
 	[board_pchlan]		= &e1000_pch_info,
 };

+static void hexdump(dma_addr_t dma, u16 len)
+{
+	uint16_t offset, i;
+	char str[80], byte[4];
+	void *va = phys_to_virt((unsigned long)dma);
+
+	printk(KERN_ERR "buffer at %016llX (%d)\n", (u64)dma, len);
+	for (offset = 0; offset < len; offset += 16) {
+		sprintf(str, "%04x: ", offset);
+		for (i = 0; i < 16; i++) {
+			if ((offset + i) < len)
+				sprintf(byte, "%02x ",
+				((unsigned char *)va)[offset + i]);
+			else
+				strcpy(byte, "   ");
+			strcat(str, byte);
+		}
+		printk(KERN_ERR "%s\n", str);
+	}
+}
+
+/*
+ * 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;
+	u32 reg;
+	char rname[16];
+	int n = 0;
+	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;
+
+	/* Print netdevice Info */
+	if (netdev) {
+		dev_err(&adapter->pdev->dev, "Net device Info\n");
+		printk(KERN_ERR "Device Name     state            "
+			"trans_start      last_rx\n");
+		printk(KERN_ERR "%-15s %016lX %016lX %016lX\n",
+			netdev->name,
+			netdev->state,
+			netdev->trans_start,
+			netdev->last_rx);
+	}
+
+	/* Print Registers */
+	if ((dump_flag & E1000_DUMP_REGS) == 0)
+		goto tx_ring_summary;
+
+	dev_err(&adapter->pdev->dev, "Register Dump\n");
+
+#define E1000_RDFH	0x02410
+#define E1000_RDFT	0x02418
+#define E1000_RDFHS	0x02420
+#define E1000_RDFTS	0x02428
+#define E1000_RDFPC	0x02430
+
+#define E1000_TDFH	0x03410
+#define E1000_TDFT	0x03418
+#define E1000_TDFHS	0x03420
+#define E1000_TDFTS	0x03428
+#define E1000_TDFPC	0x03430
+
+	printk(KERN_ERR " Register Name   [value ]\n");
+	for (reg = 0; reg < 0x04000; reg += sizeof(u32)) {
+		switch (reg & 0xffffffff) {
+
+		/* General Registers */
+		case E1000_CTRL:
+			sprintf(rname, "CTRL"); break;
+		case E1000_STATUS:
+			sprintf(rname, "STATUS"); break;
+		case E1000_CTRL_EXT:
+			sprintf(rname, "CTRL_EXT"); break;
+
+		/* Interrupt Registers*/
+		case E1000_ICR:
+			sprintf(rname, "ICR"); break;
+
+		/* RX */
+		case E1000_RCTL:
+			sprintf(rname, "RCTL"); break;
+		case E1000_RDLEN:
+			sprintf(rname, "RDLEN"); break;
+		case E1000_RDH:
+			sprintf(rname, "RDH"); break;
+		case E1000_RDT:
+			sprintf(rname, "RDT"); break;
+		case E1000_RDTR:
+			sprintf(rname, "RDTR"); break;
+		case E1000_RXDCTL(0):
+			sprintf(rname, "RXDCTL[0]"); break;
+		case E1000_ERT:
+			sprintf(rname, "ERT"); break;
+		case E1000_RDBAL:
+			sprintf(rname, "RDBAL"); break;
+		case E1000_RDBAH:
+			sprintf(rname, "RDBAH"); break;
+		case E1000_RDFH:
+			sprintf(rname, "RDFH"); break;
+		case E1000_RDFT:
+			sprintf(rname, "RDFT"); break;
+		case E1000_RDFHS:
+			sprintf(rname, "RDFHS"); break;
+		case E1000_RDFTS:
+			sprintf(rname, "RDFTS"); break;
+		case E1000_RDFPC:
+			sprintf(rname, "RDFPC"); break;
+
+		/* TX */
+		case E1000_TCTL:
+			sprintf(rname, "TCTL"); break;
+		case E1000_TDBAL:
+			sprintf(rname, "TDBAL"); break;
+		case E1000_TDBAH:
+			sprintf(rname, "TDBAH"); break;
+		case E1000_TDLEN:
+			sprintf(rname, "TDLEN"); break;
+		case E1000_TDH:
+			sprintf(rname, "TDH"); break;
+		case E1000_TDT:
+			sprintf(rname, "TDT"); break;
+		case E1000_TIDV:
+			sprintf(rname, "TIDV"); break;
+		case E1000_TXDCTL(0):
+			sprintf(rname, "TXDCTL[0-1]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 2; n++)
+				printk("%08x ", readl(hw->hw_addr +
+							(reg & 0xffffffff)));
+			printk("\n");
+			continue;
+		case E1000_TADV:
+			sprintf(rname, "TADV"); break;
+		case E1000_TARC(0):
+			sprintf(rname, "TARC[0-1]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 2; n++)
+				printk("%08x ", readl(hw->hw_addr +
+							(reg & 0xffffffff)));
+			printk("\n");
+			continue;
+		case E1000_TDFH:
+			sprintf(rname, "TDFH"); break;
+		case E1000_TDFT:
+			sprintf(rname, "TDFT"); break;
+		case E1000_TDFHS:
+			sprintf(rname, "TDFHS"); break;
+		case E1000_TDFTS:
+			sprintf(rname, "TDFTS"); break;
+		case E1000_TDFPC:
+			sprintf(rname, "TDFPC"); break;
+
+		default:
+			continue;
+		}
+		printk(KERN_ERR "%-15s %08x\n", rname,
+			readl(hw->hw_addr + (reg & 0xffffffff)));
+	}
+
+	/* Print TX Ring Summary */
+tx_ring_summary:
+	if (!netdev || !netif_running(netdev))
+		goto exit;
+
+	dev_err(&adapter->pdev->dev, "TX Rings Summary\n");
+	printk(KERN_ERR "Queue [NTU] [NTC] [bi(ntc)->dma  ]"
+		" leng ntw timestamp\n");
+	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
+	printk(KERN_ERR " %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 ((dump_flag & E1000_DUMP_TX_RINGS) == 0)
+		goto rx_ring_summary;
+
+	dev_err(&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_ERR "Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen]"
+		" [bi->dma       ] leng  ntw timestamp        bi->skb "
+		"<-- Legacy format\n");
+	printk(KERN_ERR "Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen]"
+		" [bi->dma       ] leng  ntw timestamp        bi->skb "
+		"<-- Ext Context format\n");
+	printk(KERN_ERR "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_ERR "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(" NTC/U\n");
+		else if (i == tx_ring->next_to_use)
+			printk(" NTU\n");
+		else if (i == tx_ring->next_to_clean)
+			printk(" NTC\n");
+		else
+			printk("\n");
+
+		if ((dump_flag & E1000_DUMP_BUFFERS) && buffer_info->dma != 0)
+			hexdump(buffer_info->dma, buffer_info->length);
+	}
+
+	/* Print RX Rings Summary */
+rx_ring_summary:
+	dev_err(&adapter->pdev->dev, "RX Rings Summary\n");
+	printk(KERN_ERR "Queue [NTU] [NTC]\n");
+	printk(KERN_ERR " %5d %5X %5X\n", 0,
+		rx_ring->next_to_use, rx_ring->next_to_clean);
+
+	/* Print RX Rings */
+	if ((dump_flag & E1000_DUMP_RX_RINGS) == 0)
+		goto exit;
+
+	dev_err(&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_ERR "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_ERR "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_ERR "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_ERR "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 (dump_flag & E1000_DUMP_BUFFERS)
+					hexdump(buffer_info->dma,
+						adapter->rx_ps_bsize0);
+			}
+
+			if (i == rx_ring->next_to_use)
+				printk(" NTU\n");
+			else if (i == rx_ring->next_to_clean)
+				printk(" NTC\n");
+			else
+				printk("\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_ERR "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_ERR "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(" NTU\n");
+			else if (i == rx_ring->next_to_clean)
+				printk(" NTC\n");
+			else
+				printk("\n");
+
+			if (dump_flag & E1000_DUMP_BUFFERS)
+				hexdump(buffer_info->dma,
+					adapter->rx_buffer_len);
+		}
+	}
+
+exit:
+	return;
+}
+
 /**
  * e1000_desc_unused - calculate if we have unused descriptors
  **/
@@ -4257,6 +4642,7 @@ static void e1000_reset_task(struct work
 	struct e1000_adapter *adapter;
 	adapter = container_of(work, struct e1000_adapter, reset_task);

+	e1000e_dump(adapter);
 	e1000e_reinit_locked(adapter);
 }




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/3] igb: add registers etc. printout code just before resetting adapters
  2010-01-07 10:47 [PATCH 0/3] e1000e,igb,ixgbe: add registers etc. printout code just before resetting adapters Taku Izumi
  2010-01-07 11:01 ` [PATCH 1/3] e1000e: " Taku Izumi
@ 2010-01-07 11:01 ` Taku Izumi
  2010-01-07 19:16   ` Laurent Chavey
  2010-01-07 11:02 ` [PATCH 3/3] ixgbe: " Taku Izumi
  2010-01-11 21:52 ` [PATCH 0/3] e1000e,igb,ixgbe: " Jeff Kirsher
  3 siblings, 1 reply; 9+ messages in thread
From: Taku Izumi @ 2010-01-07 11:01 UTC (permalink / raw)
  To: netdev, Bruce Allan, David S. Miller, Jesse Brandeburg,
	John Ronciak
  Cc: Koki Sanagi, Kenji Kaneshige


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.

The default output is netdevice status (transstart, last_rx), registers,
and tx/rx rings' simple information. TX/RX descriptors information and
buffer_info  can be output by changing the dump_flag module option, but,
of course, the amount of output becomes quite large.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
---
 drivers/net/igb/igb_main.c |  360 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 360 insertions(+)

Index: net-next-2.6/drivers/net/igb/igb_main.c
===================================================================
--- net-next-2.6.orig/drivers/net/igb/igb_main.c
+++ net-next-2.6/drivers/net/igb/igb_main.c
@@ -60,6 +60,14 @@ static const struct e1000_info *igb_info
 	[board_82575] = &e1000_82575_info,
 };

+static unsigned int dump_flag = 1;
+module_param(dump_flag, uint, 0644);
+MODULE_PARM_DESC(dump_flag, "Dump Flag");
+#define IGB_DUMP_REGS		(1 << 0)
+#define IGB_DUMP_TX_RINGS	(1 << 1)
+#define IGB_DUMP_RX_RINGS	(1 << 2)
+#define IGB_DUMP_BUFFERS	(1 << 3)
+
 static struct pci_device_id igb_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_FIBER), board_82575 },
@@ -189,6 +197,357 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Eth
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);

+static void hexdump(dma_addr_t dma, u16 len)
+{
+	uint16_t offset, i;
+	char str[80], byte[4];
+	void *va = phys_to_virt((unsigned long)dma);
+
+	printk(KERN_ERR "buffer at %016llX (%d)\n", (u64)dma, len);
+	for (offset = 0; offset < len; offset += 16) {
+		sprintf(str, "%04x: ", offset);
+		for (i = 0; i < 16; i++) {
+			if ((offset + i) < len)
+				sprintf(byte, "%02x ",
+				((unsigned char *)va)[offset + i]);
+			else
+				strcpy(byte, "   ");
+			strcat(str, byte);
+		}
+		printk(KERN_ERR "%s\n", str);
+	}
+}
+
+/*
+ * igb_dump - Print registers, tx-rings and rx-rings
+ */
+static void igb_dump(struct igb_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
+	u32 reg;
+	char rname[16];
+	int n = 0;
+	struct igb_ring *tx_ring;
+	union e1000_adv_tx_desc *tx_desc;
+	struct my_u0 { u64 a; u64 b; } *u0;
+	struct igb_buffer *buffer_info;
+	struct igb_ring *rx_ring;
+	union e1000_adv_rx_desc *rx_desc;
+	u32 staterr;
+	int i = 0;
+
+	/* Print netdevice Info */
+	if (netdev) {
+		dev_err(&adapter->pdev->dev, "Net device Info\n");
+		printk(KERN_ERR "Device Name     state            "
+			"trans_start      last_rx\n");
+		printk(KERN_ERR "%-15s %016lX %016lX %016lX\n",
+		netdev->name,
+		netdev->state,
+		netdev->trans_start,
+		netdev->last_rx);
+	}
+
+	/* Print Registers */
+	if ((dump_flag & IGB_DUMP_REGS) == 0)
+		goto tx_ring_summary;
+
+	dev_err(&adapter->pdev->dev, "Register Dump\n");
+
+	printk(KERN_ERR " Register Name   [value ]\n");
+	for (reg = 0; reg < 0x04000; reg += sizeof(u32)) {
+		switch (reg & 0xffffffff) {
+		/* General Registers */
+		case E1000_CTRL:
+			sprintf(rname, "CTRL"); break;
+		case E1000_STATUS:
+			sprintf(rname, "STATUS"); break;
+		case E1000_CTRL_EXT:
+			sprintf(rname, "CTRL_EXT"); break;
+
+		/* Interrupt Registers*/
+		case E1000_ICR:
+			sprintf(rname, "ICR"); break;
+
+		/* RX */
+		case E1000_RCTL:
+			sprintf(rname, "RCTL"); break;
+		case E1000_RDLEN(0):
+			sprintf(rname, "RDLEN[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_RDLEN(n)));
+			printk("\n");
+			continue;
+		case E1000_RDH(0):
+			sprintf(rname, "RDH[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_RDH(n)));
+			printk("\n");
+			continue;
+		case E1000_RDT(0):
+			sprintf(rname, "RDT[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_RDT(n)));
+			printk("\n");
+			continue;
+		case E1000_RXDCTL(0):
+			sprintf(rname, "RXDCTL[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_RXDCTL(n)));
+			printk("\n");
+			continue;
+		case E1000_RDBAL(0):
+			sprintf(rname, "RDBAL[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_RDBAL(n)));
+			printk("\n");
+			continue;
+		case E1000_RDBAH(0):
+			sprintf(rname, "RDBAH[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_RDBAH(n)));
+			printk("\n");
+			continue;
+
+		/* TX */
+		case E1000_TCTL:
+			sprintf(rname, "TCTL"); break;
+		case E1000_TDBAL(0):
+			sprintf(rname, "TDBAL[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_TDBAL(n)));
+			printk("\n");
+			continue;
+		case E1000_TDBAH(0):
+			sprintf(rname, "TDBAH[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_TDBAH(n)));
+			printk("\n");
+			continue;
+		case E1000_TDLEN(0):
+			sprintf(rname, "TDLEN[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_TDLEN(n)));
+			printk("\n");
+			continue;
+		case E1000_TDH(0):
+			sprintf(rname, "TDH[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_TDH(n)));
+			printk("\n");
+			continue;
+		case E1000_TDT(0):
+			sprintf(rname, "TDT[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_TDT(n)));
+			printk("\n");
+			continue;
+		case E1000_TXDCTL(0):
+			sprintf(rname, "TXDCTL[0-3]");
+			printk(KERN_ERR "%-15s ", rname);
+			for (n = 0; n < 4; n++)
+				printk("%08x ", rd32(E1000_TXDCTL(n)));
+			printk("\n");
+			continue;
+		case E1000_TDFH:
+			sprintf(rname, "TDFH"); break;
+		case E1000_TDFT:
+			sprintf(rname, "TDFT"); break;
+		case E1000_TDFHS:
+			sprintf(rname, "TDFHS"); break;
+		case E1000_TDFPC:
+			sprintf(rname, "TDFPC"); break;
+
+		default:
+			continue;
+		}
+
+		printk(KERN_ERR "%-15s %08x\n", rname,
+			rd32((reg & 0xffffffff)));
+
+	}
+
+	/* Print TX Ring Summary */
+tx_ring_summary:
+	if (!netdev || !netif_running(netdev))
+		goto exit;
+
+	dev_err(&adapter->pdev->dev, "TX Rings Summary\n");
+	printk(KERN_ERR "Queue [NTU] [NTC] [bi(ntc)->dma  ]"
+		" leng ntw timestamp\n");
+	for (n = 0; n < adapter->num_tx_queues; n++) {
+		tx_ring = &adapter->tx_ring[n];
+		buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
+		printk(KERN_ERR " %5d %5X %5X %016llX %04X %3X %016llX\n",
+			   n, 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 ((dump_flag & IGB_DUMP_TX_RINGS) == 0)
+		goto rx_ring_summary;
+
+	dev_err(&adapter->pdev->dev, "TX Rings Dump\n");
+
+	/* Transmit Descriptor Formats
+	 *
+	 * Advanced Transmit Descriptor
+	 *   +--------------------------------------------------------------+
+	 * 0 |         Buffer Address [63:0]                                |
+	 *   +--------------------------------------------------------------+
+	 * 8 | PAYLEN  | PORTS  |CC|IDX | STA | DCMD  |DTYP|MAC|RSV| DTALEN |
+	 *   +--------------------------------------------------------------+
+	 *   63      46 45    40 39 38 36 35 32 31   24             15       0
+	 */
+
+	for (n = 0; n < adapter->num_tx_queues; n++) {
+		tx_ring = &adapter->tx_ring[n];
+		printk(KERN_ERR "------------------------------------\n");
+		printk(KERN_ERR "TX QUEUE INDEX = %d\n", tx_ring->queue_index);
+		printk(KERN_ERR "------------------------------------\n");
+		printk(KERN_ERR "T [desc]     [address 63:0  ] "
+			"[PlPOCIStDDM Ln] [bi->dma       ] "
+			"leng  ntw timestamp        bi->skb\n");
+
+		for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
+			tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
+			buffer_info = &tx_ring->buffer_info[i];
+			u0 = (struct my_u0 *)tx_desc;
+			printk(KERN_ERR "T [0x%03X]    %016llX %016llX %016llX"
+				" %04X  %3X %016llX %p", 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(" NTC/U\n");
+			else if (i == tx_ring->next_to_use)
+				printk(" NTU\n");
+			else if (i == tx_ring->next_to_clean)
+				printk(" NTC\n");
+			else
+				printk("\n");
+
+			if ((dump_flag & IGB_DUMP_BUFFERS) &&
+				buffer_info->dma != 0)
+				hexdump(buffer_info->dma, buffer_info->length);
+		}
+	}
+
+	/* Print RX Rings Summary */
+rx_ring_summary:
+	dev_err(&adapter->pdev->dev, "RX Rings Summary\n");
+	printk(KERN_ERR "Queue [NTU] [NTC]\n");
+	for (n = 0; n < adapter->num_rx_queues; n++) {
+		rx_ring = &adapter->rx_ring[n];
+		printk(KERN_ERR " %5d %5X %5X\n", n,
+			   rx_ring->next_to_use, rx_ring->next_to_clean);
+	}
+
+	/* Print RX Rings */
+	if ((dump_flag & IGB_DUMP_RX_RINGS) == 0)
+		goto exit;
+
+	dev_err(&adapter->pdev->dev, "RX Rings Dump\n");
+
+	/* Advanced Receive Descriptor (Read) Format
+	 *    63                                           1        0
+	 *    +-----------------------------------------------------+
+	 *  0 |       Packet Buffer Address [63:1]           |A0/NSE|
+	 *    +----------------------------------------------+------+
+	 *  8 |       Header Buffer Address [63:1]           |  DD  |
+	 *    +-----------------------------------------------------+
+	 *
+	 *
+	 * Advanced Receive Descriptor (Write-Back) Format
+	 *
+	 *   63       48 47    32 31  30      21 20 17 16   4 3     0
+	 *   +------------------------------------------------------+
+	 * 0 | Packet     IP     |SPH| HDR_LEN   | RSV|Packet|  RSS |
+	 *   | Checksum   Ident  |   |           |    | Type | Type |
+	 *   +------------------------------------------------------+
+	 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
+	 *   +------------------------------------------------------+
+	 *   63       48 47    32 31            20 19               0
+	 */
+
+	for (n = 0; n < adapter->num_rx_queues; n++) {
+		rx_ring = &adapter->rx_ring[n];
+		printk(KERN_ERR "------------------------------------\n");
+		printk(KERN_ERR "RX QUEUE INDEX = %d\n", rx_ring->queue_index);
+		printk(KERN_ERR "------------------------------------\n");
+		printk(KERN_ERR "R  [desc]      [ PktBuf     A0] "
+			"[  HeadBuf   DD] [bi->dma       ] [bi->skb] "
+			"<-- Adv Rx Read format\n");
+		printk(KERN_ERR "RWB[desc]      [PcsmIpSHl PtRs] "
+			"[vl er S cks ln] ---------------- [bi->skb] "
+			"<-- Adv Rx Write-Back format\n");
+
+		for (i = 0; i < rx_ring->count; i++) {
+			buffer_info = &rx_ring->buffer_info[i];
+			rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
+			u0 = (struct my_u0 *)rx_desc;
+			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+			if (staterr & E1000_RXD_STAT_DD) {
+				/* Descriptor Done */
+				printk(KERN_ERR "RWB[0x%03X]     %016llX "
+					"%016llX ---------------- %p", i,
+					le64_to_cpu(u0->a),
+					le64_to_cpu(u0->b),
+					buffer_info->skb);
+			} else {
+				printk(KERN_ERR "R  [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 (dump_flag & IGB_DUMP_BUFFERS) {
+					hexdump(buffer_info->dma,
+						rx_ring->rx_buffer_len);
+					if (rx_ring->rx_buffer_len
+						< IGB_RXBUFFER_1024)
+						hexdump(buffer_info->page_dma +
+						 buffer_info->page_offset,
+						 PAGE_SIZE/2);
+				}
+			}
+
+			if (i == rx_ring->next_to_use)
+				printk(" NTU\n");
+			else if (i == rx_ring->next_to_clean)
+				printk(" NTC\n");
+			else
+				printk("\n");
+
+		}
+	}
+
+exit:
+	return;
+}
+
+
 /**
  * igb_read_clock - read raw cycle counter (to be used by time counter)
  */
@@ -3859,6 +4218,7 @@ static void igb_reset_task(struct work_s
 	struct igb_adapter *adapter;
 	adapter = container_of(work, struct igb_adapter, reset_task);

+	igb_dump(adapter);
 	igb_reinit_locked(adapter);
 }




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/3] ixgbe: add registers etc. printout code just before resetting adapters
  2010-01-07 10:47 [PATCH 0/3] e1000e,igb,ixgbe: add registers etc. printout code just before resetting adapters Taku Izumi
  2010-01-07 11:01 ` [PATCH 1/3] e1000e: " Taku Izumi
  2010-01-07 11:01 ` [PATCH 2/3] igb: " Taku Izumi
@ 2010-01-07 11:02 ` Taku Izumi
  2010-01-11 21:28   ` Jesse Brandeburg
  2010-01-11 21:52 ` [PATCH 0/3] e1000e,igb,ixgbe: " Jeff Kirsher
  3 siblings, 1 reply; 9+ messages in thread
From: Taku Izumi @ 2010-01-07 11:02 UTC (permalink / raw)
  To: netdev, Bruce Allan, David S. Miller, Jesse Brandeburg,
	John Ronciak
  Cc: Koki Sanagi, Kenji Kaneshige


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.

The default output is netdevice status (transstart, last_rx), registers,
and tx/rx rings' simple information. TX/RX descriptors information and
buffer_info  can be output by changing the dump_flag module option, but,
of course, the amount of output becomes quite large.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
---
 drivers/net/ixgbe/ixgbe_main.c |  436 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 436 insertions(+)

Index: net-next-2.6/drivers/net/ixgbe/ixgbe_main.c
===================================================================
--- net-next-2.6.orig/drivers/net/ixgbe/ixgbe_main.c
+++ net-next-2.6/drivers/net/ixgbe/ixgbe_main.c
@@ -59,6 +59,15 @@ static const struct ixgbe_info *ixgbe_in
 	[board_82599] = &ixgbe_82599_info,
 };

+
+static unsigned int dump_flag = 1;
+module_param(dump_flag, uint, 0644);
+MODULE_PARM_DESC(dump_flag, "Dump Flag");
+#define IXGBE_DUMP_REGS		(1 << 0)
+#define IXGBE_DUMP_TX_RINGS	(1 << 1)
+#define IXGBE_DUMP_RX_RINGS	(1 << 2)
+#define IXGBE_DUMP_BUFFERS	(1 << 3)
+
 /* ixgbe_pci_tbl - PCI Device ID Table
  *
  * Wildcard entries (PCI_ANY_ID) should come last
@@ -131,6 +140,432 @@ MODULE_VERSION(DRV_VERSION);

 #define DEFAULT_DEBUG_LEVEL_SHIFT 3

+static void hexdump(dma_addr_t dma, u16 len)
+{
+	uint16_t offset, i;
+	char str[80], byte[4];
+	void *va = phys_to_virt((unsigned long)dma);
+
+	printk(KERN_ERR "buffer at %016llX (%d)\n", (u64)dma, len);
+	for (offset = 0; offset < len; offset += 16) {
+		sprintf(str, "%04x: ", offset);
+		for (i = 0; i < 16; i++) {
+			if ((offset + i) < len)
+				sprintf(byte, "%02x ",
+					((unsigned char *)va)[offset + i]);
+			else
+				strcpy(byte, "   ");
+			strcat(str, byte);
+		}
+		printk(KERN_ERR "%s\n", str);
+	}
+}
+
+/*
+ * ixgbe_dump - Print registers, tx-rings and rx-rings
+ */
+static void ixgbe_dump(struct ixgbe_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	u32 reg;
+	char rname[32];
+	int n = 0;
+	int j = 0;
+	struct ixgbe_ring *tx_ring;
+	struct ixgbe_tx_buffer *tx_buffer_info;
+	union ixgbe_adv_tx_desc *tx_desc;
+	struct my_u0 { u64 a; u64 b; } *u0;
+	struct ixgbe_ring *rx_ring;
+	union ixgbe_adv_rx_desc *rx_desc;
+	struct ixgbe_rx_buffer *rx_buffer_info;
+	u32 staterr;
+	int i = 0;
+
+	/* Print netdevice Info */
+	dev_err(&adapter->pdev->dev, "Net device Info\n");
+	if (netdev) {
+		printk(KERN_ERR "Device Name     state            "
+			"trans_start      last_rx\n");
+		printk(KERN_ERR "%-15s %016lX %016lX %016lX\n",
+		netdev->name,
+		netdev->state,
+		netdev->trans_start,
+		netdev->last_rx);
+	}
+
+	/* Print Registers */
+	if ((dump_flag & IXGBE_DUMP_REGS) == 0)
+		goto tx_ring_summary;
+
+	dev_err(&adapter->pdev->dev, "Register Dump\n");
+
+	printk(KERN_ERR " Register Name   [value ]\n");
+	for (reg = 0; reg < 0x07000; reg += sizeof(u32)) {
+		switch (reg & 0xffffffff) {
+		/* General Registers */
+		case IXGBE_CTRL:
+			sprintf(rname, "CTRL"); break;
+		case IXGBE_STATUS:
+			sprintf(rname, "STATUS"); break;
+		case IXGBE_CTRL_EXT:
+			sprintf(rname, "CTRL_EXT"); break;
+
+		/* Interrupt Registers*/
+		case IXGBE_EICR:
+			sprintf(rname, "EICR"); break;
+
+		/* RX */
+		case IXGBE_SRRCTL(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "SRRCTL[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_SRRCTL(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_DCA_RXCTRL(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "DRXCTRL[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_DCA_RXCTRL(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_RDLEN(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "RDLEN[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_RDLEN(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_RDH(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "RDH[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_RDH(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_RDT(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "RDT[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_RDT(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_RXDCTL(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "RXDCTL[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_RXDCTL(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_RDBAL(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "RDBAL[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_RDBAL(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_RDBAH(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "RDBAH[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_RDBAH(i*8+j)));
+				printk("\n");
+			}
+			continue;
+
+		/* TX */
+		case IXGBE_TDBAL(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "TDBAL[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_TDBAL(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_TDBAH(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "TDBAH[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_TDBAH(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_TDLEN(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "TDLEN[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_TDLEN(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_TDH(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "TDH[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_TDH(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_TDT(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "TDT[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_TDT(i*8+j)));
+				printk("\n");
+			}
+			continue;
+		case IXGBE_TXDCTL(0):
+			for (i = 0; i < 8; i++) {
+				sprintf(rname, "TXDCTL[%d-%d]",
+					i*8, i*8+7);
+				printk(KERN_ERR "%-15s ", rname);
+				for (j = 0; j < 8; j++)
+					printk("%08x ",
+						IXGBE_READ_REG(hw,
+						  IXGBE_TXDCTL(i*8+j)));
+				printk("\n");
+			}
+			continue;
+
+		default:
+			continue;
+		}
+
+		printk(KERN_ERR "%-15s %08x\n", rname,
+			IXGBE_READ_REG(hw, (reg & 0xffffffff)));
+	}
+
+	/* Print TX Ring Summary */
+tx_ring_summary:
+	if (!netdev || !netif_running(netdev))
+		goto exit;
+
+	dev_err(&adapter->pdev->dev, "TX Rings Summary\n");
+	printk(KERN_ERR "Queue [NTU] [NTC] [bi(ntc)->dma  ] "
+		"leng ntw timestamp\n");
+	for (n = 0; n < adapter->num_tx_queues; n++) {
+		tx_ring = &adapter->tx_ring[n];
+		tx_buffer_info =
+			&tx_ring->tx_buffer_info[tx_ring->next_to_clean];
+		printk(KERN_ERR " %5d %5X %5X %016llX %04X %3X %016llX\n",
+			   n, tx_ring->next_to_use, tx_ring->next_to_clean,
+			   (u64)tx_buffer_info->dma,
+			   tx_buffer_info->length,
+			   tx_buffer_info->next_to_watch,
+			   (u64)tx_buffer_info->time_stamp);
+	}
+
+	/* Print TX Rings */
+	if ((dump_flag & IXGBE_DUMP_TX_RINGS) == 0)
+		goto rx_ring_summary;
+
+	dev_err(&adapter->pdev->dev, "TX Rings Dump\n");
+
+	/* Transmit Descriptor Formats
+	 *
+	 * Advanced Transmit Descriptor
+	 *   +--------------------------------------------------------------+
+	 * 0 |         Buffer Address [63:0]                                |
+	 *   +--------------------------------------------------------------+
+	 * 8 |  PAYLEN  | PORTS  | IDX | STA | DCMD  |DTYP |  RSV |  DTALEN |
+	 *   +--------------------------------------------------------------+
+	 *   63       46 45    40 39 36 35 32 31   24 23 20 19              0
+	 */
+
+	for (n = 0; n < adapter->num_tx_queues; n++) {
+		tx_ring = &adapter->tx_ring[n];
+		printk(KERN_ERR "------------------------------------\n");
+		printk(KERN_ERR "TX QUEUE INDEX = %d\n", tx_ring->queue_index);
+		printk(KERN_ERR "------------------------------------\n");
+		printk(KERN_ERR "T [desc]     [address 63:0  ] "
+			"[PlPOIdStDDt Ln] [bi->dma       ] "
+			"leng  ntw timestamp        bi->skb\n");
+
+		for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
+			tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
+			tx_buffer_info = &tx_ring->tx_buffer_info[i];
+			u0 = (struct my_u0 *)tx_desc;
+			printk(KERN_ERR "T [0x%03X]    %016llX %016llX %016llX"
+				" %04X  %3X %016llX %p", i,
+				le64_to_cpu(u0->a),
+				le64_to_cpu(u0->b),
+				(u64)tx_buffer_info->dma,
+				tx_buffer_info->length,
+				tx_buffer_info->next_to_watch,
+				(u64)tx_buffer_info->time_stamp,
+				tx_buffer_info->skb);
+			if (i == tx_ring->next_to_use &&
+				i == tx_ring->next_to_clean)
+				printk(" NTC/U\n");
+			else if (i == tx_ring->next_to_use)
+				printk(" NTU\n");
+			else if (i == tx_ring->next_to_clean)
+				printk(" NTC\n");
+			else
+				printk("\n");
+
+			if ((dump_flag & IXGBE_DUMP_BUFFERS) &&
+				tx_buffer_info->dma != 0)
+				hexdump(tx_buffer_info->dma,
+					tx_buffer_info->length);
+		}
+	}
+
+	/* Print RX Rings Summary */
+rx_ring_summary:
+	dev_err(&adapter->pdev->dev, "RX Rings Summary\n");
+	printk(KERN_ERR "Queue [NTU] [NTC]\n");
+	for (n = 0; n < adapter->num_rx_queues; n++) {
+		rx_ring = &adapter->rx_ring[n];
+		printk(KERN_ERR "%5d %5X %5X\n", n,
+			   rx_ring->next_to_use, rx_ring->next_to_clean);
+	}
+
+	/* Print RX Rings */
+	if ((dump_flag & IXGBE_DUMP_RX_RINGS) == 0)
+		goto exit;
+
+	dev_err(&adapter->pdev->dev, "RX Rings Dump\n");
+
+	/* Advanced Receive Descriptor (Read) Format
+	 *    63                                           1        0
+	 *    +-----------------------------------------------------+
+	 *  0 |       Packet Buffer Address [63:1]           |A0/NSE|
+	 *    +----------------------------------------------+------+
+	 *  8 |       Header Buffer Address [63:1]           |  DD  |
+	 *    +-----------------------------------------------------+
+	 *
+	 *
+	 * Advanced Receive Descriptor (Write-Back) Format
+	 *
+	 *   63       48 47    32 31  30      21 20 16 15   4 3     0
+	 *   +------------------------------------------------------+
+	 * 0 | Packet     IP     |SPH| HDR_LEN   | RSV|Packet|  RSS |
+	 *   | Checksum   Ident  |   |           |    | Type | Type |
+	 *   +------------------------------------------------------+
+	 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
+	 *   +------------------------------------------------------+
+	 *   63       48 47    32 31            20 19               0
+	 */
+	for (n = 0; n < adapter->num_rx_queues; n++) {
+		rx_ring = &adapter->rx_ring[n];
+		printk(KERN_ERR "------------------------------------\n");
+		printk(KERN_ERR "RX QUEUE INDEX = %d\n", rx_ring->queue_index);
+		printk(KERN_ERR "------------------------------------\n");
+		printk(KERN_ERR "R  [desc]      [ PktBuf     A0] "
+			"[  HeadBuf   DD] [bi->dma       ] [bi->skb] "
+			"<-- Adv Rx Read format\n");
+		printk(KERN_ERR "RWB[desc]      [PcsmIpSHl PtRs] "
+			"[vl er S cks ln] ---------------- [bi->skb] "
+			"<-- Adv Rx Write-Back format\n");
+
+		for (i = 0; i < rx_ring->count; i++) {
+			rx_buffer_info = &rx_ring->rx_buffer_info[i];
+			rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+			u0 = (struct my_u0 *)rx_desc;
+			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+			if (staterr & IXGBE_RXD_STAT_DD) {
+				/* Descriptor Done */
+				printk(KERN_ERR "RWB[0x%03X]     %016llX "
+					"%016llX ---------------- %p", i,
+					le64_to_cpu(u0->a),
+					le64_to_cpu(u0->b),
+					rx_buffer_info->skb);
+			} else {
+				printk(KERN_ERR "R  [0x%03X]     %016llX "
+					"%016llX %016llX %p", i,
+					le64_to_cpu(u0->a),
+					le64_to_cpu(u0->b),
+					(u64)rx_buffer_info->dma,
+					rx_buffer_info->skb);
+
+				if (dump_flag & IXGBE_DUMP_BUFFERS) {
+					hexdump(rx_buffer_info->dma,
+						rx_ring->rx_buf_len);
+					if (rx_ring->rx_buf_len
+						< IXGBE_RXBUFFER_2048)
+						hexdump(
+						  rx_buffer_info->page_dma +
+						  rx_buffer_info->page_offset,
+						  PAGE_SIZE/2);
+				}
+			}
+
+			if (i == rx_ring->next_to_use)
+				printk(" NTU\n");
+			else if (i == rx_ring->next_to_clean)
+				printk(" NTC\n");
+			else
+				printk("\n");
+
+		}
+	}
+
+exit:
+	return;
+}
+
 static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
 {
 	u32 ctrl_ext;
@@ -3162,6 +3597,7 @@ static void ixgbe_reset_task(struct work

 	adapter->tx_timeout_count++;

+	ixgbe_dump(adapter);
 	ixgbe_reinit_locked(adapter);
 }




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] e1000e: add registers etc. printout code just before resetting adapters
  2010-01-07 11:01 ` [PATCH 1/3] e1000e: " Taku Izumi
@ 2010-01-07 19:00   ` Laurent Chavey
  0 siblings, 0 replies; 9+ messages in thread
From: Laurent Chavey @ 2010-01-07 19:00 UTC (permalink / raw)
  To: Taku Izumi
  Cc: netdev, Bruce Allan, David S. Miller, Jesse Brandeburg,
	John Ronciak, Kirsher, Jeffrey T, PJ Waskiewicz, Koki Sanagi,
	Kenji Kaneshige

can the call to e1000e_dump(adapter) be
set at runtime / compile time  to only be call
when in debug mode (however debug mode is
defined).

why not add all the new registers
+#define E1000_RDFH     0x02410 etc...
to e1000_hw.h



2010/1/7 Taku Izumi <izumi.taku@jp.fujitsu.com>:
>
> 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.
>
> The default output is netdevice status (transstart, last_rx), registers,
> and tx/rx rings' simple information. TX/RX descriptors information and
> buffer_info  can be output by changing the dump_flag module option, but,
> of course, the amount of output becomes quite large.
>
> Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
> Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
> ---
>  drivers/net/e1000e/netdev.c |  386 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 386 insertions(+)
> Index: net-next-2.6/drivers/net/e1000e/netdev.c
> ===================================================================
> --- net-next-2.6.orig/drivers/net/e1000e/netdev.c
> +++ net-next-2.6/drivers/net/e1000e/netdev.c
> @@ -52,6 +52,14 @@
>  char e1000e_driver_name[] = "e1000e";
>  const char e1000e_driver_version[] = DRV_VERSION;
>
> +static unsigned int dump_flag = 1;
> +module_param(dump_flag, uint, 0644);
> +MODULE_PARM_DESC(dump_flag, "Dump Flag");
> +#define E1000_DUMP_REGS                (1 << 0)
> +#define E1000_DUMP_TX_RINGS    (1 << 1)
> +#define E1000_DUMP_RX_RINGS    (1 << 2)
> +#define E1000_DUMP_BUFFERS     (1 << 3)
> +
>  static const struct e1000_info *e1000_info_tbl[] = {
>        [board_82571]           = &e1000_82571_info,
>        [board_82572]           = &e1000_82572_info,
> @@ -65,6 +73,383 @@ static const struct e1000_info *e1000_in
>        [board_pchlan]          = &e1000_pch_info,
>  };
>
> +static void hexdump(dma_addr_t dma, u16 len)
> +{
> +       uint16_t offset, i;
> +       char str[80], byte[4];
> +       void *va = phys_to_virt((unsigned long)dma);
> +
> +       printk(KERN_ERR "buffer at %016llX (%d)\n", (u64)dma, len);
> +       for (offset = 0; offset < len; offset += 16) {
> +               sprintf(str, "%04x: ", offset);
> +               for (i = 0; i < 16; i++) {
> +                       if ((offset + i) < len)
> +                               sprintf(byte, "%02x ",
> +                               ((unsigned char *)va)[offset + i]);
> +                       else
> +                               strcpy(byte, "   ");
> +                       strcat(str, byte);
> +               }
> +               printk(KERN_ERR "%s\n", str);
> +       }
> +}
> +
> +/*
> + * 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;
> +       u32 reg;
> +       char rname[16];
> +       int n = 0;
> +       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;
> +
> +       /* Print netdevice Info */
> +       if (netdev) {
> +               dev_err(&adapter->pdev->dev, "Net device Info\n");
> +               printk(KERN_ERR "Device Name     state            "
> +                       "trans_start      last_rx\n");
> +               printk(KERN_ERR "%-15s %016lX %016lX %016lX\n",
> +                       netdev->name,
> +                       netdev->state,
> +                       netdev->trans_start,
> +                       netdev->last_rx);
> +       }
> +
> +       /* Print Registers */
> +       if ((dump_flag & E1000_DUMP_REGS) == 0)
> +               goto tx_ring_summary;
> +
> +       dev_err(&adapter->pdev->dev, "Register Dump\n");
> +
> +#define E1000_RDFH     0x02410
> +#define E1000_RDFT     0x02418
> +#define E1000_RDFHS    0x02420
> +#define E1000_RDFTS    0x02428
> +#define E1000_RDFPC    0x02430
> +
> +#define E1000_TDFH     0x03410
> +#define E1000_TDFT     0x03418
> +#define E1000_TDFHS    0x03420
> +#define E1000_TDFTS    0x03428
> +#define E1000_TDFPC    0x03430
> +
> +       printk(KERN_ERR " Register Name   [value ]\n");
> +       for (reg = 0; reg < 0x04000; reg += sizeof(u32)) {
> +               switch (reg & 0xffffffff) {
> +
> +               /* General Registers */
> +               case E1000_CTRL:
> +                       sprintf(rname, "CTRL"); break;
> +               case E1000_STATUS:
> +                       sprintf(rname, "STATUS"); break;
> +               case E1000_CTRL_EXT:
> +                       sprintf(rname, "CTRL_EXT"); break;
> +
> +               /* Interrupt Registers*/
> +               case E1000_ICR:
> +                       sprintf(rname, "ICR"); break;
> +
> +               /* RX */
> +               case E1000_RCTL:
> +                       sprintf(rname, "RCTL"); break;
> +               case E1000_RDLEN:
> +                       sprintf(rname, "RDLEN"); break;
> +               case E1000_RDH:
> +                       sprintf(rname, "RDH"); break;
> +               case E1000_RDT:
> +                       sprintf(rname, "RDT"); break;
> +               case E1000_RDTR:
> +                       sprintf(rname, "RDTR"); break;
> +               case E1000_RXDCTL(0):
> +                       sprintf(rname, "RXDCTL[0]"); break;
> +               case E1000_ERT:
> +                       sprintf(rname, "ERT"); break;
> +               case E1000_RDBAL:
> +                       sprintf(rname, "RDBAL"); break;
> +               case E1000_RDBAH:
> +                       sprintf(rname, "RDBAH"); break;
> +               case E1000_RDFH:
> +                       sprintf(rname, "RDFH"); break;
> +               case E1000_RDFT:
> +                       sprintf(rname, "RDFT"); break;
> +               case E1000_RDFHS:
> +                       sprintf(rname, "RDFHS"); break;
> +               case E1000_RDFTS:
> +                       sprintf(rname, "RDFTS"); break;
> +               case E1000_RDFPC:
> +                       sprintf(rname, "RDFPC"); break;
> +
> +               /* TX */
> +               case E1000_TCTL:
> +                       sprintf(rname, "TCTL"); break;
> +               case E1000_TDBAL:
> +                       sprintf(rname, "TDBAL"); break;
> +               case E1000_TDBAH:
> +                       sprintf(rname, "TDBAH"); break;
> +               case E1000_TDLEN:
> +                       sprintf(rname, "TDLEN"); break;
> +               case E1000_TDH:
> +                       sprintf(rname, "TDH"); break;
> +               case E1000_TDT:
> +                       sprintf(rname, "TDT"); break;
> +               case E1000_TIDV:
> +                       sprintf(rname, "TIDV"); break;
> +               case E1000_TXDCTL(0):
> +                       sprintf(rname, "TXDCTL[0-1]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 2; n++)
> +                               printk("%08x ", readl(hw->hw_addr +
> +                                                       (reg & 0xffffffff)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_TADV:
> +                       sprintf(rname, "TADV"); break;
> +               case E1000_TARC(0):
> +                       sprintf(rname, "TARC[0-1]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 2; n++)
> +                               printk("%08x ", readl(hw->hw_addr +
> +                                                       (reg & 0xffffffff)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_TDFH:
> +                       sprintf(rname, "TDFH"); break;
> +               case E1000_TDFT:
> +                       sprintf(rname, "TDFT"); break;
> +               case E1000_TDFHS:
> +                       sprintf(rname, "TDFHS"); break;
> +               case E1000_TDFTS:
> +                       sprintf(rname, "TDFTS"); break;
> +               case E1000_TDFPC:
> +                       sprintf(rname, "TDFPC"); break;
> +
> +               default:
> +                       continue;
> +               }
> +               printk(KERN_ERR "%-15s %08x\n", rname,
> +                       readl(hw->hw_addr + (reg & 0xffffffff)));
> +       }
> +
> +       /* Print TX Ring Summary */
> +tx_ring_summary:
> +       if (!netdev || !netif_running(netdev))
> +               goto exit;
> +
> +       dev_err(&adapter->pdev->dev, "TX Rings Summary\n");
> +       printk(KERN_ERR "Queue [NTU] [NTC] [bi(ntc)->dma  ]"
> +               " leng ntw timestamp\n");
> +       buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
> +       printk(KERN_ERR " %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 ((dump_flag & E1000_DUMP_TX_RINGS) == 0)
> +               goto rx_ring_summary;
> +
> +       dev_err(&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_ERR "Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen]"
> +               " [bi->dma       ] leng  ntw timestamp        bi->skb "
> +               "<-- Legacy format\n");
> +       printk(KERN_ERR "Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen]"
> +               " [bi->dma       ] leng  ntw timestamp        bi->skb "
> +               "<-- Ext Context format\n");
> +       printk(KERN_ERR "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_ERR "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(" NTC/U\n");
> +               else if (i == tx_ring->next_to_use)
> +                       printk(" NTU\n");
> +               else if (i == tx_ring->next_to_clean)
> +                       printk(" NTC\n");
> +               else
> +                       printk("\n");
> +
> +               if ((dump_flag & E1000_DUMP_BUFFERS) && buffer_info->dma != 0)
> +                       hexdump(buffer_info->dma, buffer_info->length);
> +       }
> +
> +       /* Print RX Rings Summary */
> +rx_ring_summary:
> +       dev_err(&adapter->pdev->dev, "RX Rings Summary\n");
> +       printk(KERN_ERR "Queue [NTU] [NTC]\n");
> +       printk(KERN_ERR " %5d %5X %5X\n", 0,
> +               rx_ring->next_to_use, rx_ring->next_to_clean);
> +
> +       /* Print RX Rings */
> +       if ((dump_flag & E1000_DUMP_RX_RINGS) == 0)
> +               goto exit;
> +
> +       dev_err(&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_ERR "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_ERR "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_ERR "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_ERR "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 (dump_flag & E1000_DUMP_BUFFERS)
> +                                       hexdump(buffer_info->dma,
> +                                               adapter->rx_ps_bsize0);
> +                       }
> +
> +                       if (i == rx_ring->next_to_use)
> +                               printk(" NTU\n");
> +                       else if (i == rx_ring->next_to_clean)
> +                               printk(" NTC\n");
> +                       else
> +                               printk("\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_ERR "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_ERR "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(" NTU\n");
> +                       else if (i == rx_ring->next_to_clean)
> +                               printk(" NTC\n");
> +                       else
> +                               printk("\n");
> +
> +                       if (dump_flag & E1000_DUMP_BUFFERS)
> +                               hexdump(buffer_info->dma,
> +                                       adapter->rx_buffer_len);
> +               }
> +       }
> +
> +exit:
> +       return;
> +}
> +
>  /**
>  * e1000_desc_unused - calculate if we have unused descriptors
>  **/
> @@ -4257,6 +4642,7 @@ static void e1000_reset_task(struct work
>        struct e1000_adapter *adapter;
>        adapter = container_of(work, struct e1000_adapter, reset_task);
>
> +       e1000e_dump(adapter);
>        e1000e_reinit_locked(adapter);
>  }
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] igb: add registers etc. printout code just before resetting adapters
  2010-01-07 11:01 ` [PATCH 2/3] igb: " Taku Izumi
@ 2010-01-07 19:16   ` Laurent Chavey
  2010-01-08 10:33     ` Taku Izumi
  0 siblings, 1 reply; 9+ messages in thread
From: Laurent Chavey @ 2010-01-07 19:16 UTC (permalink / raw)
  To: Taku Izumi
  Cc: netdev, Bruce Allan, David S. Miller, Jesse Brandeburg,
	John Ronciak, Kirsher, Jeffrey T, PJ Waskiewicz, Koki Sanagi,
	Kenji Kaneshige

since hexdump() is already in patch 1/3, could this be moved
to lib/hexdump.c (or could the code make use of hex_dump_to_buffer())

same comment as for patch1/3 for the call to igb_dump()
[use of dump_flag] I can see how it the flag is use thru out the
call but did not see how it prevents the  logging of netdev
info.

it looks like the code in each of the case statement is identical
except for some naming. Could this be converted to
a data driven table (register definition, type, dump routine.)
The later may actually be leveraged across drivers and
use full to implement some semi standard debug dump
reg tool.


2010/1/7 Taku Izumi <izumi.taku@jp.fujitsu.com>:
>
> 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.
>
> The default output is netdevice status (transstart, last_rx), registers,
> and tx/rx rings' simple information. TX/RX descriptors information and
> buffer_info  can be output by changing the dump_flag module option, but,
> of course, the amount of output becomes quite large.
>
> Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
> Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
> ---
>  drivers/net/igb/igb_main.c |  360 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 360 insertions(+)
>
> Index: net-next-2.6/drivers/net/igb/igb_main.c
> ===================================================================
> --- net-next-2.6.orig/drivers/net/igb/igb_main.c
> +++ net-next-2.6/drivers/net/igb/igb_main.c
> @@ -60,6 +60,14 @@ static const struct e1000_info *igb_info
>        [board_82575] = &e1000_82575_info,
>  };
>
> +static unsigned int dump_flag = 1;
> +module_param(dump_flag, uint, 0644);
> +MODULE_PARM_DESC(dump_flag, "Dump Flag");
> +#define IGB_DUMP_REGS          (1 << 0)
> +#define IGB_DUMP_TX_RINGS      (1 << 1)
> +#define IGB_DUMP_RX_RINGS      (1 << 2)
> +#define IGB_DUMP_BUFFERS       (1 << 3)
> +
>  static struct pci_device_id igb_pci_tbl[] = {
>        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER), board_82575 },
>        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_FIBER), board_82575 },
> @@ -189,6 +197,357 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Eth
>  MODULE_LICENSE("GPL");
>  MODULE_VERSION(DRV_VERSION);
>
> +static void hexdump(dma_addr_t dma, u16 len)
> +{
> +       uint16_t offset, i;
> +       char str[80], byte[4];
> +       void *va = phys_to_virt((unsigned long)dma);
> +
> +       printk(KERN_ERR "buffer at %016llX (%d)\n", (u64)dma, len);
> +       for (offset = 0; offset < len; offset += 16) {
> +               sprintf(str, "%04x: ", offset);
> +               for (i = 0; i < 16; i++) {
> +                       if ((offset + i) < len)
> +                               sprintf(byte, "%02x ",
> +                               ((unsigned char *)va)[offset + i]);
> +                       else
> +                               strcpy(byte, "   ");
> +                       strcat(str, byte);
> +               }
> +               printk(KERN_ERR "%s\n", str);
> +       }
> +}
> +
> +/*
> + * igb_dump - Print registers, tx-rings and rx-rings
> + */
> +static void igb_dump(struct igb_adapter *adapter)
> +{
> +       struct net_device *netdev = adapter->netdev;
> +       struct e1000_hw *hw = &adapter->hw;
> +       u32 reg;
> +       char rname[16];
> +       int n = 0;
> +       struct igb_ring *tx_ring;
> +       union e1000_adv_tx_desc *tx_desc;
> +       struct my_u0 { u64 a; u64 b; } *u0;
> +       struct igb_buffer *buffer_info;
> +       struct igb_ring *rx_ring;
> +       union e1000_adv_rx_desc *rx_desc;
> +       u32 staterr;
> +       int i = 0;
> +
> +       /* Print netdevice Info */
> +       if (netdev) {
> +               dev_err(&adapter->pdev->dev, "Net device Info\n");
> +               printk(KERN_ERR "Device Name     state            "
> +                       "trans_start      last_rx\n");
> +               printk(KERN_ERR "%-15s %016lX %016lX %016lX\n",
> +               netdev->name,
> +               netdev->state,
> +               netdev->trans_start,
> +               netdev->last_rx);
> +       }
> +
> +       /* Print Registers */
> +       if ((dump_flag & IGB_DUMP_REGS) == 0)
> +               goto tx_ring_summary;
> +
> +       dev_err(&adapter->pdev->dev, "Register Dump\n");
> +
> +       printk(KERN_ERR " Register Name   [value ]\n");
> +       for (reg = 0; reg < 0x04000; reg += sizeof(u32)) {
> +               switch (reg & 0xffffffff) {
> +               /* General Registers */
> +               case E1000_CTRL:
> +                       sprintf(rname, "CTRL"); break;
> +               case E1000_STATUS:
> +                       sprintf(rname, "STATUS"); break;
> +               case E1000_CTRL_EXT:
> +                       sprintf(rname, "CTRL_EXT"); break;
> +
> +               /* Interrupt Registers*/
> +               case E1000_ICR:
> +                       sprintf(rname, "ICR"); break;
> +
> +               /* RX */
> +               case E1000_RCTL:
> +                       sprintf(rname, "RCTL"); break;
> +               case E1000_RDLEN(0):
> +                       sprintf(rname, "RDLEN[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_RDLEN(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_RDH(0):
> +                       sprintf(rname, "RDH[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_RDH(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_RDT(0):
> +                       sprintf(rname, "RDT[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_RDT(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_RXDCTL(0):
> +                       sprintf(rname, "RXDCTL[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_RXDCTL(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_RDBAL(0):
> +                       sprintf(rname, "RDBAL[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_RDBAL(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_RDBAH(0):
> +                       sprintf(rname, "RDBAH[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_RDBAH(n)));
> +                       printk("\n");
> +                       continue;
> +
> +               /* TX */
> +               case E1000_TCTL:
> +                       sprintf(rname, "TCTL"); break;
> +               case E1000_TDBAL(0):
> +                       sprintf(rname, "TDBAL[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_TDBAL(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_TDBAH(0):
> +                       sprintf(rname, "TDBAH[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_TDBAH(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_TDLEN(0):
> +                       sprintf(rname, "TDLEN[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_TDLEN(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_TDH(0):
> +                       sprintf(rname, "TDH[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_TDH(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_TDT(0):
> +                       sprintf(rname, "TDT[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_TDT(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_TXDCTL(0):
> +                       sprintf(rname, "TXDCTL[0-3]");
> +                       printk(KERN_ERR "%-15s ", rname);
> +                       for (n = 0; n < 4; n++)
> +                               printk("%08x ", rd32(E1000_TXDCTL(n)));
> +                       printk("\n");
> +                       continue;
> +               case E1000_TDFH:
> +                       sprintf(rname, "TDFH"); break;
> +               case E1000_TDFT:
> +                       sprintf(rname, "TDFT"); break;
> +               case E1000_TDFHS:
> +                       sprintf(rname, "TDFHS"); break;
> +               case E1000_TDFPC:
> +                       sprintf(rname, "TDFPC"); break;
> +
> +               default:
> +                       continue;
> +               }
> +
> +               printk(KERN_ERR "%-15s %08x\n", rname,
> +                       rd32((reg & 0xffffffff)));
> +
> +       }
> +
> +       /* Print TX Ring Summary */
> +tx_ring_summary:
> +       if (!netdev || !netif_running(netdev))
> +               goto exit;
> +
> +       dev_err(&adapter->pdev->dev, "TX Rings Summary\n");
> +       printk(KERN_ERR "Queue [NTU] [NTC] [bi(ntc)->dma  ]"
> +               " leng ntw timestamp\n");
> +       for (n = 0; n < adapter->num_tx_queues; n++) {
> +               tx_ring = &adapter->tx_ring[n];
> +               buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
> +               printk(KERN_ERR " %5d %5X %5X %016llX %04X %3X %016llX\n",
> +                          n, 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 ((dump_flag & IGB_DUMP_TX_RINGS) == 0)
> +               goto rx_ring_summary;
> +
> +       dev_err(&adapter->pdev->dev, "TX Rings Dump\n");
> +
> +       /* Transmit Descriptor Formats
> +        *
> +        * Advanced Transmit Descriptor
> +        *   +--------------------------------------------------------------+
> +        * 0 |         Buffer Address [63:0]                                |
> +        *   +--------------------------------------------------------------+
> +        * 8 | PAYLEN  | PORTS  |CC|IDX | STA | DCMD  |DTYP|MAC|RSV| DTALEN |
> +        *   +--------------------------------------------------------------+
> +        *   63      46 45    40 39 38 36 35 32 31   24             15       0
> +        */
> +
> +       for (n = 0; n < adapter->num_tx_queues; n++) {
> +               tx_ring = &adapter->tx_ring[n];
> +               printk(KERN_ERR "------------------------------------\n");
> +               printk(KERN_ERR "TX QUEUE INDEX = %d\n", tx_ring->queue_index);
> +               printk(KERN_ERR "------------------------------------\n");
> +               printk(KERN_ERR "T [desc]     [address 63:0  ] "
> +                       "[PlPOCIStDDM Ln] [bi->dma       ] "
> +                       "leng  ntw timestamp        bi->skb\n");
> +
> +               for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
> +                       tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
> +                       buffer_info = &tx_ring->buffer_info[i];
> +                       u0 = (struct my_u0 *)tx_desc;
> +                       printk(KERN_ERR "T [0x%03X]    %016llX %016llX %016llX"
> +                               " %04X  %3X %016llX %p", 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(" NTC/U\n");
> +                       else if (i == tx_ring->next_to_use)
> +                               printk(" NTU\n");
> +                       else if (i == tx_ring->next_to_clean)
> +                               printk(" NTC\n");
> +                       else
> +                               printk("\n");
> +
> +                       if ((dump_flag & IGB_DUMP_BUFFERS) &&
> +                               buffer_info->dma != 0)
> +                               hexdump(buffer_info->dma, buffer_info->length);
> +               }
> +       }
> +
> +       /* Print RX Rings Summary */
> +rx_ring_summary:
> +       dev_err(&adapter->pdev->dev, "RX Rings Summary\n");
> +       printk(KERN_ERR "Queue [NTU] [NTC]\n");
> +       for (n = 0; n < adapter->num_rx_queues; n++) {
> +               rx_ring = &adapter->rx_ring[n];
> +               printk(KERN_ERR " %5d %5X %5X\n", n,
> +                          rx_ring->next_to_use, rx_ring->next_to_clean);
> +       }
> +
> +       /* Print RX Rings */
> +       if ((dump_flag & IGB_DUMP_RX_RINGS) == 0)
> +               goto exit;
> +
> +       dev_err(&adapter->pdev->dev, "RX Rings Dump\n");
> +
> +       /* Advanced Receive Descriptor (Read) Format
> +        *    63                                           1        0
> +        *    +-----------------------------------------------------+
> +        *  0 |       Packet Buffer Address [63:1]           |A0/NSE|
> +        *    +----------------------------------------------+------+
> +        *  8 |       Header Buffer Address [63:1]           |  DD  |
> +        *    +-----------------------------------------------------+
> +        *
> +        *
> +        * Advanced Receive Descriptor (Write-Back) Format
> +        *
> +        *   63       48 47    32 31  30      21 20 17 16   4 3     0
> +        *   +------------------------------------------------------+
> +        * 0 | Packet     IP     |SPH| HDR_LEN   | RSV|Packet|  RSS |
> +        *   | Checksum   Ident  |   |           |    | Type | Type |
> +        *   +------------------------------------------------------+
> +        * 8 | VLAN Tag | Length | Extended Error | Extended Status |
> +        *   +------------------------------------------------------+
> +        *   63       48 47    32 31            20 19               0
> +        */
> +
> +       for (n = 0; n < adapter->num_rx_queues; n++) {
> +               rx_ring = &adapter->rx_ring[n];
> +               printk(KERN_ERR "------------------------------------\n");
> +               printk(KERN_ERR "RX QUEUE INDEX = %d\n", rx_ring->queue_index);
> +               printk(KERN_ERR "------------------------------------\n");
> +               printk(KERN_ERR "R  [desc]      [ PktBuf     A0] "
> +                       "[  HeadBuf   DD] [bi->dma       ] [bi->skb] "
> +                       "<-- Adv Rx Read format\n");
> +               printk(KERN_ERR "RWB[desc]      [PcsmIpSHl PtRs] "
> +                       "[vl er S cks ln] ---------------- [bi->skb] "
> +                       "<-- Adv Rx Write-Back format\n");
> +
> +               for (i = 0; i < rx_ring->count; i++) {
> +                       buffer_info = &rx_ring->buffer_info[i];
> +                       rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
> +                       u0 = (struct my_u0 *)rx_desc;
> +                       staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
> +                       if (staterr & E1000_RXD_STAT_DD) {
> +                               /* Descriptor Done */
> +                               printk(KERN_ERR "RWB[0x%03X]     %016llX "
> +                                       "%016llX ---------------- %p", i,
> +                                       le64_to_cpu(u0->a),
> +                                       le64_to_cpu(u0->b),
> +                                       buffer_info->skb);
> +                       } else {
> +                               printk(KERN_ERR "R  [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 (dump_flag & IGB_DUMP_BUFFERS) {
> +                                       hexdump(buffer_info->dma,
> +                                               rx_ring->rx_buffer_len);
> +                                       if (rx_ring->rx_buffer_len
> +                                               < IGB_RXBUFFER_1024)
> +                                               hexdump(buffer_info->page_dma +
> +                                                buffer_info->page_offset,
> +                                                PAGE_SIZE/2);
> +                               }
> +                       }
> +
> +                       if (i == rx_ring->next_to_use)
> +                               printk(" NTU\n");
> +                       else if (i == rx_ring->next_to_clean)
> +                               printk(" NTC\n");
> +                       else
> +                               printk("\n");
> +
> +               }
> +       }
> +
> +exit:
> +       return;
> +}
> +
> +
>  /**
>  * igb_read_clock - read raw cycle counter (to be used by time counter)
>  */
> @@ -3859,6 +4218,7 @@ static void igb_reset_task(struct work_s
>        struct igb_adapter *adapter;
>        adapter = container_of(work, struct igb_adapter, reset_task);
>
> +       igb_dump(adapter);
>        igb_reinit_locked(adapter);
>  }
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] igb: add registers etc. printout code just before resetting adapters
  2010-01-07 19:16   ` Laurent Chavey
@ 2010-01-08 10:33     ` Taku Izumi
  0 siblings, 0 replies; 9+ messages in thread
From: Taku Izumi @ 2010-01-08 10:33 UTC (permalink / raw)
  To: Laurent Chavey
  Cc: netdev, Bruce Allan, David S. Miller, Jesse Brandeburg,
	John Ronciak, Kirsher, Jeffrey T, PJ Waskiewicz, Koki Sanagi,
	Kenji Kaneshige


(2010/01/08 4:16), Laurent Chavey wrote:
> since hexdump() is already in patch 1/3, could this be moved
> to lib/hexdump.c (or could the code make use of hex_dump_to_buffer())
> 
> same comment as for patch1/3 for the call to igb_dump()
> [use of dump_flag] I can see how it the flag is use thru out the
> call but did not see how it prevents the  logging of netdev
> info.
> 
> it looks like the code in each of the case statement is identical
> except for some naming. Could this be converted to
> a data driven table (register definition, type, dump routine.)
> The later may actually be leveraged across drivers and
> use full to implement some semi standard debug dump
> reg tool.

 Thank you for your useful comment. I'll reflect your comment and
 improve later.


Best regards,
Taku Izumi


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/3] ixgbe: add registers etc. printout code just before resetting adapters
  2010-01-07 11:02 ` [PATCH 3/3] ixgbe: " Taku Izumi
@ 2010-01-11 21:28   ` Jesse Brandeburg
  0 siblings, 0 replies; 9+ messages in thread
From: Jesse Brandeburg @ 2010-01-11 21:28 UTC (permalink / raw)
  To: Taku Izumi
  Cc: netdev@vger.kernel.org, Allan, Bruce W, David S. Miller,
	Ronciak, John, Kirsher, Jeffrey T, Waskiewicz Jr, Peter P,
	Koki Sanagi, Kenji Kaneshige

On Thu, 2010-01-07 at 03:02 -0800, Taku Izumi wrote:
> 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.
> 
> The default output is netdevice status (transstart, last_rx), registers,
> and tx/rx rings' simple information. TX/RX descriptors information and
> buffer_info  can be output by changing the dump_flag module option, but,
> of course, the amount of output becomes quite large.
> 
> Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
> Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
> ---
>  drivers/net/ixgbe/ixgbe_main.c |  436 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 436 insertions(+)
> 
> Index: net-next-2.6/drivers/net/ixgbe/ixgbe_main.c
> ===================================================================
> --- net-next-2.6.orig/drivers/net/ixgbe/ixgbe_main.c
> +++ net-next-2.6/drivers/net/ixgbe/ixgbe_main.c
> @@ -59,6 +59,15 @@ static const struct ixgbe_info *ixgbe_in
>         [board_82599] = &ixgbe_82599_info,
>  };
> 
> +
> +static unsigned int dump_flag = 1;

dump flag should default to 0.

> +module_param(dump_flag, uint, 0644);
> +MODULE_PARM_DESC(dump_flag, "Dump Flag");
> +#define IXGBE_DUMP_REGS                (1 << 0)
> +#define IXGBE_DUMP_TX_RINGS    (1 << 1)
> +#define IXGBE_DUMP_RX_RINGS    (1 << 2)
> +#define IXGBE_DUMP_BUFFERS     (1 << 3)
> +
>  /* ixgbe_pci_tbl - PCI Device ID Table
>   *
>   * Wildcard entries (PCI_ANY_ID) should come last
> @@ -131,6 +140,432 @@ MODULE_VERSION(DRV_VERSION);
> 
>  #define DEFAULT_DEBUG_LEVEL_SHIFT 3
> 
> +static void hexdump(dma_addr_t dma, u16 len)
> +{
> +       uint16_t offset, i;
> +       char str[80], byte[4];
> +       void *va = phys_to_virt((unsigned long)dma);
> +
> +       printk(KERN_ERR "buffer at %016llX (%d)\n", (u64)dma, len);
> +       for (offset = 0; offset < len; offset += 16) {
> +               sprintf(str, "%04x: ", offset);
> +               for (i = 0; i < 16; i++) {
> +                       if ((offset + i) < len)
> +                               sprintf(byte, "%02x ",
> +                                       ((unsigned char *)va)[offset + i]);
> +                       else
> +                               strcpy(byte, "   ");
> +                       strcat(str, byte);
> +               }
> +               printk(KERN_ERR "%s\n", str);
> +       }
> +}

There is probably a global version of this in the kernel already.

> +
> +/*
> + * ixgbe_dump - Print registers, tx-rings and rx-rings
> + */
> +static void ixgbe_dump(struct ixgbe_adapter *adapter)
> +{
> +       struct net_device *netdev = adapter->netdev;
> +       struct ixgbe_hw *hw = &adapter->hw;
> +
> +       u32 reg;
> +       char rname[32];
> +       int n = 0;
> +       int j = 0;
> +       struct ixgbe_ring *tx_ring;
> +       struct ixgbe_tx_buffer *tx_buffer_info;
> +       union ixgbe_adv_tx_desc *tx_desc;
> +       struct my_u0 { u64 a; u64 b; } *u0;
> +       struct ixgbe_ring *rx_ring;
> +       union ixgbe_adv_rx_desc *rx_desc;
> +       struct ixgbe_rx_buffer *rx_buffer_info;
> +       u32 staterr;
> +       int i = 0;
> +
> +       /* Print netdevice Info */
> +       dev_err(&adapter->pdev->dev, "Net device Info\n");
> +       if (netdev) {
> +               printk(KERN_ERR "Device Name     state            "
> +                       "trans_start      last_rx\n");
> +               printk(KERN_ERR "%-15s %016lX %016lX %016lX\n",
> +               netdev->name,
> +               netdev->state,
> +               netdev->trans_start,
> +               netdev->last_rx);
> +       }
> +
> +       /* Print Registers */
> +       if ((dump_flag & IXGBE_DUMP_REGS) == 0)
> +               goto tx_ring_summary;
> +
> +       dev_err(&adapter->pdev->dev, "Register Dump\n");
> +
> +       printk(KERN_ERR " Register Name   [value ]\n");
> +       for (reg = 0; reg < 0x07000; reg += sizeof(u32)) {
> +               switch (reg & 0xffffffff) {
> +               /* General Registers */
> +               case IXGBE_CTRL:
> +                       sprintf(rname, "CTRL"); break;
> +               case IXGBE_STATUS:
> +                       sprintf(rname, "STATUS"); break;
> +               case IXGBE_CTRL_EXT:
> +                       sprintf(rname, "CTRL_EXT"); break;
> +
> +               /* Interrupt Registers*/
> +               case IXGBE_EICR:
> +                       sprintf(rname, "EICR"); break;
> +
> +               /* RX */
> +               case IXGBE_SRRCTL(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "SRRCTL[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_SRRCTL(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_DCA_RXCTRL(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "DRXCTRL[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_DCA_RXCTRL(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_RDLEN(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "RDLEN[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_RDLEN(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_RDH(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "RDH[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_RDH(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_RDT(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "RDT[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_RDT(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_RXDCTL(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "RXDCTL[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_RXDCTL(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_RDBAL(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "RDBAL[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_RDBAL(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_RDBAH(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "RDBAH[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_RDBAH(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +
> +               /* TX */
> +               case IXGBE_TDBAL(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "TDBAL[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_TDBAL(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_TDBAH(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "TDBAH[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_TDBAH(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_TDLEN(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "TDLEN[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_TDLEN(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_TDH(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "TDH[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_TDH(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_TDT(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "TDT[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_TDT(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +               case IXGBE_TXDCTL(0):
> +                       for (i = 0; i < 8; i++) {
> +                               sprintf(rname, "TXDCTL[%d-%d]",
> +                                       i*8, i*8+7);
> +                               printk(KERN_ERR "%-15s ", rname);
> +                               for (j = 0; j < 8; j++)
> +                                       printk("%08x ",
> +                                               IXGBE_READ_REG(hw,
> +                                                 IXGBE_TXDCTL(i*8+j)));
> +                               printk("\n");
> +                       }
> +                       continue;
> +
> +               default:
> +                       continue;
> +               }
> +
> +               printk(KERN_ERR "%-15s %08x\n", rname,
> +                       IXGBE_READ_REG(hw, (reg & 0xffffffff)));
> +       }
> +
> +       /* Print TX Ring Summary */
> +tx_ring_summary:
> +       if (!netdev || !netif_running(netdev))
> +               goto exit;
> +
> +       dev_err(&adapter->pdev->dev, "TX Rings Summary\n");
> +       printk(KERN_ERR "Queue [NTU] [NTC] [bi(ntc)->dma  ] "
> +               "leng ntw timestamp\n");
> +       for (n = 0; n < adapter->num_tx_queues; n++) {
> +               tx_ring = &adapter->tx_ring[n];
> +               tx_buffer_info =
> +                       &tx_ring->tx_buffer_info[tx_ring->next_to_clean];
> +               printk(KERN_ERR " %5d %5X %5X %016llX %04X %3X %016llX\n",
> +                          n, tx_ring->next_to_use, tx_ring->next_to_clean,
> +                          (u64)tx_buffer_info->dma,
> +                          tx_buffer_info->length,
> +                          tx_buffer_info->next_to_watch,
> +                          (u64)tx_buffer_info->time_stamp);
> +       }
> +
> +       /* Print TX Rings */
> +       if ((dump_flag & IXGBE_DUMP_TX_RINGS) == 0)
> +               goto rx_ring_summary;
> +
> +       dev_err(&adapter->pdev->dev, "TX Rings Dump\n");
> +
> +       /* Transmit Descriptor Formats
> +        *
> +        * Advanced Transmit Descriptor
> +        *   +--------------------------------------------------------------+
> +        * 0 |         Buffer Address [63:0]                                |
> +        *   +--------------------------------------------------------------+
> +        * 8 |  PAYLEN  | PORTS  | IDX | STA | DCMD  |DTYP |  RSV |  DTALEN |
> +        *   +--------------------------------------------------------------+
> +        *   63       46 45    40 39 36 35 32 31   24 23 20 19              0
> +        */
> +
> +       for (n = 0; n < adapter->num_tx_queues; n++) {
> +               tx_ring = &adapter->tx_ring[n];
> +               printk(KERN_ERR "------------------------------------\n");
> +               printk(KERN_ERR "TX QUEUE INDEX = %d\n", tx_ring->queue_index);
> +               printk(KERN_ERR "------------------------------------\n");
> +               printk(KERN_ERR "T [desc]     [address 63:0  ] "
> +                       "[PlPOIdStDDt Ln] [bi->dma       ] "
> +                       "leng  ntw timestamp        bi->skb\n");
> +
> +               for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
> +                       tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
> +                       tx_buffer_info = &tx_ring->tx_buffer_info[i];
> +                       u0 = (struct my_u0 *)tx_desc;
> +                       printk(KERN_ERR "T [0x%03X]    %016llX %016llX %016llX"
> +                               " %04X  %3X %016llX %p", i,
> +                               le64_to_cpu(u0->a),
> +                               le64_to_cpu(u0->b),
> +                               (u64)tx_buffer_info->dma,
> +                               tx_buffer_info->length,
> +                               tx_buffer_info->next_to_watch,
> +                               (u64)tx_buffer_info->time_stamp,
> +                               tx_buffer_info->skb);
> +                       if (i == tx_ring->next_to_use &&
> +                               i == tx_ring->next_to_clean)
> +                               printk(" NTC/U\n");
> +                       else if (i == tx_ring->next_to_use)
> +                               printk(" NTU\n");
> +                       else if (i == tx_ring->next_to_clean)
> +                               printk(" NTC\n");
> +                       else
> +                               printk("\n");
> +
> +                       if ((dump_flag & IXGBE_DUMP_BUFFERS) &&
> +                               tx_buffer_info->dma != 0)
> +                               hexdump(tx_buffer_info->dma,
> +                                       tx_buffer_info->length);
> +               }
> +       }
> +
> +       /* Print RX Rings Summary */
> +rx_ring_summary:
> +       dev_err(&adapter->pdev->dev, "RX Rings Summary\n");
> +       printk(KERN_ERR "Queue [NTU] [NTC]\n");
> +       for (n = 0; n < adapter->num_rx_queues; n++) {
> +               rx_ring = &adapter->rx_ring[n];
> +               printk(KERN_ERR "%5d %5X %5X\n", n,
> +                          rx_ring->next_to_use, rx_ring->next_to_clean);
> +       }
> +
> +       /* Print RX Rings */
> +       if ((dump_flag & IXGBE_DUMP_RX_RINGS) == 0)
> +               goto exit;
> +
> +       dev_err(&adapter->pdev->dev, "RX Rings Dump\n");
> +
> +       /* Advanced Receive Descriptor (Read) Format
> +        *    63                                           1        0
> +        *    +-----------------------------------------------------+
> +        *  0 |       Packet Buffer Address [63:1]           |A0/NSE|
> +        *    +----------------------------------------------+------+
> +        *  8 |       Header Buffer Address [63:1]           |  DD  |
> +        *    +-----------------------------------------------------+
> +        *
> +        *
> +        * Advanced Receive Descriptor (Write-Back) Format
> +        *
> +        *   63       48 47    32 31  30      21 20 16 15   4 3     0
> +        *   +------------------------------------------------------+
> +        * 0 | Packet     IP     |SPH| HDR_LEN   | RSV|Packet|  RSS |
> +        *   | Checksum   Ident  |   |           |    | Type | Type |
> +        *   +------------------------------------------------------+
> +        * 8 | VLAN Tag | Length | Extended Error | Extended Status |
> +        *   +------------------------------------------------------+
> +        *   63       48 47    32 31            20 19               0
> +        */
> +       for (n = 0; n < adapter->num_rx_queues; n++) {
> +               rx_ring = &adapter->rx_ring[n];
> +               printk(KERN_ERR "------------------------------------\n");
> +               printk(KERN_ERR "RX QUEUE INDEX = %d\n", rx_ring->queue_index);
> +               printk(KERN_ERR "------------------------------------\n");
> +               printk(KERN_ERR "R  [desc]      [ PktBuf     A0] "
> +                       "[  HeadBuf   DD] [bi->dma       ] [bi->skb] "
> +                       "<-- Adv Rx Read format\n");
> +               printk(KERN_ERR "RWB[desc]      [PcsmIpSHl PtRs] "
> +                       "[vl er S cks ln] ---------------- [bi->skb] "
> +                       "<-- Adv Rx Write-Back format\n");
> +
> +               for (i = 0; i < rx_ring->count; i++) {
> +                       rx_buffer_info = &rx_ring->rx_buffer_info[i];
> +                       rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
> +                       u0 = (struct my_u0 *)rx_desc;
> +                       staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
> +                       if (staterr & IXGBE_RXD_STAT_DD) {
> +                               /* Descriptor Done */
> +                               printk(KERN_ERR "RWB[0x%03X]     %016llX "
> +                                       "%016llX ---------------- %p", i,
> +                                       le64_to_cpu(u0->a),
> +                                       le64_to_cpu(u0->b),
> +                                       rx_buffer_info->skb);
> +                       } else {
> +                               printk(KERN_ERR "R  [0x%03X]     %016llX "
> +                                       "%016llX %016llX %p", i,
> +                                       le64_to_cpu(u0->a),
> +                                       le64_to_cpu(u0->b),
> +                                       (u64)rx_buffer_info->dma,
> +                                       rx_buffer_info->skb);
> +
> +                               if (dump_flag & IXGBE_DUMP_BUFFERS) {
> +                                       hexdump(rx_buffer_info->dma,
> +                                               rx_ring->rx_buf_len);
> +                                       if (rx_ring->rx_buf_len
> +                                               < IXGBE_RXBUFFER_2048)
> +                                               hexdump(
> +                                                 rx_buffer_info->page_dma +
> +                                                 rx_buffer_info->page_offset,
> +                                                 PAGE_SIZE/2);
> +                               }
> +                       }
> +
> +                       if (i == rx_ring->next_to_use)
> +                               printk(" NTU\n");
> +                       else if (i == rx_ring->next_to_clean)
> +                               printk(" NTC\n");
> +                       else
> +                               printk("\n");
> +
> +               }
> +       }
> +
> +exit:
> +       return;
> +}
> +
>  static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
>  {
>         u32 ctrl_ext;
> @@ -3162,6 +3597,7 @@ static void ixgbe_reset_task(struct work
> 
>         adapter->tx_timeout_count++;
> 
> +       ixgbe_dump(adapter);
>         ixgbe_reinit_locked(adapter);
>  }
> 
> 
> 


-- 
Jesse Brandeburg
This email sent via Evolution, powered by Linux


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] e1000e,igb,ixgbe: add registers etc. printout code just before resetting adapters
  2010-01-07 10:47 [PATCH 0/3] e1000e,igb,ixgbe: add registers etc. printout code just before resetting adapters Taku Izumi
                   ` (2 preceding siblings ...)
  2010-01-07 11:02 ` [PATCH 3/3] ixgbe: " Taku Izumi
@ 2010-01-11 21:52 ` Jeff Kirsher
  3 siblings, 0 replies; 9+ messages in thread
From: Jeff Kirsher @ 2010-01-11 21:52 UTC (permalink / raw)
  To: Taku Izumi
  Cc: netdev, Bruce Allan, David S. Miller, Jesse Brandeburg,
	John Ronciak, PJ Waskiewicz, Koki Sanagi, Kenji Kaneshige

2010/1/7 Taku Izumi <izumi.taku@jp.fujitsu.com>:
>
> This patchset adds registers etc. printout code just before resetting adapters
> to e1000e, igb, ixgbe modules. The registers, tx/rx rings status, descriptors,
> and buffer info will be helpful for detecting the root cause of adapters reset.
>
> This patchset is based on the following Jesse's debug patch of e1000e module.
>  http://marc.info/?l=linux-netdev&m=121446492912285&w=2
> I think that code is very useful, and should be comitted to upstream.
>
> The main difference between Jesse's patch and mine is as follows:
>  - the function which invokes xxx_dump function. (xxx_clean_tx_irq -> xxx_reset_task)
>  - add the "dump_flag" module option to select category of printout
>
> The default output is netdevice status (transstart, last_rx), registers,
> and tx/rx rings' simple information. TX/RX descriptors information and
> buffer_info  can be output by changing the dump_flag module option, but,
> of course, the amount of output becomes quite large.
>
>  *[PATCH 1/3] e1000e: add registers etc. printout code just before resetting adapters
>  *[PATCH 2/3] igb: add registers etc. printout code just before resetting adapters
>  *[PATCH 3/3] ixgbe: add registers etc. printout code just before resetting adapters
>
> Best regards,
> Taku Izumi <izumi.taku@jp.fujitsu.com>
>

Thanks Taku!  I have added your patches to my queue of patches.  Let
me know you are working on an updated version of these patches based
on Laurent Chavey's comments so that I can suck in your updated
versions of the patches when they become available.

-- 
Cheers,
Jeff

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-01-11 21:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-07 10:47 [PATCH 0/3] e1000e,igb,ixgbe: add registers etc. printout code just before resetting adapters Taku Izumi
2010-01-07 11:01 ` [PATCH 1/3] e1000e: " Taku Izumi
2010-01-07 19:00   ` Laurent Chavey
2010-01-07 11:01 ` [PATCH 2/3] igb: " Taku Izumi
2010-01-07 19:16   ` Laurent Chavey
2010-01-08 10:33     ` Taku Izumi
2010-01-07 11:02 ` [PATCH 3/3] ixgbe: " Taku Izumi
2010-01-11 21:28   ` Jesse Brandeburg
2010-01-11 21:52 ` [PATCH 0/3] e1000e,igb,ixgbe: " Jeff Kirsher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).