aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sfc/ethtool.c19
-rw-r--r--drivers/net/sfc/selftest.c76
-rw-r--r--drivers/net/sfc/selftest.h8
3 files changed, 48 insertions, 55 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 3aaece6b12cc..7fa28443c7bc 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -487,7 +487,7 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
487{ 487{
488 struct efx_nic *efx = netdev_priv(net_dev); 488 struct efx_nic *efx = netdev_priv(net_dev);
489 struct efx_self_tests efx_tests; 489 struct efx_self_tests efx_tests;
490 int offline, already_up; 490 int already_up;
491 int rc; 491 int rc;
492 492
493 ASSERT_RTNL(); 493 ASSERT_RTNL();
@@ -507,24 +507,15 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
507 } 507 }
508 508
509 memset(&efx_tests, 0, sizeof(efx_tests)); 509 memset(&efx_tests, 0, sizeof(efx_tests));
510 offline = (test->flags & ETH_TEST_FL_OFFLINE);
511 510
512 /* Perform online self tests first */ 511 rc = efx_selftest(efx, &efx_tests, test->flags);
513 rc = efx_online_test(efx, &efx_tests);
514 if (rc)
515 goto out;
516
517 /* Perform offline tests only if online tests passed */
518 if (offline)
519 rc = efx_offline_test(efx, &efx_tests,
520 efx->loopback_modes);
521 512
522 out:
523 if (!already_up) 513 if (!already_up)
524 dev_close(efx->net_dev); 514 dev_close(efx->net_dev);
525 515
526 EFX_LOG(efx, "%s all %sline self-tests\n", 516 EFX_LOG(efx, "%s %sline self-tests\n",
527 rc == 0 ? "passed" : "failed", offline ? "off" : "on"); 517 rc == 0 ? "passed" : "failed",
518 (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
528 519
529 fail2: 520 fail2:
530 fail1: 521 fail1:
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 7813ab354411..d10f6fbbb5ce 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -653,47 +653,48 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
653 653
654/************************************************************************** 654/**************************************************************************
655 * 655 *
656 * Entry points 656 * Entry point
657 * 657 *
658 *************************************************************************/ 658 *************************************************************************/
659 659
660/* Online (i.e. non-disruptive) testing 660int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
661 * This checks interrupt generation, event delivery and PHY presence. */ 661 unsigned flags)
662int efx_online_test(struct efx_nic *efx, struct efx_self_tests *tests)
663{ 662{
663 enum efx_loopback_mode loopback_mode = efx->loopback_mode;
664 int phy_mode = efx->phy_mode;
665 struct ethtool_cmd ecmd;
664 struct efx_channel *channel; 666 struct efx_channel *channel;
665 int rc, rc2 = 0; 667 int rc_test = 0, rc_reset = 0, rc;
668
669 /* Online (i.e. non-disruptive) testing
670 * This checks interrupt generation, event delivery and PHY presence. */
666 671
667 rc = efx_test_mii(efx, tests); 672 rc = efx_test_mii(efx, tests);
668 if (rc && !rc2) 673 if (rc && !rc_test)
669 rc2 = rc; 674 rc_test = rc;
670 675
671 rc = efx_test_nvram(efx, tests); 676 rc = efx_test_nvram(efx, tests);
672 if (rc && !rc2) 677 if (rc && !rc_test)
673 rc2 = rc; 678 rc_test = rc;
674 679
675 rc = efx_test_interrupts(efx, tests); 680 rc = efx_test_interrupts(efx, tests);
676 if (rc && !rc2) 681 if (rc && !rc_test)
677 rc2 = rc; 682 rc_test = rc;
678 683
679 efx_for_each_channel(channel, efx) { 684 efx_for_each_channel(channel, efx) {
680 rc = efx_test_eventq_irq(channel, tests); 685 rc = efx_test_eventq_irq(channel, tests);
681 if (rc && !rc2) 686 if (rc && !rc_test)
682 rc2 = rc; 687 rc_test = rc;
683 } 688 }
684 689
685 return rc2; 690 if (rc_test)
686} 691 return rc_test;
687 692
688/* Offline (i.e. disruptive) testing 693 if (!(flags & ETH_TEST_FL_OFFLINE))
689 * This checks MAC and PHY loopback on the specified port. */ 694 return 0;
690int efx_offline_test(struct efx_nic *efx, 695
691 struct efx_self_tests *tests, unsigned int loopback_modes) 696 /* Offline (i.e. disruptive) testing
692{ 697 * This checks MAC and PHY loopback on the specified port. */
693 enum efx_loopback_mode loopback_mode = efx->loopback_mode;
694 int phy_mode = efx->phy_mode;
695 struct ethtool_cmd ecmd;
696 int rc, rc2 = 0;
697 698
698 /* force the carrier state off so the kernel doesn't transmit during 699 /* force the carrier state off so the kernel doesn't transmit during
699 * the loopback test, and the watchdog timeout doesn't fire. Also put 700 * the loopback test, and the watchdog timeout doesn't fire. Also put
@@ -717,31 +718,34 @@ int efx_offline_test(struct efx_nic *efx,
717 efx_reset_down(efx, &ecmd); 718 efx_reset_down(efx, &ecmd);
718 719
719 rc = efx_test_chip(efx, tests); 720 rc = efx_test_chip(efx, tests);
720 if (rc && !rc2) 721 if (rc && !rc_test)
721 rc2 = rc; 722 rc_test = rc;
722 723
723 /* reset the chip to recover from the register test */ 724 /* reset the chip to recover from the register test */
724 rc = falcon_reset_hw(efx, RESET_TYPE_ALL); 725 rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL);
725 726
726 /* Ensure that the phy is powered and out of loopback 727 /* Ensure that the phy is powered and out of loopback
727 * for the bist and loopback tests */ 728 * for the bist and loopback tests */
728 efx->phy_mode &= ~PHY_MODE_LOW_POWER; 729 efx->phy_mode &= ~PHY_MODE_LOW_POWER;
729 efx->loopback_mode = LOOPBACK_NONE; 730 efx->loopback_mode = LOOPBACK_NONE;
730 731
731 rc = efx_reset_up(efx, &ecmd, rc == 0); 732 rc = efx_reset_up(efx, &ecmd, rc_reset == 0);
732 if (rc) { 733 if (rc && !rc_reset)
734 rc_reset = rc;
735
736 if (rc_reset) {
733 EFX_ERR(efx, "Unable to recover from chip test\n"); 737 EFX_ERR(efx, "Unable to recover from chip test\n");
734 efx_schedule_reset(efx, RESET_TYPE_DISABLE); 738 efx_schedule_reset(efx, RESET_TYPE_DISABLE);
735 return rc; 739 return rc_reset;
736 } 740 }
737 741
738 rc = efx_test_phy(efx, tests); 742 rc = efx_test_phy(efx, tests);
739 if (rc && !rc2) 743 if (rc && !rc_test)
740 rc2 = rc; 744 rc_test = rc;
741 745
742 rc = efx_test_loopbacks(efx, tests, loopback_modes); 746 rc = efx_test_loopbacks(efx, tests, efx->loopback_modes);
743 if (rc && !rc2) 747 if (rc && !rc_test)
744 rc2 = rc; 748 rc_test = rc;
745 749
746 /* restore the PHY to the previous state */ 750 /* restore the PHY to the previous state */
747 efx->loopback_mode = loopback_mode; 751 efx->loopback_mode = loopback_mode;
@@ -749,6 +753,6 @@ int efx_offline_test(struct efx_nic *efx,
749 efx->port_inhibited = false; 753 efx->port_inhibited = false;
750 efx_ethtool_set_settings(efx->net_dev, &ecmd); 754 efx_ethtool_set_settings(efx->net_dev, &ecmd);
751 755
752 return rc2; 756 return rc_test;
753} 757}
754 758
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h
index 252f7d717242..97d6acc11ad3 100644
--- a/drivers/net/sfc/selftest.h
+++ b/drivers/net/sfc/selftest.h
@@ -44,10 +44,8 @@ struct efx_self_tests {
44 44
45extern void efx_loopback_rx_packet(struct efx_nic *efx, 45extern void efx_loopback_rx_packet(struct efx_nic *efx,
46 const char *buf_ptr, int pkt_len); 46 const char *buf_ptr, int pkt_len);
47extern int efx_online_test(struct efx_nic *efx, 47extern int efx_selftest(struct efx_nic *efx,
48 struct efx_self_tests *tests); 48 struct efx_self_tests *tests,
49extern int efx_offline_test(struct efx_nic *efx, 49 unsigned flags);
50 struct efx_self_tests *tests,
51 unsigned int loopback_modes);
52 50
53#endif /* EFX_SELFTEST_H */ 51#endif /* EFX_SELFTEST_H */