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>
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 15edda2..c785003 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -60,8 +60,8 @@
 #define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1)
 
 /* Ports */
-extern void efx_reconfigure_port(struct efx_nic *efx);
-extern void __efx_reconfigure_port(struct efx_nic *efx);
+extern int efx_reconfigure_port(struct efx_nic *efx);
+extern int __efx_reconfigure_port(struct efx_nic *efx);
 
 /* Ethtool support */
 extern int efx_ethtool_get_settings(struct net_device *net_dev,
@@ -71,10 +71,8 @@
 extern const struct ethtool_ops efx_ethtool_ops;
 
 /* Reset handling */
-extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
-			   struct ethtool_cmd *ecmd);
-extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
-			struct ethtool_cmd *ecmd, bool ok);
+extern void efx_reset_down(struct efx_nic *efx, enum reset_type method);
+extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok);
 
 /* Global */
 extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
@@ -115,5 +113,7 @@
 }
 
 extern void efx_link_status_changed(struct efx_nic *efx);
+extern void efx_link_set_advertising(struct efx_nic *efx, u32);
+extern void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type);
 
 #endif /* EFX_EFX_H */