aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/selftest.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2009-11-28 22:42:41 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-29 19:46:28 -0500
commitd3245b28ef2a45ec4e115062a38100bd06229289 (patch)
tree036133fdf01a20f36086d5eb8606728859c056de /drivers/net/sfc/selftest.c
parentef2b90ee4dba7a3d9001f1f0003b860b39a4aaae (diff)
sfc: Refactor link configuration
Refactor PHY, MAC and NIC configuration operations so that the existing link configuration can be re-pushed with: efx->phy_op->reconfigure(efx); efx->mac_op->reconfigure(efx); and a new configuration with: efx->nic_op->reconfigure_port(efx); (plus locking and error-checking). We have not held the link settings in software (aside from flow control), and have relied on asking the hardware what they are. This is a problem because in some cases the hardware may no longer be in a state to tell us. In particular, if an entire multi-port board is reset through one port, the driver bindings to other ports have no chance to save settings before recovering. We only actually need to keep track of the autonegotiation settings, so add an ethtool advertising mask to struct efx_nic, initialise it in PHY init and update it as necessary. Remove now-unneeded uses of efx_phy_op::{get,set}_settings() and struct ethtool_cmd. Much of this was done by Steve Hodgson <shodgson@solarflare.com>. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/selftest.c')
-rw-r--r--drivers/net/sfc/selftest.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 15d4d9c81362..dddeb9dfb373 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -659,7 +659,6 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
659 enum efx_loopback_mode loopback_mode = efx->loopback_mode; 659 enum efx_loopback_mode loopback_mode = efx->loopback_mode;
660 int phy_mode = efx->phy_mode; 660 int phy_mode = efx->phy_mode;
661 enum reset_type reset_method = RESET_TYPE_INVISIBLE; 661 enum reset_type reset_method = RESET_TYPE_INVISIBLE;
662 struct ethtool_cmd ecmd;
663 struct efx_channel *channel; 662 struct efx_channel *channel;
664 int rc_test = 0, rc_reset = 0, rc; 663 int rc_test = 0, rc_reset = 0, rc;
665 664
@@ -712,7 +711,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
712 mutex_unlock(&efx->mac_lock); 711 mutex_unlock(&efx->mac_lock);
713 712
714 /* free up all consumers of SRAM (including all the queues) */ 713 /* free up all consumers of SRAM (including all the queues) */
715 efx_reset_down(efx, reset_method, &ecmd); 714 efx_reset_down(efx, reset_method);
716 715
717 rc = efx_test_chip(efx, tests); 716 rc = efx_test_chip(efx, tests);
718 if (rc && !rc_test) 717 if (rc && !rc_test)
@@ -726,7 +725,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
726 efx->phy_mode &= ~PHY_MODE_LOW_POWER; 725 efx->phy_mode &= ~PHY_MODE_LOW_POWER;
727 efx->loopback_mode = LOOPBACK_NONE; 726 efx->loopback_mode = LOOPBACK_NONE;
728 727
729 rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0); 728 rc = efx_reset_up(efx, reset_method, rc_reset == 0);
730 if (rc && !rc_reset) 729 if (rc && !rc_reset)
731 rc_reset = rc; 730 rc_reset = rc;
732 731
@@ -745,10 +744,12 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
745 rc_test = rc; 744 rc_test = rc;
746 745
747 /* restore the PHY to the previous state */ 746 /* restore the PHY to the previous state */
748 efx->loopback_mode = loopback_mode; 747 mutex_lock(&efx->mac_lock);
749 efx->phy_mode = phy_mode; 748 efx->phy_mode = phy_mode;
750 efx->port_inhibited = false; 749 efx->port_inhibited = false;
751 efx_ethtool_set_settings(efx->net_dev, &ecmd); 750 efx->loopback_mode = loopback_mode;
751 __efx_reconfigure_port(efx);
752 mutex_unlock(&efx->mac_lock);
752 753
753 return rc_test; 754 return rc_test;
754} 755}