netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest
@ 2005-05-26 17:33 Michael Chan
  2005-05-26 17:56 ` [PATCH 2.6.12-rc5 1/9] tg3: Add basic selftest infrastructure Michael Chan
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:33 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

I tried to keep these patches reasonably small. The total added size is
about 5K on i386. Patches will follow.

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

* [PATCH 2.6.12-rc5 1/9] tg3: Add basic selftest infrastructure
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
@ 2005-05-26 17:56 ` Michael Chan
  2005-05-26 17:57 ` [PATCH 2.6.12-rc5 2/9] tg3: Add nvram test Michael Chan
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:56 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 49 bytes --]

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d1.patch --]
[-- Type: text/x-patch, Size: 2107 bytes --]

diff -Nru d0/drivers/net/tg3.c d1/drivers/net/tg3.c
--- d0/drivers/net/tg3.c	2005-05-25 12:57:36.000000000 -0700
+++ d1/drivers/net/tg3.c	2005-05-25 12:58:50.000000000 -0700
@@ -133,6 +133,8 @@
 /* number of ETHTOOL_GSTATS u64's */
 #define TG3_NUM_STATS		(sizeof(struct tg3_ethtool_stats)/sizeof(u64))
 
+#define TG3_NUM_TEST		6
+
 static char version[] __devinitdata =
 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
@@ -316,6 +318,17 @@
 	{ "nic_tx_threshold_hit" }
 };
 
+static struct {
+	const char string[ETH_GSTRING_LEN];
+} ethtool_test_keys[TG3_NUM_TEST] = {
+	{ "nvram test     (online) " },
+	{ "link test      (online) " },
+	{ "register test  (offline)" },
+	{ "memory test    (offline)" },
+	{ "loopback test  (offline)" },
+	{ "interrupt test (offline)" },
+};
+
 static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
 {
 	if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
@@ -7199,12 +7212,20 @@
 	return TG3_NUM_STATS;
 }
 
+static int tg3_get_test_count (struct net_device *dev)
+{
+	return TG3_NUM_TEST;
+}
+
 static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf)
 {
 	switch (stringset) {
 	case ETH_SS_STATS:
 		memcpy(buf, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
 		break;
+	case ETH_SS_TEST:
+		memcpy(buf, &ethtool_test_keys, sizeof(ethtool_test_keys));
+		break;
 	default:
 		WARN_ON(1);	/* we need a WARN() */
 		break;
@@ -7218,6 +7239,11 @@
 	memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats));
 }
 
+static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
+			  u64 *data)
+{
+}
+
 static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	struct mii_ioctl_data *data = if_mii(ifr);
@@ -7331,6 +7357,8 @@
 	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= tg3_set_tso,
 #endif
+	.self_test_count	= tg3_get_test_count,
+	.self_test		= tg3_self_test,
 	.get_strings		= tg3_get_strings,
 	.get_stats_count	= tg3_get_stats_count,
 	.get_ethtool_stats	= tg3_get_ethtool_stats,

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

* [PATCH 2.6.12-rc5 2/9] tg3: Add nvram test
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
  2005-05-26 17:56 ` [PATCH 2.6.12-rc5 1/9] tg3: Add basic selftest infrastructure Michael Chan
@ 2005-05-26 17:57 ` Michael Chan
  2005-05-26 17:57 ` [PATCH 2.6.12-rc5 3/9] tg3: Add link test Michael Chan
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:57 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 49 bytes --]

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d2.patch --]
[-- Type: text/x-patch, Size: 1550 bytes --]

diff -Nru d1/drivers/net/tg3.c d2/drivers/net/tg3.c
--- d1/drivers/net/tg3.c	2005-05-25 12:58:50.000000000 -0700
+++ d2/drivers/net/tg3.c	2005-05-25 12:59:00.000000000 -0700
@@ -7239,9 +7239,59 @@
 	memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats));
 }
 
+#define NVRAM_TEST_SIZE 0x100
+
+static int tg3_test_nvram(struct tg3 *tp)
+{
+	u32 *buf, csum;
+	int i, j, err = 0;
+
+	buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) {
+		u32 val;
+
+		if ((err = tg3_nvram_read(tp, i, &val)) != 0)
+			break;
+		buf[j] = cpu_to_le32(val);
+	}
+	if (i < NVRAM_TEST_SIZE)
+		goto out;
+
+	err = -EIO;
+	if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC)
+		goto out;
+
+	/* Bootstrap checksum at offset 0x10 */
+	csum = calc_crc((unsigned char *) buf, 0x10);
+	if(csum != cpu_to_le32(buf[0x10/4]))
+		goto out;
+
+	/* Manufacturing block starts at offset 0x74, checksum at 0xfc */
+	csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88);
+	if (csum != cpu_to_le32(buf[0xfc/4]))
+		 goto out;
+
+	err = 0;
+
+out:
+	kfree(buf);
+	return err;
+}
+
 static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 			  u64 *data)
 {
+	struct tg3 *tp = netdev_priv(dev);
+
+	memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
+
+	if (tg3_test_nvram(tp) != 0) {
+		etest->flags |= ETH_TEST_FL_FAILED;
+		data[0] = 1;
+	}
 }
 
 static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)

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

* [PATCH 2.6.12-rc5 3/9] tg3: Add link test
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
  2005-05-26 17:56 ` [PATCH 2.6.12-rc5 1/9] tg3: Add basic selftest infrastructure Michael Chan
  2005-05-26 17:57 ` [PATCH 2.6.12-rc5 2/9] tg3: Add nvram test Michael Chan
@ 2005-05-26 17:57 ` Michael Chan
  2005-05-26 17:58 ` [PATCH 2.6.12-rc5 4/9] tg3: Add parameter to tg3_halt Michael Chan
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:57 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 49 bytes --]

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d3.patch --]
[-- Type: text/x-patch, Size: 1068 bytes --]

diff -Nru d2/drivers/net/tg3.c d3/drivers/net/tg3.c
--- d2/drivers/net/tg3.c	2005-05-25 12:59:00.000000000 -0700
+++ d3/drivers/net/tg3.c	2005-05-25 12:59:09.000000000 -0700
@@ -7281,6 +7281,32 @@
 	return err;
 }
 
+#define TG3_SERDES_TIMEOUT_SEC	2
+#define TG3_COPPER_TIMEOUT_SEC	6
+
+static int tg3_test_link(struct tg3 *tp)
+{
+	int i, max;
+
+	if (!netif_running(tp->dev))
+		return -ENODEV;
+
+	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+		max = TG3_SERDES_TIMEOUT_SEC;
+	else
+		max = TG3_COPPER_TIMEOUT_SEC;
+
+	for (i = 0; i < max; i++) {
+		if (netif_carrier_ok(tp->dev))
+			return 0;
+
+		if (msleep_interruptible(1000))
+			break;
+	}
+
+	return -EIO;
+}
+
 static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 			  u64 *data)
 {
@@ -7292,6 +7318,10 @@
 		etest->flags |= ETH_TEST_FL_FAILED;
 		data[0] = 1;
 	}
+	if (tg3_test_link(tp) != 0) {
+		etest->flags |= ETH_TEST_FL_FAILED;
+		data[1] = 1;
+	}
 }
 
 static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)

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

* [PATCH 2.6.12-rc5 4/9] tg3: Add parameter to tg3_halt
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
                   ` (2 preceding siblings ...)
  2005-05-26 17:57 ` [PATCH 2.6.12-rc5 3/9] tg3: Add link test Michael Chan
@ 2005-05-26 17:58 ` Michael Chan
  2005-05-26 17:58 ` [PATCH 2.6.12-rc5 5/9] tg3: Add register test Michael Chan
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:58 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 263 bytes --]

Add a reset kind parameter to tg3_halt() so that the RESET_KIND_SUSPEND
parameter can be passed to tg3_halt() before doing offline tests.

All other calls to tg3_halt() will use the RESET_KIND_SHUTDOWN
parameter.

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d4.patch --]
[-- Type: text/x-patch, Size: 3136 bytes --]

diff -Nru d3/drivers/net/tg3.c d4/drivers/net/tg3.c
--- d3/drivers/net/tg3.c	2005-05-25 12:59:09.000000000 -0700
+++ d4/drivers/net/tg3.c	2005-05-25 12:59:17.000000000 -0700
@@ -3083,7 +3083,7 @@
 }
 
 static int tg3_init_hw(struct tg3 *);
-static int tg3_halt(struct tg3 *, int);
+static int tg3_halt(struct tg3 *, int, int);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void tg3_poll_controller(struct net_device *dev)
@@ -3107,7 +3107,7 @@
 	restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
 	tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
 
-	tg3_halt(tp, 0);
+	tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
 	tg3_init_hw(tp);
 
 	tg3_netif_start(tp);
@@ -3453,7 +3453,7 @@
 	spin_lock_irq(&tp->lock);
 	spin_lock(&tp->tx_lock);
 
-	tg3_halt(tp, 1);
+	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 
 	tg3_set_mtu(dev, tp, new_mtu);
 
@@ -4144,19 +4144,19 @@
 }
 
 /* tp->lock is held. */
-static int tg3_halt(struct tg3 *tp, int silent)
+static int tg3_halt(struct tg3 *tp, int kind, int silent)
 {
 	int err;
 
 	tg3_stop_fw(tp);
 
-	tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN);
+	tg3_write_sig_pre_reset(tp, kind);
 
 	tg3_abort_hw(tp, silent);
 	err = tg3_chip_reset(tp);
 
-	tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN);
-	tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
+	tg3_write_sig_legacy(tp, kind);
+	tg3_write_sig_post_reset(tp, kind);
 
 	if (err)
 		return err;
@@ -5997,7 +5997,7 @@
 	spin_lock_irq(&tp->lock);
 	spin_lock(&tp->tx_lock);
 
-	tg3_halt(tp, 1);
+	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 	err = tg3_init_hw(tp);
 
 	spin_unlock(&tp->tx_lock);
@@ -6073,7 +6073,7 @@
 
 	err = tg3_init_hw(tp);
 	if (err) {
-		tg3_halt(tp, 1);
+		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		tg3_free_rings(tp);
 	} else {
 		if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
@@ -6117,7 +6117,7 @@
 				pci_disable_msi(tp->pdev);
 				tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
 			}
-			tg3_halt(tp, 1);
+			tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 			tg3_free_rings(tp);
 			tg3_free_consistent(tp);
 
@@ -6390,7 +6390,7 @@
 
 	tg3_disable_ints(tp);
 
-	tg3_halt(tp, 1);
+	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 	tg3_free_rings(tp);
 	tp->tg3_flags &=
 		~(TG3_FLAG_INIT_COMPLETE |
@@ -7110,7 +7110,7 @@
 	tp->tx_pending = ering->tx_pending;
 
 	if (netif_running(dev)) {
-		tg3_halt(tp, 1);
+		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		tg3_init_hw(tp);
 		tg3_netif_start(tp);
 	}
@@ -7153,7 +7153,7 @@
 		tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE;
 
 	if (netif_running(dev)) {
-		tg3_halt(tp, 1);
+		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		tg3_init_hw(tp);
 		tg3_netif_start(tp);
 	}
@@ -9586,7 +9586,7 @@
 	    (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
 		pci_save_state(tp->pdev);
 		tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
-		tg3_halt(tp, 1);
+		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 	}
 
 	err = tg3_test_dma(tp);
@@ -9713,7 +9713,7 @@
 
 	spin_lock_irq(&tp->lock);
 	spin_lock(&tp->tx_lock);
-	tg3_halt(tp, 1);
+	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 

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

* [PATCH 2.6.12-rc5 5/9] tg3: Add register test
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
                   ` (3 preceding siblings ...)
  2005-05-26 17:58 ` [PATCH 2.6.12-rc5 4/9] tg3: Add parameter to tg3_halt Michael Chan
@ 2005-05-26 17:58 ` Michael Chan
  2005-05-26 17:58 ` [PATCH 2.6.12-rc5 6/9] tg3: Add memory test Michael Chan
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:58 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 49 bytes --]

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d5.patch --]
[-- Type: text/x-patch, Size: 7840 bytes --]

diff -Nru d4/drivers/net/tg3.c d5/drivers/net/tg3.c
--- d4/drivers/net/tg3.c	2005-05-25 12:59:17.000000000 -0700
+++ d5/drivers/net/tg3.c	2005-05-25 12:59:24.000000000 -0700
@@ -7307,6 +7307,219 @@
 	return -EIO;
 }
 
+/* Only test the commonly used registers */
+static int tg3_test_registers(struct tg3 *tp)
+{
+	int i, is_5705;
+	u32 offset, read_mask, write_mask, val, save_val, read_val;
+	static struct {
+		u16 offset;
+		u16 flags;
+#define TG3_FL_5705	0x1
+#define TG3_FL_NOT_5705	0x2
+#define TG3_FL_NOT_5788	0x4
+		u32 read_mask;
+		u32 write_mask;
+	} reg_tbl[] = {
+		/* MAC Control Registers */
+		{ MAC_MODE, TG3_FL_NOT_5705,
+			0x00000000, 0x00ef6f8c },
+		{ MAC_MODE, TG3_FL_5705,
+			0x00000000, 0x01ef6b8c },
+		{ MAC_STATUS, TG3_FL_NOT_5705,
+			0x03800107, 0x00000000 },
+		{ MAC_STATUS, TG3_FL_5705,
+			0x03800100, 0x00000000 },
+		{ MAC_ADDR_0_HIGH, 0x0000,
+			0x00000000, 0x0000ffff },
+		{ MAC_ADDR_0_LOW, 0x0000,
+		       	0x00000000, 0xffffffff },
+		{ MAC_RX_MTU_SIZE, 0x0000,
+			0x00000000, 0x0000ffff },
+		{ MAC_TX_MODE, 0x0000,
+			0x00000000, 0x00000070 },
+		{ MAC_TX_LENGTHS, 0x0000,
+			0x00000000, 0x00003fff },
+		{ MAC_RX_MODE, TG3_FL_NOT_5705,
+			0x00000000, 0x000007fc },
+		{ MAC_RX_MODE, TG3_FL_5705,
+			0x00000000, 0x000007dc },
+		{ MAC_HASH_REG_0, 0x0000,
+			0x00000000, 0xffffffff },
+		{ MAC_HASH_REG_1, 0x0000,
+			0x00000000, 0xffffffff },
+		{ MAC_HASH_REG_2, 0x0000,
+			0x00000000, 0xffffffff },
+		{ MAC_HASH_REG_3, 0x0000,
+			0x00000000, 0xffffffff },
+
+		/* Receive Data and Receive BD Initiator Control Registers. */
+		{ RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705,
+			0x00000000, 0x00000003 },
+		{ RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ RCVDBDI_STD_BD+0, 0x0000,
+			0x00000000, 0xffffffff },
+		{ RCVDBDI_STD_BD+4, 0x0000,
+			0x00000000, 0xffffffff },
+		{ RCVDBDI_STD_BD+8, 0x0000,
+			0x00000000, 0xffff0002 },
+		{ RCVDBDI_STD_BD+0xc, 0x0000,
+			0x00000000, 0xffffffff },
+	
+		/* Receive BD Initiator Control Registers. */
+		{ RCVBDI_STD_THRESH, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ RCVBDI_STD_THRESH, TG3_FL_5705,
+			0x00000000, 0x000003ff },
+		{ RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+	
+		/* Host Coalescing Control Registers. */
+		{ HOSTCC_MODE, TG3_FL_NOT_5705,
+			0x00000000, 0x00000004 },
+		{ HOSTCC_MODE, TG3_FL_5705,
+			0x00000000, 0x000000f6 },
+		{ HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_RXCOL_TICKS, TG3_FL_5705,
+			0x00000000, 0x000003ff },
+		{ HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_TXCOL_TICKS, TG3_FL_5705,
+			0x00000000, 0x000003ff },
+		{ HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788,
+			0x00000000, 0x000000ff },
+		{ HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788,
+			0x00000000, 0x000000ff },
+		{ HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788,
+			0x00000000, 0x000000ff },
+		{ HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788,
+			0x00000000, 0x000000ff },
+		{ HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000,
+			0x00000000, 0xffffffff },
+		{ HOSTCC_STATS_BLK_NIC_ADDR, 0x0000,
+			0xffffffff, 0x00000000 },
+		{ HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000,
+			0xffffffff, 0x00000000 },
+
+		/* Buffer Manager Control Registers. */
+		{ BUFMGR_MB_POOL_ADDR, 0x0000,
+			0x00000000, 0x007fff80 },
+		{ BUFMGR_MB_POOL_SIZE, 0x0000,
+			0x00000000, 0x007fffff },
+		{ BUFMGR_MB_RDMA_LOW_WATER, 0x0000,
+			0x00000000, 0x0000003f },
+		{ BUFMGR_MB_MACRX_LOW_WATER, 0x0000,
+			0x00000000, 0x000001ff },
+		{ BUFMGR_MB_HIGH_WATER, 0x0000,
+			0x00000000, 0x000001ff },
+		{ BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705,
+			0xffffffff, 0x00000000 },
+		{ BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705,
+			0xffffffff, 0x00000000 },
+	
+		/* Mailbox Registers */
+		{ GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000,
+			0x00000000, 0x000001ff },
+		{ GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705,
+			0x00000000, 0x000001ff },
+		{ GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000,
+			0x00000000, 0x000007ff },
+		{ GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000,
+			0x00000000, 0x000001ff },
+
+		{ 0xffff, 0x0000, 0x00000000, 0x00000000 },
+	};
+
+	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+		is_5705 = 1;
+	else
+		is_5705 = 0;
+
+	for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
+		if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705))
+			continue;
+
+		if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705))
+			continue;
+
+		if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
+		    (reg_tbl[i].flags & TG3_FL_NOT_5788))
+			continue;
+
+		offset = (u32) reg_tbl[i].offset;
+		read_mask = reg_tbl[i].read_mask;
+		write_mask = reg_tbl[i].write_mask;
+
+		/* Save the original register content */
+		save_val = tr32(offset);
+
+		/* Determine the read-only value. */
+		read_val = save_val & read_mask;
+
+		/* Write zero to the register, then make sure the read-only bits
+		 * are not changed and the read/write bits are all zeros.
+		 */
+		tw32(offset, 0);
+
+		val = tr32(offset);
+
+		/* Test the read-only and read/write bits. */
+		if (((val & read_mask) != read_val) || (val & write_mask))
+			goto out;
+
+		/* Write ones to all the bits defined by RdMask and WrMask, then
+		 * make sure the read-only bits are not changed and the
+		 * read/write bits are all ones.
+		 */
+		tw32(offset, read_mask | write_mask);
+
+		val = tr32(offset);
+
+		/* Test the read-only bits. */
+		if ((val & read_mask) != read_val)
+			goto out;
+
+		/* Test the read/write bits. */
+		if ((val & write_mask) != write_mask)
+			goto out;
+
+		tw32(offset, save_val);
+	}
+
+	return 0;
+
+out:
+	printk(KERN_ERR PFX "Register test failed at offset %x\n", offset);
+	tw32(offset, save_val);
+	return -EIO;
+}
+
 static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 			  u64 *data)
 {
@@ -7322,6 +7535,34 @@
 		etest->flags |= ETH_TEST_FL_FAILED;
 		data[1] = 1;
 	}
+	if (etest->flags & ETH_TEST_FL_OFFLINE) {
+		if (netif_running(dev))
+			tg3_netif_stop(tp);
+
+		spin_lock_irq(&tp->lock);
+		spin_lock(&tp->tx_lock);
+
+		tg3_halt(tp, RESET_KIND_SUSPEND, 1);
+		tg3_nvram_lock(tp);
+		tg3_halt_cpu(tp, RX_CPU_BASE);
+		if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+			tg3_halt_cpu(tp, TX_CPU_BASE);
+		tg3_nvram_unlock(tp);
+
+		if (tg3_test_registers(tp) != 0) {
+			etest->flags |= ETH_TEST_FL_FAILED;
+			data[2] = 1;
+		}
+
+		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+		if (netif_running(dev)) {
+			tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+			tg3_init_hw(tp);
+			tg3_netif_start(tp);
+		}
+		spin_unlock(&tp->tx_lock);
+		spin_unlock_irq(&tp->lock);
+	}
 }
 
 static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)

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

* [PATCH 2.6.12-rc5 6/9] tg3: Add memory test
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
                   ` (4 preceding siblings ...)
  2005-05-26 17:58 ` [PATCH 2.6.12-rc5 5/9] tg3: Add register test Michael Chan
@ 2005-05-26 17:58 ` Michael Chan
  2005-05-26 17:59 ` [PATCH 2.6.12-rc5 7/9] tg3: Add loopback test Michael Chan
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:58 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 49 bytes --]

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d6.patch --]
[-- Type: text/x-patch, Size: 1865 bytes --]

diff -Nru d5/drivers/net/tg3.c d6/drivers/net/tg3.c
--- d5/drivers/net/tg3.c	2005-05-25 12:59:24.000000000 -0700
+++ d6/drivers/net/tg3.c	2005-05-25 12:59:31.000000000 -0700
@@ -7520,6 +7520,62 @@
 	return -EIO;
 }
 
+static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len)
+{
+	static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a };
+	int i;
+	u32 j;
+
+	for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) {
+		for (j = 0; j < len; j += 4) {
+			u32 val;
+
+			tg3_write_mem(tp, offset + j, test_pattern[i]);
+			tg3_read_mem(tp, offset + j, &val);
+			if (val != test_pattern[i])
+				return -EIO;
+		}
+	}
+	return 0;
+}
+
+static int tg3_test_memory(struct tg3 *tp)
+{
+	static struct mem_entry {
+		u32 offset;
+		u32 len;
+	} mem_tbl_570x[] = {
+		{ 0x00000000, 0x01000},
+		{ 0x00002000, 0x1c000},
+		{ 0xffffffff, 0x00000}
+	}, mem_tbl_5705[] = {
+		{ 0x00000100, 0x0000c},
+		{ 0x00000200, 0x00008},
+		{ 0x00000b50, 0x00400},
+		{ 0x00004000, 0x00800},
+		{ 0x00006000, 0x01000},
+		{ 0x00008000, 0x02000},
+		{ 0x00010000, 0x0e000},
+		{ 0xffffffff, 0x00000}
+	};
+	struct mem_entry *mem_tbl;
+	int err = 0;
+	int i;
+
+	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+		mem_tbl = mem_tbl_5705;
+	else
+		mem_tbl = mem_tbl_570x;
+
+	for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
+		if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset,
+		    mem_tbl[i].len)) != 0)
+			break;
+	}
+	
+	return err;
+}
+
 static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 			  u64 *data)
 {
@@ -7553,6 +7609,10 @@
 			etest->flags |= ETH_TEST_FL_FAILED;
 			data[2] = 1;
 		}
+		if (tg3_test_memory(tp) != 0) {
+			etest->flags |= ETH_TEST_FL_FAILED;
+			data[3] = 1;
+		}
 
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		if (netif_running(dev)) {

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

* [PATCH 2.6.12-rc5 7/9] tg3: Add loopback test
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
                   ` (5 preceding siblings ...)
  2005-05-26 17:58 ` [PATCH 2.6.12-rc5 6/9] tg3: Add memory test Michael Chan
@ 2005-05-26 17:59 ` Michael Chan
  2005-05-26 17:59 ` [PATCH 2.6.12-rc5 8/9] tg3: Add interrupt test Michael Chan
  2005-05-26 18:00 ` [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu Michael Chan
  8 siblings, 0 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:59 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 133 bytes --]

The test will loopback one packet in MAC loopback mode and verify the
packet data.

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d7.patch --]
[-- Type: text/x-patch, Size: 3431 bytes --]

diff -Nru d6/drivers/net/tg3.c d7/drivers/net/tg3.c
--- d6/drivers/net/tg3.c	2005-05-25 12:59:31.000000000 -0700
+++ d7/drivers/net/tg3.c	2005-05-25 12:59:38.000000000 -0700
@@ -7576,6 +7576,117 @@
 	return err;
 }
 
+static int tg3_test_loopback(struct tg3 *tp)
+{
+	u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key;
+	u32 desc_idx;
+	struct sk_buff *skb, *rx_skb;
+	u8 *tx_data;
+	dma_addr_t map;
+	int num_pkts, tx_len, rx_len, i, err;
+	struct tg3_rx_buffer_desc *desc;
+
+	if (!netif_running(tp->dev))
+		return -ENODEV;
+
+	err = -EIO;
+
+	tg3_abort_hw(tp, 1);
+
+	/* Clearing this flag to keep interrupts disabled */
+	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+	tg3_reset_hw(tp);
+
+	mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
+		   MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY |
+		   MAC_MODE_PORT_MODE_GMII;
+	tw32(MAC_MODE, mac_mode);
+
+	tx_len = 1514;
+	skb = dev_alloc_skb(tx_len);
+	tx_data = skb_put(skb, tx_len);
+	memcpy(tx_data, tp->dev->dev_addr, 6);
+	memset(tx_data + 6, 0x0, 8);
+
+	tw32(MAC_RX_MTU_SIZE, tx_len + 4);
+
+	for (i = 14; i < tx_len; i++)
+		tx_data[i] = (u8) (i & 0xff);
+
+	map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
+
+	tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+	     HOSTCC_MODE_NOW);
+
+	udelay(10);
+
+	rx_start_idx = tp->hw_status->idx[0].rx_producer;
+
+	send_idx = 0;
+	num_pkts = 0;
+
+	tg3_set_txd(tp, send_idx, map, tx_len, 0, 1);
+
+	send_idx++;
+	num_pkts++;
+
+	tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx);
+	tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
+
+	udelay(10);
+
+	for (i = 0; i < 10; i++) {
+		tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+		       HOSTCC_MODE_NOW);
+
+		udelay(10);
+
+		tx_idx = tp->hw_status->idx[0].tx_consumer;
+		rx_idx = tp->hw_status->idx[0].rx_producer;
+		if ((tx_idx == send_idx) &&
+		    (rx_idx == (rx_start_idx + num_pkts)))
+			break;
+	}
+
+	pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE);
+	dev_kfree_skb(skb);
+
+	if (tx_idx != send_idx)
+		goto out;
+
+	if (rx_idx != rx_start_idx + num_pkts)
+		goto out;
+
+	desc = &tp->rx_rcb[rx_start_idx];
+	desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
+	opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
+	if (opaque_key != RXD_OPAQUE_RING_STD)
+		goto out;
+
+	if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
+	    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII))
+		goto out;
+
+	rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4;
+	if (rx_len != tx_len)
+		goto out;
+
+	rx_skb = tp->rx_std_buffers[desc_idx].skb;
+
+	map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping);
+	pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE);
+
+	for (i = 14; i < tx_len; i++) {
+		if (*(rx_skb->data + i) != (u8) (i & 0xff))
+			goto out;
+	}
+	err = 0;
+	
+	/* tg3_free_rings will unmap and free the rx_skb */
+out:
+	return err;
+}
+
 static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 			  u64 *data)
 {
@@ -7613,6 +7724,10 @@
 			etest->flags |= ETH_TEST_FL_FAILED;
 			data[3] = 1;
 		}
+		if (tg3_test_loopback(tp) != 0) {
+			etest->flags |= ETH_TEST_FL_FAILED;
+			data[4] = 1;
+		}
 
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		if (netif_running(dev)) {

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

* [PATCH 2.6.12-rc5 8/9] tg3: Add interrupt test
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
                   ` (6 preceding siblings ...)
  2005-05-26 17:59 ` [PATCH 2.6.12-rc5 7/9] tg3: Add loopback test Michael Chan
@ 2005-05-26 17:59 ` Michael Chan
  2005-05-26 18:00 ` [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu Michael Chan
  8 siblings, 0 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 17:59 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 128 bytes --]

This test uses the previously added tg3_test_interrupt() to perform the
test.

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d8.patch --]
[-- Type: text/x-patch, Size: 749 bytes --]

diff -Nru d7/drivers/net/tg3.c d8/drivers/net/tg3.c
--- d7/drivers/net/tg3.c	2005-05-25 12:59:38.000000000 -0700
+++ d8/drivers/net/tg3.c	2005-05-25 12:59:46.000000000 -0700
@@ -5894,6 +5894,9 @@
 	int err, i;
 	u32 int_mbox = 0;
 
+	if (!netif_running(dev))
+		return -ENODEV;
+
 	tg3_disable_ints(tp);
 
 	free_irq(tp->pdev->irq, dev);
@@ -7729,6 +7732,15 @@
 			data[4] = 1;
 		}
 
+		spin_unlock(&tp->tx_lock);
+		spin_unlock_irq(&tp->lock);
+		if (tg3_test_interrupt(tp) != 0) {
+			etest->flags |= ETH_TEST_FL_FAILED;
+			data[5] = 1;
+		}
+		spin_lock_irq(&tp->lock);
+		spin_lock(&tp->tx_lock);
+
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		if (netif_running(dev)) {
 			tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;

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

* [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu
  2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
                   ` (7 preceding siblings ...)
  2005-05-26 17:59 ` [PATCH 2.6.12-rc5 8/9] tg3: Add interrupt test Michael Chan
@ 2005-05-26 18:00 ` Michael Chan
  2005-05-26 19:13   ` Jeff Garzik
  2005-05-26 22:10   ` David S. Miller
  8 siblings, 2 replies; 12+ messages in thread
From: Michael Chan @ 2005-05-26 18:00 UTC (permalink / raw)
  To: davem; +Cc: jgarzik, netdev

[-- Attachment #1: Type: text/plain, Size: 375 bytes --]

Add tg3_nvram_lock() and tg3_nvram_unlock() calls around tg3_halt_cpu().
It is possible that the bootcode may be loading code from nvram during
this call and stopping the cpu without getting the lock may cause
uncompleted nvram data to be left in the nvram data register. Subsequent
calls to read/write nvram data will fail.

Signed-off-by: Michael Chan <mchan@broadcom.com>

[-- Attachment #2: tg3-d9.patch --]
[-- Type: text/x-patch, Size: 502 bytes --]

diff -Nru d8/drivers/net/tg3.c d9/drivers/net/tg3.c
--- d8/drivers/net/tg3.c	2005-05-25 12:59:46.000000000 -0700
+++ d9/drivers/net/tg3.c	2005-05-25 12:59:55.000000000 -0700
@@ -4370,7 +4370,12 @@
 	 */
 	tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
 
+	/* It is possible that bootcode is still loading at this point.
+	 * Get the nvram lock first before halting the cpu.
+	 */
+	tg3_nvram_lock(tp);
 	err = tg3_halt_cpu(tp, cpu_base);
+	tg3_nvram_unlock(tp);
 	if (err)
 		goto out;
 

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

* Re: [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu
  2005-05-26 18:00 ` [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu Michael Chan
@ 2005-05-26 19:13   ` Jeff Garzik
  2005-05-26 22:10   ` David S. Miller
  1 sibling, 0 replies; 12+ messages in thread
From: Jeff Garzik @ 2005-05-26 19:13 UTC (permalink / raw)
  To: Michael Chan; +Cc: davem, netdev

Michael Chan wrote:
> Add tg3_nvram_lock() and tg3_nvram_unlock() calls around tg3_halt_cpu().
> It is possible that the bootcode may be loading code from nvram during
> this call and stopping the cpu without getting the lock may cause
> uncompleted nvram data to be left in the nvram data register. Subsequent
> calls to read/write nvram data will fail.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

All the patches seem sane to me.

To touch a bit on patch order, I would suggest ordering bug fixes before 
feature patches.  Your patch #9 could have been better ordered as patch #1.

The patch order did not matter today, but sometime in the future, if an 
add-a-feature patch is rejected or delayed, you would still likely want 
DaveM to apply other bugfix patches.

Regards,

	Jeff

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

* Re: [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu
  2005-05-26 18:00 ` [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu Michael Chan
  2005-05-26 19:13   ` Jeff Garzik
@ 2005-05-26 22:10   ` David S. Miller
  1 sibling, 0 replies; 12+ messages in thread
From: David S. Miller @ 2005-05-26 22:10 UTC (permalink / raw)
  To: mchan; +Cc: jgarzik, netdev


All 9 patches applied, thanks Michael.

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

end of thread, other threads:[~2005-05-26 22:10 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-26 17:33 [PATCH 2.6.12-rc5 0/9] tg3: Add ethtool selftest Michael Chan
2005-05-26 17:56 ` [PATCH 2.6.12-rc5 1/9] tg3: Add basic selftest infrastructure Michael Chan
2005-05-26 17:57 ` [PATCH 2.6.12-rc5 2/9] tg3: Add nvram test Michael Chan
2005-05-26 17:57 ` [PATCH 2.6.12-rc5 3/9] tg3: Add link test Michael Chan
2005-05-26 17:58 ` [PATCH 2.6.12-rc5 4/9] tg3: Add parameter to tg3_halt Michael Chan
2005-05-26 17:58 ` [PATCH 2.6.12-rc5 5/9] tg3: Add register test Michael Chan
2005-05-26 17:58 ` [PATCH 2.6.12-rc5 6/9] tg3: Add memory test Michael Chan
2005-05-26 17:59 ` [PATCH 2.6.12-rc5 7/9] tg3: Add loopback test Michael Chan
2005-05-26 17:59 ` [PATCH 2.6.12-rc5 8/9] tg3: Add interrupt test Michael Chan
2005-05-26 18:00 ` [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu Michael Chan
2005-05-26 19:13   ` Jeff Garzik
2005-05-26 22:10   ` David S. Miller

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).