aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/selftest.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/selftest.c')
-rw-r--r--drivers/net/sfc/selftest.c76
1 files changed, 40 insertions, 36 deletions
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