diff options
| -rw-r--r-- | drivers/net/sfc/ethtool.c | 8 | ||||
| -rw-r--r-- | drivers/net/sfc/net_driver.h | 8 | ||||
| -rw-r--r-- | drivers/net/sfc/selftest.c | 15 | ||||
| -rw-r--r-- | drivers/net/sfc/selftest.h | 4 | ||||
| -rw-r--r-- | drivers/net/sfc/tenxpress.c | 24 |
5 files changed, 44 insertions, 15 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 7fa28443c7bc..53d259e90187 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
| @@ -345,7 +345,7 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, | |||
| 345 | u64 *data) | 345 | u64 *data) |
| 346 | { | 346 | { |
| 347 | struct efx_channel *channel; | 347 | struct efx_channel *channel; |
| 348 | unsigned int n = 0; | 348 | unsigned int n = 0, i; |
| 349 | enum efx_loopback_mode mode; | 349 | enum efx_loopback_mode mode; |
| 350 | 350 | ||
| 351 | efx_fill_test(n++, strings, data, &tests->mii, | 351 | efx_fill_test(n++, strings, data, &tests->mii, |
| @@ -373,8 +373,10 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, | |||
| 373 | 373 | ||
| 374 | efx_fill_test(n++, strings, data, &tests->registers, | 374 | efx_fill_test(n++, strings, data, &tests->registers, |
| 375 | "core", 0, "registers", NULL); | 375 | "core", 0, "registers", NULL); |
| 376 | efx_fill_test(n++, strings, data, &tests->phy, | 376 | |
| 377 | "phy", 0, "bist", NULL); | 377 | for (i = 0; i < efx->phy_op->num_tests; i++) |
| 378 | efx_fill_test(n++, strings, data, &tests->phy[i], | ||
| 379 | "phy", 0, efx->phy_op->test_names[i], NULL); | ||
| 378 | 380 | ||
| 379 | /* Loopback tests */ | 381 | /* Loopback tests */ |
| 380 | for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { | 382 | for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index b0c79755ef2f..5f255f75754e 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
| @@ -568,6 +568,10 @@ struct efx_mac_operations { | |||
| 568 | * @set_settings: Set ethtool settings. Serialised by the mac_lock. | 568 | * @set_settings: Set ethtool settings. Serialised by the mac_lock. |
| 569 | * @set_xnp_advertise: Set abilities advertised in Extended Next Page | 569 | * @set_xnp_advertise: Set abilities advertised in Extended Next Page |
| 570 | * (only needed where AN bit is set in mmds) | 570 | * (only needed where AN bit is set in mmds) |
| 571 | * @num_tests: Number of PHY-specific tests/results | ||
| 572 | * @test_names: Names of the tests/results | ||
| 573 | * @run_tests: Run tests and record results as appropriate. | ||
| 574 | * Flags are the ethtool tests flags. | ||
| 571 | * @mmds: MMD presence mask | 575 | * @mmds: MMD presence mask |
| 572 | * @loopbacks: Supported loopback modes mask | 576 | * @loopbacks: Supported loopback modes mask |
| 573 | */ | 577 | */ |
| @@ -578,12 +582,14 @@ struct efx_phy_operations { | |||
| 578 | void (*reconfigure) (struct efx_nic *efx); | 582 | void (*reconfigure) (struct efx_nic *efx); |
| 579 | void (*clear_interrupt) (struct efx_nic *efx); | 583 | void (*clear_interrupt) (struct efx_nic *efx); |
| 580 | void (*poll) (struct efx_nic *efx); | 584 | void (*poll) (struct efx_nic *efx); |
| 581 | int (*test) (struct efx_nic *efx); | ||
| 582 | void (*get_settings) (struct efx_nic *efx, | 585 | void (*get_settings) (struct efx_nic *efx, |
| 583 | struct ethtool_cmd *ecmd); | 586 | struct ethtool_cmd *ecmd); |
| 584 | int (*set_settings) (struct efx_nic *efx, | 587 | int (*set_settings) (struct efx_nic *efx, |
| 585 | struct ethtool_cmd *ecmd); | 588 | struct ethtool_cmd *ecmd); |
| 586 | bool (*set_xnp_advertise) (struct efx_nic *efx, u32); | 589 | bool (*set_xnp_advertise) (struct efx_nic *efx, u32); |
| 590 | u32 num_tests; | ||
| 591 | const char *const *test_names; | ||
| 592 | int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); | ||
| 587 | int mmds; | 593 | int mmds; |
| 588 | unsigned loopbacks; | 594 | unsigned loopbacks; |
| 589 | }; | 595 | }; |
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index d10f6fbbb5ce..dba0d64d50cd 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c | |||
| @@ -247,17 +247,20 @@ static int efx_test_eventq_irq(struct efx_channel *channel, | |||
| 247 | return 0; | 247 | return 0; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests) | 250 | static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests, |
| 251 | unsigned flags) | ||
| 251 | { | 252 | { |
| 252 | int rc; | 253 | int rc; |
| 253 | 254 | ||
| 254 | if (!efx->phy_op->test) | 255 | if (!efx->phy_op->run_tests) |
| 255 | return 0; | 256 | return 0; |
| 256 | 257 | ||
| 258 | EFX_BUG_ON_PARANOID(efx->phy_op->num_tests == 0 || | ||
| 259 | efx->phy_op->num_tests > EFX_MAX_PHY_TESTS); | ||
| 260 | |||
| 257 | mutex_lock(&efx->mac_lock); | 261 | mutex_lock(&efx->mac_lock); |
| 258 | rc = efx->phy_op->test(efx); | 262 | rc = efx->phy_op->run_tests(efx, tests->phy, flags); |
| 259 | mutex_unlock(&efx->mac_lock); | 263 | mutex_unlock(&efx->mac_lock); |
| 260 | tests->phy = rc ? -1 : 1; | ||
| 261 | return rc; | 264 | return rc; |
| 262 | } | 265 | } |
| 263 | 266 | ||
| @@ -691,7 +694,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, | |||
| 691 | return rc_test; | 694 | return rc_test; |
| 692 | 695 | ||
| 693 | if (!(flags & ETH_TEST_FL_OFFLINE)) | 696 | if (!(flags & ETH_TEST_FL_OFFLINE)) |
| 694 | return 0; | 697 | return efx_test_phy(efx, tests, flags); |
| 695 | 698 | ||
| 696 | /* Offline (i.e. disruptive) testing | 699 | /* Offline (i.e. disruptive) testing |
| 697 | * This checks MAC and PHY loopback on the specified port. */ | 700 | * This checks MAC and PHY loopback on the specified port. */ |
| @@ -739,7 +742,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, | |||
| 739 | return rc_reset; | 742 | return rc_reset; |
| 740 | } | 743 | } |
| 741 | 744 | ||
| 742 | rc = efx_test_phy(efx, tests); | 745 | rc = efx_test_phy(efx, tests, flags); |
| 743 | if (rc && !rc_test) | 746 | if (rc && !rc_test) |
| 744 | rc_test = rc; | 747 | rc_test = rc; |
| 745 | 748 | ||
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h index 97d6acc11ad3..39451cf938cf 100644 --- a/drivers/net/sfc/selftest.h +++ b/drivers/net/sfc/selftest.h | |||
| @@ -24,6 +24,8 @@ struct efx_loopback_self_tests { | |||
| 24 | int rx_bad; | 24 | int rx_bad; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | #define EFX_MAX_PHY_TESTS 20 | ||
| 28 | |||
| 27 | /* Efx self test results | 29 | /* Efx self test results |
| 28 | * For fields which are not counters, 1 indicates success and -1 | 30 | * For fields which are not counters, 1 indicates success and -1 |
| 29 | * indicates failure. | 31 | * indicates failure. |
| @@ -38,7 +40,7 @@ struct efx_self_tests { | |||
| 38 | int eventq_poll[EFX_MAX_CHANNELS]; | 40 | int eventq_poll[EFX_MAX_CHANNELS]; |
| 39 | /* offline tests */ | 41 | /* offline tests */ |
| 40 | int registers; | 42 | int registers; |
| 41 | int phy; | 43 | int phy[EFX_MAX_PHY_TESTS]; |
| 42 | struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; | 44 | struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 1567ab538e27..bd204820e189 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
| @@ -654,10 +654,22 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink) | |||
| 654 | PMA_PMD_LED_OVERR_REG, reg); | 654 | PMA_PMD_LED_OVERR_REG, reg); |
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | static int tenxpress_phy_test(struct efx_nic *efx) | 657 | static const char *const tenxpress_test_names[] = { |
| 658 | "bist" | ||
| 659 | }; | ||
| 660 | |||
| 661 | static int | ||
| 662 | tenxpress_run_tests(struct efx_nic *efx, int *results, unsigned flags) | ||
| 658 | { | 663 | { |
| 664 | int rc; | ||
| 665 | |||
| 666 | if (!(flags & ETH_TEST_FL_OFFLINE)) | ||
| 667 | return 0; | ||
| 668 | |||
| 659 | /* BIST is automatically run after a special software reset */ | 669 | /* BIST is automatically run after a special software reset */ |
| 660 | return tenxpress_special_reset(efx); | 670 | rc = tenxpress_special_reset(efx); |
| 671 | results[0] = rc ? -1 : 1; | ||
| 672 | return rc; | ||
| 661 | } | 673 | } |
| 662 | 674 | ||
| 663 | static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) | 675 | static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) |
| @@ -770,9 +782,11 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { | |||
| 770 | .poll = tenxpress_phy_poll, | 782 | .poll = tenxpress_phy_poll, |
| 771 | .fini = tenxpress_phy_fini, | 783 | .fini = tenxpress_phy_fini, |
| 772 | .clear_interrupt = efx_port_dummy_op_void, | 784 | .clear_interrupt = efx_port_dummy_op_void, |
| 773 | .test = tenxpress_phy_test, | ||
| 774 | .get_settings = sfx7101_get_settings, | 785 | .get_settings = sfx7101_get_settings, |
| 775 | .set_settings = mdio_clause45_set_settings, | 786 | .set_settings = mdio_clause45_set_settings, |
| 787 | .num_tests = ARRAY_SIZE(tenxpress_test_names), | ||
| 788 | .test_names = tenxpress_test_names, | ||
| 789 | .run_tests = tenxpress_run_tests, | ||
| 776 | .mmds = TENXPRESS_REQUIRED_DEVS, | 790 | .mmds = TENXPRESS_REQUIRED_DEVS, |
| 777 | .loopbacks = SFX7101_LOOPBACKS, | 791 | .loopbacks = SFX7101_LOOPBACKS, |
| 778 | }; | 792 | }; |
| @@ -784,10 +798,12 @@ struct efx_phy_operations falcon_sft9001_phy_ops = { | |||
| 784 | .poll = tenxpress_phy_poll, | 798 | .poll = tenxpress_phy_poll, |
| 785 | .fini = tenxpress_phy_fini, | 799 | .fini = tenxpress_phy_fini, |
| 786 | .clear_interrupt = efx_port_dummy_op_void, | 800 | .clear_interrupt = efx_port_dummy_op_void, |
| 787 | .test = tenxpress_phy_test, | ||
| 788 | .get_settings = sft9001_get_settings, | 801 | .get_settings = sft9001_get_settings, |
| 789 | .set_settings = sft9001_set_settings, | 802 | .set_settings = sft9001_set_settings, |
| 790 | .set_xnp_advertise = sft9001_set_xnp_advertise, | 803 | .set_xnp_advertise = sft9001_set_xnp_advertise, |
| 804 | .num_tests = ARRAY_SIZE(tenxpress_test_names), | ||
| 805 | .test_names = tenxpress_test_names, | ||
| 806 | .run_tests = tenxpress_run_tests, | ||
| 791 | .mmds = TENXPRESS_REQUIRED_DEVS, | 807 | .mmds = TENXPRESS_REQUIRED_DEVS, |
| 792 | .loopbacks = SFT9001_LOOPBACKS, | 808 | .loopbacks = SFT9001_LOOPBACKS, |
| 793 | }; | 809 | }; |
