diff options
author | Michael Chan <mchan@broadcom.com> | 2005-05-29 17:58:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-05-29 17:58:11 -0400 |
commit | a71116d1f3b85a69fe3a3acec9223fefb4b1fc66 (patch) | |
tree | e3d5019a6b3f0eb874f4c9803ea0dc7ba338ae2c /drivers | |
parent | 944d980ecaabe44616a9e2d50101ce774f517bb6 (diff) |
[TG3]: Add register test
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/tg3.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 73f6e962ed5e..4589f8f90119 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -7307,6 +7307,219 @@ static int tg3_test_link(struct tg3 *tp) | |||
7307 | return -EIO; | 7307 | return -EIO; |
7308 | } | 7308 | } |
7309 | 7309 | ||
7310 | /* Only test the commonly used registers */ | ||
7311 | static int tg3_test_registers(struct tg3 *tp) | ||
7312 | { | ||
7313 | int i, is_5705; | ||
7314 | u32 offset, read_mask, write_mask, val, save_val, read_val; | ||
7315 | static struct { | ||
7316 | u16 offset; | ||
7317 | u16 flags; | ||
7318 | #define TG3_FL_5705 0x1 | ||
7319 | #define TG3_FL_NOT_5705 0x2 | ||
7320 | #define TG3_FL_NOT_5788 0x4 | ||
7321 | u32 read_mask; | ||
7322 | u32 write_mask; | ||
7323 | } reg_tbl[] = { | ||
7324 | /* MAC Control Registers */ | ||
7325 | { MAC_MODE, TG3_FL_NOT_5705, | ||
7326 | 0x00000000, 0x00ef6f8c }, | ||
7327 | { MAC_MODE, TG3_FL_5705, | ||
7328 | 0x00000000, 0x01ef6b8c }, | ||
7329 | { MAC_STATUS, TG3_FL_NOT_5705, | ||
7330 | 0x03800107, 0x00000000 }, | ||
7331 | { MAC_STATUS, TG3_FL_5705, | ||
7332 | 0x03800100, 0x00000000 }, | ||
7333 | { MAC_ADDR_0_HIGH, 0x0000, | ||
7334 | 0x00000000, 0x0000ffff }, | ||
7335 | { MAC_ADDR_0_LOW, 0x0000, | ||
7336 | 0x00000000, 0xffffffff }, | ||
7337 | { MAC_RX_MTU_SIZE, 0x0000, | ||
7338 | 0x00000000, 0x0000ffff }, | ||
7339 | { MAC_TX_MODE, 0x0000, | ||
7340 | 0x00000000, 0x00000070 }, | ||
7341 | { MAC_TX_LENGTHS, 0x0000, | ||
7342 | 0x00000000, 0x00003fff }, | ||
7343 | { MAC_RX_MODE, TG3_FL_NOT_5705, | ||
7344 | 0x00000000, 0x000007fc }, | ||
7345 | { MAC_RX_MODE, TG3_FL_5705, | ||
7346 | 0x00000000, 0x000007dc }, | ||
7347 | { MAC_HASH_REG_0, 0x0000, | ||
7348 | 0x00000000, 0xffffffff }, | ||
7349 | { MAC_HASH_REG_1, 0x0000, | ||
7350 | 0x00000000, 0xffffffff }, | ||
7351 | { MAC_HASH_REG_2, 0x0000, | ||
7352 | 0x00000000, 0xffffffff }, | ||
7353 | { MAC_HASH_REG_3, 0x0000, | ||
7354 | 0x00000000, 0xffffffff }, | ||
7355 | |||
7356 | /* Receive Data and Receive BD Initiator Control Registers. */ | ||
7357 | { RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705, | ||
7358 | 0x00000000, 0xffffffff }, | ||
7359 | { RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705, | ||
7360 | 0x00000000, 0xffffffff }, | ||
7361 | { RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705, | ||
7362 | 0x00000000, 0x00000003 }, | ||
7363 | { RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705, | ||
7364 | 0x00000000, 0xffffffff }, | ||
7365 | { RCVDBDI_STD_BD+0, 0x0000, | ||
7366 | 0x00000000, 0xffffffff }, | ||
7367 | { RCVDBDI_STD_BD+4, 0x0000, | ||
7368 | 0x00000000, 0xffffffff }, | ||
7369 | { RCVDBDI_STD_BD+8, 0x0000, | ||
7370 | 0x00000000, 0xffff0002 }, | ||
7371 | { RCVDBDI_STD_BD+0xc, 0x0000, | ||
7372 | 0x00000000, 0xffffffff }, | ||
7373 | |||
7374 | /* Receive BD Initiator Control Registers. */ | ||
7375 | { RCVBDI_STD_THRESH, TG3_FL_NOT_5705, | ||
7376 | 0x00000000, 0xffffffff }, | ||
7377 | { RCVBDI_STD_THRESH, TG3_FL_5705, | ||
7378 | 0x00000000, 0x000003ff }, | ||
7379 | { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705, | ||
7380 | 0x00000000, 0xffffffff }, | ||
7381 | |||
7382 | /* Host Coalescing Control Registers. */ | ||
7383 | { HOSTCC_MODE, TG3_FL_NOT_5705, | ||
7384 | 0x00000000, 0x00000004 }, | ||
7385 | { HOSTCC_MODE, TG3_FL_5705, | ||
7386 | 0x00000000, 0x000000f6 }, | ||
7387 | { HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705, | ||
7388 | 0x00000000, 0xffffffff }, | ||
7389 | { HOSTCC_RXCOL_TICKS, TG3_FL_5705, | ||
7390 | 0x00000000, 0x000003ff }, | ||
7391 | { HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705, | ||
7392 | 0x00000000, 0xffffffff }, | ||
7393 | { HOSTCC_TXCOL_TICKS, TG3_FL_5705, | ||
7394 | 0x00000000, 0x000003ff }, | ||
7395 | { HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705, | ||
7396 | 0x00000000, 0xffffffff }, | ||
7397 | { HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7398 | 0x00000000, 0x000000ff }, | ||
7399 | { HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705, | ||
7400 | 0x00000000, 0xffffffff }, | ||
7401 | { HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7402 | 0x00000000, 0x000000ff }, | ||
7403 | { HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
7404 | 0x00000000, 0xffffffff }, | ||
7405 | { HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
7406 | 0x00000000, 0xffffffff }, | ||
7407 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
7408 | 0x00000000, 0xffffffff }, | ||
7409 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7410 | 0x00000000, 0x000000ff }, | ||
7411 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
7412 | 0x00000000, 0xffffffff }, | ||
7413 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7414 | 0x00000000, 0x000000ff }, | ||
7415 | { HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705, | ||
7416 | 0x00000000, 0xffffffff }, | ||
7417 | { HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705, | ||
7418 | 0x00000000, 0xffffffff }, | ||
7419 | { HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705, | ||
7420 | 0x00000000, 0xffffffff }, | ||
7421 | { HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000, | ||
7422 | 0x00000000, 0xffffffff }, | ||
7423 | { HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000, | ||
7424 | 0x00000000, 0xffffffff }, | ||
7425 | { HOSTCC_STATS_BLK_NIC_ADDR, 0x0000, | ||
7426 | 0xffffffff, 0x00000000 }, | ||
7427 | { HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000, | ||
7428 | 0xffffffff, 0x00000000 }, | ||
7429 | |||
7430 | /* Buffer Manager Control Registers. */ | ||
7431 | { BUFMGR_MB_POOL_ADDR, 0x0000, | ||
7432 | 0x00000000, 0x007fff80 }, | ||
7433 | { BUFMGR_MB_POOL_SIZE, 0x0000, | ||
7434 | 0x00000000, 0x007fffff }, | ||
7435 | { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, | ||
7436 | 0x00000000, 0x0000003f }, | ||
7437 | { BUFMGR_MB_MACRX_LOW_WATER, 0x0000, | ||
7438 | 0x00000000, 0x000001ff }, | ||
7439 | { BUFMGR_MB_HIGH_WATER, 0x0000, | ||
7440 | 0x00000000, 0x000001ff }, | ||
7441 | { BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705, | ||
7442 | 0xffffffff, 0x00000000 }, | ||
7443 | { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705, | ||
7444 | 0xffffffff, 0x00000000 }, | ||
7445 | |||
7446 | /* Mailbox Registers */ | ||
7447 | { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000, | ||
7448 | 0x00000000, 0x000001ff }, | ||
7449 | { GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705, | ||
7450 | 0x00000000, 0x000001ff }, | ||
7451 | { GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000, | ||
7452 | 0x00000000, 0x000007ff }, | ||
7453 | { GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000, | ||
7454 | 0x00000000, 0x000001ff }, | ||
7455 | |||
7456 | { 0xffff, 0x0000, 0x00000000, 0x00000000 }, | ||
7457 | }; | ||
7458 | |||
7459 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
7460 | is_5705 = 1; | ||
7461 | else | ||
7462 | is_5705 = 0; | ||
7463 | |||
7464 | for (i = 0; reg_tbl[i].offset != 0xffff; i++) { | ||
7465 | if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) | ||
7466 | continue; | ||
7467 | |||
7468 | if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705)) | ||
7469 | continue; | ||
7470 | |||
7471 | if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) && | ||
7472 | (reg_tbl[i].flags & TG3_FL_NOT_5788)) | ||
7473 | continue; | ||
7474 | |||
7475 | offset = (u32) reg_tbl[i].offset; | ||
7476 | read_mask = reg_tbl[i].read_mask; | ||
7477 | write_mask = reg_tbl[i].write_mask; | ||
7478 | |||
7479 | /* Save the original register content */ | ||
7480 | save_val = tr32(offset); | ||
7481 | |||
7482 | /* Determine the read-only value. */ | ||
7483 | read_val = save_val & read_mask; | ||
7484 | |||
7485 | /* Write zero to the register, then make sure the read-only bits | ||
7486 | * are not changed and the read/write bits are all zeros. | ||
7487 | */ | ||
7488 | tw32(offset, 0); | ||
7489 | |||
7490 | val = tr32(offset); | ||
7491 | |||
7492 | /* Test the read-only and read/write bits. */ | ||
7493 | if (((val & read_mask) != read_val) || (val & write_mask)) | ||
7494 | goto out; | ||
7495 | |||
7496 | /* Write ones to all the bits defined by RdMask and WrMask, then | ||
7497 | * make sure the read-only bits are not changed and the | ||
7498 | * read/write bits are all ones. | ||
7499 | */ | ||
7500 | tw32(offset, read_mask | write_mask); | ||
7501 | |||
7502 | val = tr32(offset); | ||
7503 | |||
7504 | /* Test the read-only bits. */ | ||
7505 | if ((val & read_mask) != read_val) | ||
7506 | goto out; | ||
7507 | |||
7508 | /* Test the read/write bits. */ | ||
7509 | if ((val & write_mask) != write_mask) | ||
7510 | goto out; | ||
7511 | |||
7512 | tw32(offset, save_val); | ||
7513 | } | ||
7514 | |||
7515 | return 0; | ||
7516 | |||
7517 | out: | ||
7518 | printk(KERN_ERR PFX "Register test failed at offset %x\n", offset); | ||
7519 | tw32(offset, save_val); | ||
7520 | return -EIO; | ||
7521 | } | ||
7522 | |||
7310 | static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | 7523 | static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, |
7311 | u64 *data) | 7524 | u64 *data) |
7312 | { | 7525 | { |
@@ -7322,6 +7535,34 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
7322 | etest->flags |= ETH_TEST_FL_FAILED; | 7535 | etest->flags |= ETH_TEST_FL_FAILED; |
7323 | data[1] = 1; | 7536 | data[1] = 1; |
7324 | } | 7537 | } |
7538 | if (etest->flags & ETH_TEST_FL_OFFLINE) { | ||
7539 | if (netif_running(dev)) | ||
7540 | tg3_netif_stop(tp); | ||
7541 | |||
7542 | spin_lock_irq(&tp->lock); | ||
7543 | spin_lock(&tp->tx_lock); | ||
7544 | |||
7545 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); | ||
7546 | tg3_nvram_lock(tp); | ||
7547 | tg3_halt_cpu(tp, RX_CPU_BASE); | ||
7548 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) | ||
7549 | tg3_halt_cpu(tp, TX_CPU_BASE); | ||
7550 | tg3_nvram_unlock(tp); | ||
7551 | |||
7552 | if (tg3_test_registers(tp) != 0) { | ||
7553 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7554 | data[2] = 1; | ||
7555 | } | ||
7556 | |||
7557 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
7558 | if (netif_running(dev)) { | ||
7559 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | ||
7560 | tg3_init_hw(tp); | ||
7561 | tg3_netif_start(tp); | ||
7562 | } | ||
7563 | spin_unlock(&tp->tx_lock); | ||
7564 | spin_unlock_irq(&tp->lock); | ||
7565 | } | ||
7325 | } | 7566 | } |
7326 | 7567 | ||
7327 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 7568 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |