aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/net/sfc/efx.c132
-rw-r--r--drivers/net/sfc/efx.h12
-rw-r--r--drivers/net/sfc/ethtool.c61
-rw-r--r--drivers/net/sfc/falcon.c98
-rw-r--r--drivers/net/sfc/falcon.h3
-rw-r--r--drivers/net/sfc/falcon_boards.c3
-rw-r--r--drivers/net/sfc/falcon_gmac.c4
-rw-r--r--drivers/net/sfc/falcon_xmac.c8
-rw-r--r--drivers/net/sfc/mac.h1
-rw-r--r--drivers/net/sfc/mdio_10g.c41
-rw-r--r--drivers/net/sfc/mdio_10g.h3
-rw-r--r--drivers/net/sfc/net_driver.h8
-rw-r--r--drivers/net/sfc/qt202x_phy.c4
-rw-r--r--drivers/net/sfc/selftest.c11
-rw-r--r--drivers/net/sfc/tenxpress.c66
15 files changed, 273 insertions, 182 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 73ab246d9f2a..4210121eeff9 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -620,16 +620,49 @@ void efx_link_status_changed(struct efx_nic *efx)
620 620
621} 621}
622 622
623void efx_link_set_advertising(struct efx_nic *efx, u32 advertising)
624{
625 efx->link_advertising = advertising;
626 if (advertising) {
627 if (advertising & ADVERTISED_Pause)
628 efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX);
629 else
630 efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
631 if (advertising & ADVERTISED_Asym_Pause)
632 efx->wanted_fc ^= EFX_FC_TX;
633 }
634}
635
636void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type wanted_fc)
637{
638 efx->wanted_fc = wanted_fc;
639 if (efx->link_advertising) {
640 if (wanted_fc & EFX_FC_RX)
641 efx->link_advertising |= (ADVERTISED_Pause |
642 ADVERTISED_Asym_Pause);
643 else
644 efx->link_advertising &= ~(ADVERTISED_Pause |
645 ADVERTISED_Asym_Pause);
646 if (wanted_fc & EFX_FC_TX)
647 efx->link_advertising ^= ADVERTISED_Asym_Pause;
648 }
649}
650
623static void efx_fini_port(struct efx_nic *efx); 651static void efx_fini_port(struct efx_nic *efx);
624 652
625/* This call reinitialises the MAC to pick up new PHY settings. The 653/* Push loopback/power/transmit disable settings to the PHY, and reconfigure
626 * caller must hold the mac_lock */ 654 * the MAC appropriately. All other PHY configuration changes are pushed
627void __efx_reconfigure_port(struct efx_nic *efx) 655 * through phy_op->set_settings(), and pushed asynchronously to the MAC
656 * through efx_monitor().
657 *
658 * Callers must hold the mac_lock
659 */
660int __efx_reconfigure_port(struct efx_nic *efx)
628{ 661{
629 WARN_ON(!mutex_is_locked(&efx->mac_lock)); 662 enum efx_phy_mode phy_mode;
663 int rc;
630 664
631 EFX_LOG(efx, "reconfiguring MAC from PHY settings on CPU %d\n", 665 WARN_ON(!mutex_is_locked(&efx->mac_lock));
632 raw_smp_processor_id());
633 666
634 /* Serialise the promiscuous flag with efx_set_multicast_list. */ 667 /* Serialise the promiscuous flag with efx_set_multicast_list. */
635 if (efx_dev_registered(efx)) { 668 if (efx_dev_registered(efx)) {
@@ -637,42 +670,34 @@ void __efx_reconfigure_port(struct efx_nic *efx)
637 netif_addr_unlock_bh(efx->net_dev); 670 netif_addr_unlock_bh(efx->net_dev);
638 } 671 }
639 672
640 efx->type->stop_stats(efx); 673 /* Disable PHY transmit in mac level loopbacks */
641 falcon_deconfigure_mac_wrapper(efx); 674 phy_mode = efx->phy_mode;
642
643 /* Reconfigure the PHY, disabling transmit in mac level loopback. */
644 if (LOOPBACK_INTERNAL(efx)) 675 if (LOOPBACK_INTERNAL(efx))
645 efx->phy_mode |= PHY_MODE_TX_DISABLED; 676 efx->phy_mode |= PHY_MODE_TX_DISABLED;
646 else 677 else
647 efx->phy_mode &= ~PHY_MODE_TX_DISABLED; 678 efx->phy_mode &= ~PHY_MODE_TX_DISABLED;
648 efx->phy_op->reconfigure(efx);
649
650 if (falcon_switch_mac(efx))
651 goto fail;
652 679
653 efx->mac_op->reconfigure(efx); 680 rc = efx->type->reconfigure_port(efx);
654 681
655 efx->type->start_stats(efx); 682 if (rc)
656 683 efx->phy_mode = phy_mode;
657 /* Inform kernel of loss/gain of carrier */
658 efx_link_status_changed(efx);
659 return;
660 684
661fail: 685 return rc;
662 EFX_ERR(efx, "failed to reconfigure MAC\n");
663 efx->port_enabled = false;
664 efx_fini_port(efx);
665} 686}
666 687
667/* Reinitialise the MAC to pick up new PHY settings, even if the port is 688/* Reinitialise the MAC to pick up new PHY settings, even if the port is
668 * disabled. */ 689 * disabled. */
669void efx_reconfigure_port(struct efx_nic *efx) 690int efx_reconfigure_port(struct efx_nic *efx)
670{ 691{
692 int rc;
693
671 EFX_ASSERT_RESET_SERIALISED(efx); 694 EFX_ASSERT_RESET_SERIALISED(efx);
672 695
673 mutex_lock(&efx->mac_lock); 696 mutex_lock(&efx->mac_lock);
674 __efx_reconfigure_port(efx); 697 rc = __efx_reconfigure_port(efx);
675 mutex_unlock(&efx->mac_lock); 698 mutex_unlock(&efx->mac_lock);
699
700 return rc;
676} 701}
677 702
678/* Asynchronous work item for changing MAC promiscuity and multicast 703/* Asynchronous work item for changing MAC promiscuity and multicast
@@ -737,14 +762,18 @@ static int efx_init_port(struct efx_nic *efx)
737 rc = efx->phy_op->init(efx); 762 rc = efx->phy_op->init(efx);
738 if (rc) 763 if (rc)
739 goto fail1; 764 goto fail1;
740 efx->phy_op->reconfigure(efx);
741 rc = falcon_switch_mac(efx);
742 if (rc)
743 goto fail2;
744 efx->mac_op->reconfigure(efx);
745 765
746 efx->port_initialized = true; 766 efx->port_initialized = true;
747 767
768 /* Reconfigure the MAC before creating dma queues (required for
769 * Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */
770 efx->mac_op->reconfigure(efx);
771
772 /* Ensure the PHY advertises the correct flow control settings */
773 rc = efx->phy_op->reconfigure(efx);
774 if (rc)
775 goto fail2;
776
748 mutex_unlock(&efx->mac_lock); 777 mutex_unlock(&efx->mac_lock);
749 return 0; 778 return 0;
750 779
@@ -1209,12 +1238,6 @@ static void efx_stop_all(struct efx_nic *efx)
1209 /* Flush efx_mac_work(), refill_workqueue, monitor_work */ 1238 /* Flush efx_mac_work(), refill_workqueue, monitor_work */
1210 efx_flush_all(efx); 1239 efx_flush_all(efx);
1211 1240
1212 /* Isolate the MAC from the TX and RX engines, so that queue
1213 * flushes will complete in a timely fashion. */
1214 falcon_deconfigure_mac_wrapper(efx);
1215 msleep(10); /* Let the Rx FIFO drain */
1216 falcon_drain_tx_fifo(efx);
1217
1218 /* Stop the kernel transmit interface late, so the watchdog 1241 /* Stop the kernel transmit interface late, so the watchdog
1219 * timer isn't ticking over the flush */ 1242 * timer isn't ticking over the flush */
1220 if (efx_dev_registered(efx)) { 1243 if (efx_dev_registered(efx)) {
@@ -1491,7 +1514,14 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
1491 EFX_LOG(efx, "changing MTU to %d\n", new_mtu); 1514 EFX_LOG(efx, "changing MTU to %d\n", new_mtu);
1492 1515
1493 efx_fini_channels(efx); 1516 efx_fini_channels(efx);
1517
1518 mutex_lock(&efx->mac_lock);
1519 /* Reconfigure the MAC before enabling the dma queues so that
1520 * the RX buffers don't overflow */
1494 net_dev->mtu = new_mtu; 1521 net_dev->mtu = new_mtu;
1522 efx->mac_op->reconfigure(efx);
1523 mutex_unlock(&efx->mac_lock);
1524
1495 efx_init_channels(efx); 1525 efx_init_channels(efx);
1496 1526
1497 efx_start_all(efx); 1527 efx_start_all(efx);
@@ -1515,7 +1545,9 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
1515 memcpy(net_dev->dev_addr, new_addr, net_dev->addr_len); 1545 memcpy(net_dev->dev_addr, new_addr, net_dev->addr_len);
1516 1546
1517 /* Reconfigure the MAC */ 1547 /* Reconfigure the MAC */
1518 efx_reconfigure_port(efx); 1548 mutex_lock(&efx->mac_lock);
1549 efx->mac_op->reconfigure(efx);
1550 mutex_unlock(&efx->mac_lock);
1519 1551
1520 return 0; 1552 return 0;
1521} 1553}
@@ -1682,8 +1714,7 @@ static void efx_unregister_netdev(struct efx_nic *efx)
1682 1714
1683/* Tears down the entire software state and most of the hardware state 1715/* Tears down the entire software state and most of the hardware state
1684 * before reset. */ 1716 * before reset. */
1685void efx_reset_down(struct efx_nic *efx, enum reset_type method, 1717void efx_reset_down(struct efx_nic *efx, enum reset_type method)
1686 struct ethtool_cmd *ecmd)
1687{ 1718{
1688 EFX_ASSERT_RESET_SERIALISED(efx); 1719 EFX_ASSERT_RESET_SERIALISED(efx);
1689 1720
@@ -1691,8 +1722,6 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method,
1691 mutex_lock(&efx->mac_lock); 1722 mutex_lock(&efx->mac_lock);
1692 mutex_lock(&efx->spi_lock); 1723 mutex_lock(&efx->spi_lock);
1693 1724
1694 efx->phy_op->get_settings(efx, ecmd);
1695
1696 efx_fini_channels(efx); 1725 efx_fini_channels(efx);
1697 if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) 1726 if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
1698 efx->phy_op->fini(efx); 1727 efx->phy_op->fini(efx);
@@ -1704,8 +1733,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method,
1704 * that we were unable to reinitialise the hardware, and the 1733 * that we were unable to reinitialise the hardware, and the
1705 * driver should be disabled. If ok is false, then the rx and tx 1734 * driver should be disabled. If ok is false, then the rx and tx
1706 * engines are not restarted, pending a RESET_DISABLE. */ 1735 * engines are not restarted, pending a RESET_DISABLE. */
1707int efx_reset_up(struct efx_nic *efx, enum reset_type method, 1736int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
1708 struct ethtool_cmd *ecmd, bool ok)
1709{ 1737{
1710 int rc; 1738 int rc;
1711 1739
@@ -1722,16 +1750,17 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method,
1722 rc = efx->phy_op->init(efx); 1750 rc = efx->phy_op->init(efx);
1723 if (rc) 1751 if (rc)
1724 ok = false; 1752 ok = false;
1753 if (efx->phy_op->reconfigure(efx))
1754 EFX_ERR(efx, "could not restore PHY settings\n");
1725 } 1755 }
1726 if (!ok) 1756 if (!ok)
1727 efx->port_initialized = false; 1757 efx->port_initialized = false;
1728 } 1758 }
1729 1759
1730 if (ok) { 1760 if (ok) {
1731 efx_init_channels(efx); 1761 efx->mac_op->reconfigure(efx);
1732 1762
1733 if (efx->phy_op->set_settings(efx, ecmd)) 1763 efx_init_channels(efx);
1734 EFX_ERR(efx, "could not restore PHY settings\n");
1735 } 1764 }
1736 1765
1737 mutex_unlock(&efx->spi_lock); 1766 mutex_unlock(&efx->spi_lock);
@@ -1753,7 +1782,6 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method,
1753 */ 1782 */
1754static int efx_reset(struct efx_nic *efx) 1783static int efx_reset(struct efx_nic *efx)
1755{ 1784{
1756 struct ethtool_cmd ecmd;
1757 enum reset_type method = efx->reset_pending; 1785 enum reset_type method = efx->reset_pending;
1758 int rc = 0; 1786 int rc = 0;
1759 1787
@@ -1769,7 +1797,7 @@ static int efx_reset(struct efx_nic *efx)
1769 1797
1770 EFX_INFO(efx, "resetting (%s)\n", RESET_TYPE(method)); 1798 EFX_INFO(efx, "resetting (%s)\n", RESET_TYPE(method));
1771 1799
1772 efx_reset_down(efx, method, &ecmd); 1800 efx_reset_down(efx, method);
1773 1801
1774 rc = efx->type->reset(efx, method); 1802 rc = efx->type->reset(efx, method);
1775 if (rc) { 1803 if (rc) {
@@ -1788,10 +1816,10 @@ static int efx_reset(struct efx_nic *efx)
1788 1816
1789 /* Leave device stopped if necessary */ 1817 /* Leave device stopped if necessary */
1790 if (method == RESET_TYPE_DISABLE) { 1818 if (method == RESET_TYPE_DISABLE) {
1791 efx_reset_up(efx, method, &ecmd, false); 1819 efx_reset_up(efx, method, false);
1792 rc = -EIO; 1820 rc = -EIO;
1793 } else { 1821 } else {
1794 rc = efx_reset_up(efx, method, &ecmd, true); 1822 rc = efx_reset_up(efx, method, true);
1795 } 1823 }
1796 1824
1797out_disable: 1825out_disable:
@@ -1895,7 +1923,7 @@ bool efx_port_dummy_op_poll(struct efx_nic *efx)
1895 1923
1896static struct efx_phy_operations efx_dummy_phy_operations = { 1924static struct efx_phy_operations efx_dummy_phy_operations = {
1897 .init = efx_port_dummy_op_int, 1925 .init = efx_port_dummy_op_int,
1898 .reconfigure = efx_port_dummy_op_void, 1926 .reconfigure = efx_port_dummy_op_int,
1899 .poll = efx_port_dummy_op_poll, 1927 .poll = efx_port_dummy_op_poll,
1900 .fini = efx_port_dummy_op_void, 1928 .fini = efx_port_dummy_op_void,
1901}; 1929};
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 15edda2a2242..c78500321586 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -60,8 +60,8 @@ extern void efx_process_channel_now(struct efx_channel *channel);
60#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1) 60#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1)
61 61
62/* Ports */ 62/* Ports */
63extern void efx_reconfigure_port(struct efx_nic *efx); 63extern int efx_reconfigure_port(struct efx_nic *efx);
64extern void __efx_reconfigure_port(struct efx_nic *efx); 64extern int __efx_reconfigure_port(struct efx_nic *efx);
65 65
66/* Ethtool support */ 66/* Ethtool support */
67extern int efx_ethtool_get_settings(struct net_device *net_dev, 67extern int efx_ethtool_get_settings(struct net_device *net_dev,
@@ -71,10 +71,8 @@ extern int efx_ethtool_set_settings(struct net_device *net_dev,
71extern const struct ethtool_ops efx_ethtool_ops; 71extern const struct ethtool_ops efx_ethtool_ops;
72 72
73/* Reset handling */ 73/* Reset handling */
74extern void efx_reset_down(struct efx_nic *efx, enum reset_type method, 74extern void efx_reset_down(struct efx_nic *efx, enum reset_type method);
75 struct ethtool_cmd *ecmd); 75extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok);
76extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
77 struct ethtool_cmd *ecmd, bool ok);
78 76
79/* Global */ 77/* Global */
80extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); 78extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
@@ -115,5 +113,7 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
115} 113}
116 114
117extern void efx_link_status_changed(struct efx_nic *efx); 115extern void efx_link_status_changed(struct efx_nic *efx);
116extern void efx_link_set_advertising(struct efx_nic *efx, u32);
117extern void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type);
118 118
119#endif /* EFX_EFX_H */ 119#endif /* EFX_EFX_H */
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 49e0aed920d3..d95d0fa399ff 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/netdevice.h> 11#include <linux/netdevice.h>
12#include <linux/ethtool.h> 12#include <linux/ethtool.h>
13#include <linux/mdio.h>
14#include <linux/rtnetlink.h> 13#include <linux/rtnetlink.h>
15#include "net_driver.h" 14#include "net_driver.h"
16#include "workarounds.h" 15#include "workarounds.h"
@@ -191,6 +190,7 @@ int efx_ethtool_get_settings(struct net_device *net_dev,
191 struct ethtool_cmd *ecmd) 190 struct ethtool_cmd *ecmd)
192{ 191{
193 struct efx_nic *efx = netdev_priv(net_dev); 192 struct efx_nic *efx = netdev_priv(net_dev);
193 struct efx_link_state *link_state = &efx->link_state;
194 194
195 mutex_lock(&efx->mac_lock); 195 mutex_lock(&efx->mac_lock);
196 efx->phy_op->get_settings(efx, ecmd); 196 efx->phy_op->get_settings(efx, ecmd);
@@ -198,6 +198,13 @@ int efx_ethtool_get_settings(struct net_device *net_dev,
198 198
199 /* Falcon GMAC does not support 1000Mbps HD */ 199 /* Falcon GMAC does not support 1000Mbps HD */
200 ecmd->supported &= ~SUPPORTED_1000baseT_Half; 200 ecmd->supported &= ~SUPPORTED_1000baseT_Half;
201 /* Both MACs support pause frames (bidirectional and respond-only) */
202 ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
203
204 if (LOOPBACK_INTERNAL(efx)) {
205 ecmd->speed = link_state->speed;
206 ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
207 }
201 208
202 return 0; 209 return 0;
203} 210}
@@ -219,9 +226,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
219 mutex_lock(&efx->mac_lock); 226 mutex_lock(&efx->mac_lock);
220 rc = efx->phy_op->set_settings(efx, ecmd); 227 rc = efx->phy_op->set_settings(efx, ecmd);
221 mutex_unlock(&efx->mac_lock); 228 mutex_unlock(&efx->mac_lock);
222 if (!rc)
223 efx_reconfigure_port(efx);
224
225 return rc; 229 return rc;
226} 230}
227 231
@@ -658,8 +662,12 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
658 struct ethtool_pauseparam *pause) 662 struct ethtool_pauseparam *pause)
659{ 663{
660 struct efx_nic *efx = netdev_priv(net_dev); 664 struct efx_nic *efx = netdev_priv(net_dev);
661 enum efx_fc_type wanted_fc; 665 enum efx_fc_type wanted_fc, old_fc;
666 u32 old_adv;
662 bool reset; 667 bool reset;
668 int rc = 0;
669
670 mutex_lock(&efx->mac_lock);
663 671
664 wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) | 672 wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) |
665 (pause->tx_pause ? EFX_FC_TX : 0) | 673 (pause->tx_pause ? EFX_FC_TX : 0) |
@@ -667,14 +675,14 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
667 675
668 if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) { 676 if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) {
669 EFX_LOG(efx, "Flow control unsupported: tx ON rx OFF\n"); 677 EFX_LOG(efx, "Flow control unsupported: tx ON rx OFF\n");
670 return -EINVAL; 678 rc = -EINVAL;
679 goto out;
671 } 680 }
672 681
673 if (!(efx->phy_op->mmds & MDIO_DEVS_AN) && 682 if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising) {
674 (wanted_fc & EFX_FC_AUTO)) { 683 EFX_LOG(efx, "Autonegotiation is disabled\n");
675 EFX_LOG(efx, "PHY does not support flow control " 684 rc = -EINVAL;
676 "autonegotiation\n"); 685 goto out;
677 return -EINVAL;
678 } 686 }
679 687
680 /* TX flow control may automatically turn itself off if the 688 /* TX flow control may automatically turn itself off if the
@@ -686,25 +694,38 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
686 if (EFX_WORKAROUND_11482(efx) && reset) { 694 if (EFX_WORKAROUND_11482(efx) && reset) {
687 if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) { 695 if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) {
688 /* Recover by resetting the EM block */ 696 /* Recover by resetting the EM block */
689 if (efx->link_state.up) 697 falcon_stop_nic_stats(efx);
690 falcon_drain_tx_fifo(efx); 698 falcon_drain_tx_fifo(efx);
699 efx->mac_op->reconfigure(efx);
700 falcon_start_nic_stats(efx);
691 } else { 701 } else {
692 /* Schedule a reset to recover */ 702 /* Schedule a reset to recover */
693 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); 703 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
694 } 704 }
695 } 705 }
696 706
697 /* Try to push the pause parameters */ 707 old_adv = efx->link_advertising;
698 mutex_lock(&efx->mac_lock); 708 old_fc = efx->wanted_fc;
709 efx_link_set_wanted_fc(efx, wanted_fc);
710 if (efx->link_advertising != old_adv ||
711 (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) {
712 rc = efx->phy_op->reconfigure(efx);
713 if (rc) {
714 EFX_ERR(efx, "Unable to advertise requested flow "
715 "control setting\n");
716 goto out;
717 }
718 }
699 719
700 efx->wanted_fc = wanted_fc; 720 /* Reconfigure the MAC. The PHY *may* generate a link state change event
701 if (efx->phy_op->mmds & MDIO_DEVS_AN) 721 * if the user just changed the advertised capabilities, but there's no
702 mdio45_ethtool_spauseparam_an(&efx->mdio, pause); 722 * harm doing this twice */
703 __efx_reconfigure_port(efx); 723 efx->mac_op->reconfigure(efx);
704 724
725out:
705 mutex_unlock(&efx->mac_lock); 726 mutex_unlock(&efx->mac_lock);
706 727
707 return 0; 728 return rc;
708} 729}
709 730
710static void efx_ethtool_get_pauseparam(struct net_device *net_dev, 731static void efx_ethtool_get_pauseparam(struct net_device *net_dev,
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index f6d10213d0b7..3466616c01c0 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1193,6 +1193,8 @@ static void falcon_poll_flush_events(struct efx_nic *efx)
1193 channel->eventq_read_ptr = read_ptr; 1193 channel->eventq_read_ptr = read_ptr;
1194} 1194}
1195 1195
1196static void falcon_deconfigure_mac_wrapper(struct efx_nic *efx);
1197
1196static void falcon_prepare_flush(struct efx_nic *efx) 1198static void falcon_prepare_flush(struct efx_nic *efx)
1197{ 1199{
1198 falcon_deconfigure_mac_wrapper(efx); 1200 falcon_deconfigure_mac_wrapper(efx);
@@ -1836,9 +1838,10 @@ static void falcon_push_multicast_hash(struct efx_nic *efx)
1836 efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1); 1838 efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1);
1837} 1839}
1838 1840
1839static int falcon_reset_macs(struct efx_nic *efx) 1841static void falcon_reset_macs(struct efx_nic *efx)
1840{ 1842{
1841 efx_oword_t reg; 1843 struct falcon_nic_data *nic_data = efx->nic_data;
1844 efx_oword_t reg, mac_ctrl;
1842 int count; 1845 int count;
1843 1846
1844 if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) { 1847 if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) {
@@ -1853,7 +1856,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
1853 EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0); 1856 EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0);
1854 efx_writeo(efx, &reg, FR_AB_GM_CFG1); 1857 efx_writeo(efx, &reg, FR_AB_GM_CFG1);
1855 udelay(1000); 1858 udelay(1000);
1856 return 0; 1859 return;
1857 } else { 1860 } else {
1858 EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); 1861 EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1);
1859 efx_writeo(efx, &reg, FR_AB_XM_GLB_CFG); 1862 efx_writeo(efx, &reg, FR_AB_XM_GLB_CFG);
@@ -1862,22 +1865,20 @@ static int falcon_reset_macs(struct efx_nic *efx)
1862 efx_reado(efx, &reg, FR_AB_XM_GLB_CFG); 1865 efx_reado(efx, &reg, FR_AB_XM_GLB_CFG);
1863 if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == 1866 if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) ==
1864 0) 1867 0)
1865 return 0; 1868 return;
1866 udelay(10); 1869 udelay(10);
1867 } 1870 }
1868 1871
1869 EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); 1872 EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
1870 return -ETIMEDOUT;
1871 } 1873 }
1872 } 1874 }
1873 1875
1874 /* MAC stats will fail whilst the TX fifo is draining. Serialise 1876 /* Mac stats will fail whist the TX fifo is draining */
1875 * the drain sequence with the statistics fetch */ 1877 WARN_ON(nic_data->stats_disable_count == 0);
1876 falcon_stop_nic_stats(efx);
1877 1878
1878 efx_reado(efx, &reg, FR_AB_MAC_CTRL); 1879 efx_reado(efx, &mac_ctrl, FR_AB_MAC_CTRL);
1879 EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, 1); 1880 EFX_SET_OWORD_FIELD(mac_ctrl, FRF_BB_TXFIFO_DRAIN_EN, 1);
1880 efx_writeo(efx, &reg, FR_AB_MAC_CTRL); 1881 efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL);
1881 1882
1882 efx_reado(efx, &reg, FR_AB_GLB_CTL); 1883 efx_reado(efx, &reg, FR_AB_GLB_CTL);
1883 EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGTX, 1); 1884 EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGTX, 1);
@@ -1903,14 +1904,9 @@ static int falcon_reset_macs(struct efx_nic *efx)
1903 udelay(10); 1904 udelay(10);
1904 } 1905 }
1905 1906
1906 /* If we've reset the EM block and the link is up, then 1907 /* Ensure the correct MAC is selected before statistics
1907 * we'll have to kick the XAUI link so the PHY can recover */ 1908 * are re-enabled by the caller */
1908 if (efx->link_state.up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx)) 1909 efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL);
1909 falcon_reset_xaui(efx);
1910
1911 falcon_start_nic_stats(efx);
1912
1913 return 0;
1914} 1910}
1915 1911
1916void falcon_drain_tx_fifo(struct efx_nic *efx) 1912void falcon_drain_tx_fifo(struct efx_nic *efx)
@@ -1929,7 +1925,7 @@ void falcon_drain_tx_fifo(struct efx_nic *efx)
1929 falcon_reset_macs(efx); 1925 falcon_reset_macs(efx);
1930} 1926}
1931 1927
1932void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) 1928static void falcon_deconfigure_mac_wrapper(struct efx_nic *efx)
1933{ 1929{
1934 efx_oword_t reg; 1930 efx_oword_t reg;
1935 1931
@@ -1941,8 +1937,8 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx)
1941 EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0); 1937 EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0);
1942 efx_writeo(efx, &reg, FR_AZ_RX_CFG); 1938 efx_writeo(efx, &reg, FR_AZ_RX_CFG);
1943 1939
1944 if (!efx->link_state.up) 1940 /* Isolate TX -> MAC */
1945 falcon_drain_tx_fifo(efx); 1941 falcon_drain_tx_fifo(efx);
1946} 1942}
1947 1943
1948void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) 1944void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
@@ -2044,6 +2040,8 @@ static void falcon_stats_timer_func(unsigned long context)
2044 spin_unlock(&efx->stats_lock); 2040 spin_unlock(&efx->stats_lock);
2045} 2041}
2046 2042
2043static void falcon_switch_mac(struct efx_nic *efx);
2044
2047static bool falcon_loopback_link_poll(struct efx_nic *efx) 2045static bool falcon_loopback_link_poll(struct efx_nic *efx)
2048{ 2046{
2049 struct efx_link_state old_state = efx->link_state; 2047 struct efx_link_state old_state = efx->link_state;
@@ -2063,6 +2061,38 @@ static bool falcon_loopback_link_poll(struct efx_nic *efx)
2063 return !efx_link_state_equal(&efx->link_state, &old_state); 2061 return !efx_link_state_equal(&efx->link_state, &old_state);
2064} 2062}
2065 2063
2064static int falcon_reconfigure_port(struct efx_nic *efx)
2065{
2066 int rc;
2067
2068 WARN_ON(efx_nic_rev(efx) > EFX_REV_FALCON_B0);
2069
2070 /* Poll the PHY link state *before* reconfiguring it. This means we
2071 * will pick up the correct speed (in loopback) to select the correct
2072 * MAC.
2073 */
2074 if (LOOPBACK_INTERNAL(efx))
2075 falcon_loopback_link_poll(efx);
2076 else
2077 efx->phy_op->poll(efx);
2078
2079 falcon_stop_nic_stats(efx);
2080 falcon_deconfigure_mac_wrapper(efx);
2081
2082 falcon_switch_mac(efx);
2083
2084 efx->phy_op->reconfigure(efx);
2085 rc = efx->mac_op->reconfigure(efx);
2086 BUG_ON(rc);
2087
2088 falcon_start_nic_stats(efx);
2089
2090 /* Synchronise efx->link_state with the kernel */
2091 efx_link_status_changed(efx);
2092
2093 return 0;
2094}
2095
2066/************************************************************************** 2096/**************************************************************************
2067 * 2097 *
2068 * PHY access via GMII 2098 * PHY access via GMII
@@ -2215,17 +2245,15 @@ static void falcon_clock_mac(struct efx_nic *efx)
2215 } 2245 }
2216} 2246}
2217 2247
2218int falcon_switch_mac(struct efx_nic *efx) 2248static void falcon_switch_mac(struct efx_nic *efx)
2219{ 2249{
2220 struct efx_mac_operations *old_mac_op = efx->mac_op; 2250 struct efx_mac_operations *old_mac_op = efx->mac_op;
2221 struct falcon_nic_data *nic_data = efx->nic_data; 2251 struct falcon_nic_data *nic_data = efx->nic_data;
2222 unsigned int stats_done_offset; 2252 unsigned int stats_done_offset;
2223 int rc = 0;
2224
2225 /* Don't try to fetch MAC stats while we're switching MACs */
2226 falcon_stop_nic_stats(efx);
2227 2253
2228 WARN_ON(!mutex_is_locked(&efx->mac_lock)); 2254 WARN_ON(!mutex_is_locked(&efx->mac_lock));
2255 WARN_ON(nic_data->stats_disable_count == 0);
2256
2229 efx->mac_op = (EFX_IS10G(efx) ? 2257 efx->mac_op = (EFX_IS10G(efx) ?
2230 &falcon_xmac_operations : &falcon_gmac_operations); 2258 &falcon_xmac_operations : &falcon_gmac_operations);
2231 2259
@@ -2236,18 +2264,14 @@ int falcon_switch_mac(struct efx_nic *efx)
2236 nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset; 2264 nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset;
2237 2265
2238 if (old_mac_op == efx->mac_op) 2266 if (old_mac_op == efx->mac_op)
2239 goto out; 2267 return;
2240 2268
2241 falcon_clock_mac(efx); 2269 falcon_clock_mac(efx);
2242 2270
2243 EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); 2271 EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
2244 /* Not all macs support a mac-level link state */ 2272 /* Not all macs support a mac-level link state */
2245 efx->xmac_poll_required = false; 2273 efx->xmac_poll_required = false;
2246 2274 falcon_reset_macs(efx);
2247 rc = falcon_reset_macs(efx);
2248out:
2249 falcon_start_nic_stats(efx);
2250 return rc;
2251} 2275}
2252 2276
2253/* This call is responsible for hooking in the MAC and PHY operations */ 2277/* This call is responsible for hooking in the MAC and PHY operations */
@@ -2597,7 +2621,8 @@ static void falcon_monitor(struct efx_nic *efx)
2597 EFX_ERR(efx, "Board sensor %s; shutting down PHY\n", 2621 EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
2598 (rc == -ERANGE) ? "reported fault" : "failed"); 2622 (rc == -ERANGE) ? "reported fault" : "failed");
2599 efx->phy_mode |= PHY_MODE_LOW_POWER; 2623 efx->phy_mode |= PHY_MODE_LOW_POWER;
2600 __efx_reconfigure_port(efx); 2624 rc = __efx_reconfigure_port(efx);
2625 WARN_ON(rc);
2601 } 2626 }
2602 2627
2603 if (LOOPBACK_INTERNAL(efx)) 2628 if (LOOPBACK_INTERNAL(efx))
@@ -2610,7 +2635,8 @@ static void falcon_monitor(struct efx_nic *efx)
2610 falcon_deconfigure_mac_wrapper(efx); 2635 falcon_deconfigure_mac_wrapper(efx);
2611 2636
2612 falcon_switch_mac(efx); 2637 falcon_switch_mac(efx);
2613 efx->mac_op->reconfigure(efx); 2638 rc = efx->mac_op->reconfigure(efx);
2639 BUG_ON(rc);
2614 2640
2615 falcon_start_nic_stats(efx); 2641 falcon_start_nic_stats(efx);
2616 2642
@@ -3239,6 +3265,7 @@ struct efx_nic_type falcon_a1_nic_type = {
3239 .stop_stats = falcon_stop_nic_stats, 3265 .stop_stats = falcon_stop_nic_stats,
3240 .push_irq_moderation = falcon_push_irq_moderation, 3266 .push_irq_moderation = falcon_push_irq_moderation,
3241 .push_multicast_hash = falcon_push_multicast_hash, 3267 .push_multicast_hash = falcon_push_multicast_hash,
3268 .reconfigure_port = falcon_reconfigure_port,
3242 .default_mac_ops = &falcon_xmac_operations, 3269 .default_mac_ops = &falcon_xmac_operations,
3243 3270
3244 .revision = EFX_REV_FALCON_A1, 3271 .revision = EFX_REV_FALCON_A1,
@@ -3271,6 +3298,7 @@ struct efx_nic_type falcon_b0_nic_type = {
3271 .stop_stats = falcon_stop_nic_stats, 3298 .stop_stats = falcon_stop_nic_stats,
3272 .push_irq_moderation = falcon_push_irq_moderation, 3299 .push_irq_moderation = falcon_push_irq_moderation,
3273 .push_multicast_hash = falcon_push_multicast_hash, 3300 .push_multicast_hash = falcon_push_multicast_hash,
3301 .reconfigure_port = falcon_reconfigure_port,
3274 .default_mac_ops = &falcon_xmac_operations, 3302 .default_mac_ops = &falcon_xmac_operations,
3275 3303
3276 .revision = EFX_REV_FALCON_B0, 3304 .revision = EFX_REV_FALCON_B0,
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 3fe64849c98d..560a3f9895a5 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -130,10 +130,7 @@ extern int falcon_process_eventq(struct efx_channel *channel, int rx_quota);
130extern void falcon_eventq_read_ack(struct efx_channel *channel); 130extern void falcon_eventq_read_ack(struct efx_channel *channel);
131 131
132/* MAC/PHY */ 132/* MAC/PHY */
133extern int falcon_switch_mac(struct efx_nic *efx);
134extern bool falcon_xaui_link_ok(struct efx_nic *efx);
135extern void falcon_drain_tx_fifo(struct efx_nic *efx); 133extern void falcon_drain_tx_fifo(struct efx_nic *efx);
136extern void falcon_deconfigure_mac_wrapper(struct efx_nic *efx);
137extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx); 134extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx);
138 135
139/* Interrupts and test events */ 136/* Interrupts and test events */
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index da750959c61a..b92decc9521b 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -352,7 +352,8 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
352 err = sfe4001_poweron(efx); 352 err = sfe4001_poweron(efx);
353 else 353 else
354 err = sfn4111t_reset(efx); 354 err = sfn4111t_reset(efx);
355 efx_reconfigure_port(efx); 355 if (!err)
356 err = efx_reconfigure_port(efx);
356 if (!(new_mode & PHY_MODE_SPECIAL)) 357 if (!(new_mode & PHY_MODE_SPECIAL))
357 falcon_start_nic_stats(efx); 358 falcon_start_nic_stats(efx);
358 } 359 }
diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c
index 66d499cc23f2..19dd3ac3d1c7 100644
--- a/drivers/net/sfc/falcon_gmac.c
+++ b/drivers/net/sfc/falcon_gmac.c
@@ -22,7 +22,7 @@
22 * 22 *
23 *************************************************************************/ 23 *************************************************************************/
24 24
25static void falcon_reconfigure_gmac(struct efx_nic *efx) 25static int falcon_reconfigure_gmac(struct efx_nic *efx)
26{ 26{
27 struct efx_link_state *link_state = &efx->link_state; 27 struct efx_link_state *link_state = &efx->link_state;
28 bool loopback, tx_fc, rx_fc, bytemode; 28 bool loopback, tx_fc, rx_fc, bytemode;
@@ -123,6 +123,8 @@ static void falcon_reconfigure_gmac(struct efx_nic *efx)
123 udelay(10); 123 udelay(10);
124 124
125 falcon_reconfigure_mac_wrapper(efx); 125 falcon_reconfigure_mac_wrapper(efx);
126
127 return 0;
126} 128}
127 129
128static void falcon_update_stats_gmac(struct efx_nic *efx) 130static void falcon_update_stats_gmac(struct efx_nic *efx)
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 60dc0975cfa4..898afc1b5ef1 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -112,7 +112,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
112} 112}
113 113
114/* Get status of XAUI link */ 114/* Get status of XAUI link */
115bool falcon_xaui_link_ok(struct efx_nic *efx) 115static bool falcon_xaui_link_ok(struct efx_nic *efx)
116{ 116{
117 efx_oword_t reg; 117 efx_oword_t reg;
118 bool align_done, link_ok = false; 118 bool align_done, link_ok = false;
@@ -143,7 +143,7 @@ bool falcon_xaui_link_ok(struct efx_nic *efx)
143 return link_ok; 143 return link_ok;
144} 144}
145 145
146static void falcon_reconfigure_xmac_core(struct efx_nic *efx) 146void falcon_reconfigure_xmac_core(struct efx_nic *efx)
147{ 147{
148 unsigned int max_frame_len; 148 unsigned int max_frame_len;
149 efx_oword_t reg; 149 efx_oword_t reg;
@@ -275,7 +275,7 @@ static bool falcon_xmac_check_fault(struct efx_nic *efx)
275 return !falcon_check_xaui_link_up(efx, 5); 275 return !falcon_check_xaui_link_up(efx, 5);
276} 276}
277 277
278static void falcon_reconfigure_xmac(struct efx_nic *efx) 278static int falcon_reconfigure_xmac(struct efx_nic *efx)
279{ 279{
280 falcon_mask_status_intr(efx, false); 280 falcon_mask_status_intr(efx, false);
281 281
@@ -286,6 +286,8 @@ static void falcon_reconfigure_xmac(struct efx_nic *efx)
286 286
287 efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 5); 287 efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 5);
288 falcon_mask_status_intr(efx, true); 288 falcon_mask_status_intr(efx, true);
289
290 return 0;
289} 291}
290 292
291static void falcon_update_stats_xmac(struct efx_nic *efx) 293static void falcon_update_stats_xmac(struct efx_nic *efx)
diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h
index 4e7074278fe1..d2af50f1747b 100644
--- a/drivers/net/sfc/mac.h
+++ b/drivers/net/sfc/mac.h
@@ -15,5 +15,6 @@
15 15
16extern struct efx_mac_operations falcon_gmac_operations; 16extern struct efx_mac_operations falcon_gmac_operations;
17extern struct efx_mac_operations falcon_xmac_operations; 17extern struct efx_mac_operations falcon_xmac_operations;
18extern void falcon_reconfigure_xmac_core(struct efx_nic *efx);
18 19
19#endif 20#endif
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 231e580acc9a..1f62a5c002fd 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -248,8 +248,6 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
248int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 248int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
249{ 249{
250 struct ethtool_cmd prev; 250 struct ethtool_cmd prev;
251 bool xnp;
252 int reg;
253 251
254 efx->phy_op->get_settings(efx, &prev); 252 efx->phy_op->get_settings(efx, &prev);
255 253
@@ -269,30 +267,47 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
269 (ecmd->advertising | SUPPORTED_Autoneg) & ~prev.supported) 267 (ecmd->advertising | SUPPORTED_Autoneg) & ~prev.supported)
270 return -EINVAL; 268 return -EINVAL;
271 269
272 xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full 270 efx_link_set_advertising(efx, ecmd->advertising | ADVERTISED_Autoneg);
273 || EFX_WORKAROUND_13204(efx)); 271 efx_mdio_an_reconfigure(efx);
272 return 0;
273}
274
275/**
276 * efx_mdio_an_reconfigure - Push advertising flags and restart autonegotiation
277 * @efx: Efx NIC
278 */
279void efx_mdio_an_reconfigure(struct efx_nic *efx)
280{
281 bool xnp = (efx->link_advertising & ADVERTISED_10000baseT_Full
282 || EFX_WORKAROUND_13204(efx));
283 int reg;
284
285 WARN_ON(!(efx->mdio.mmds & MDIO_DEVS_AN));
274 286
275 /* Set up the base page */ 287 /* Set up the base page */
276 reg = ADVERTISE_CSMA; 288 reg = ADVERTISE_CSMA;
277 if (ecmd->advertising & ADVERTISED_10baseT_Half) 289 if (efx->link_advertising & ADVERTISED_10baseT_Half)
278 reg |= ADVERTISE_10HALF; 290 reg |= ADVERTISE_10HALF;
279 if (ecmd->advertising & ADVERTISED_10baseT_Full) 291 if (efx->link_advertising & ADVERTISED_10baseT_Full)
280 reg |= ADVERTISE_10FULL; 292 reg |= ADVERTISE_10FULL;
281 if (ecmd->advertising & ADVERTISED_100baseT_Half) 293 if (efx->link_advertising & ADVERTISED_100baseT_Half)
282 reg |= ADVERTISE_100HALF; 294 reg |= ADVERTISE_100HALF;
283 if (ecmd->advertising & ADVERTISED_100baseT_Full) 295 if (efx->link_advertising & ADVERTISED_100baseT_Full)
284 reg |= ADVERTISE_100FULL; 296 reg |= ADVERTISE_100FULL;
285 if (xnp) 297 if (xnp)
286 reg |= ADVERTISE_RESV; 298 reg |= ADVERTISE_RESV;
287 else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | 299 else if (efx->link_advertising & (ADVERTISED_1000baseT_Half |
288 ADVERTISED_1000baseT_Full)) 300 ADVERTISED_1000baseT_Full))
289 reg |= ADVERTISE_NPAGE; 301 reg |= ADVERTISE_NPAGE;
290 reg |= mii_advertise_flowctrl(efx->wanted_fc); 302 if (efx->link_advertising & ADVERTISED_Pause)
303 reg |= ADVERTISE_PAUSE_CAP;
304 if (efx->link_advertising & ADVERTISED_Asym_Pause)
305 reg |= ADVERTISE_PAUSE_ASYM;
291 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); 306 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
292 307
293 /* Set up the (extended) next page if necessary */ 308 /* Set up the (extended) next page if necessary */
294 if (efx->phy_op->set_npage_adv) 309 if (efx->phy_op->set_npage_adv)
295 efx->phy_op->set_npage_adv(efx, ecmd->advertising); 310 efx->phy_op->set_npage_adv(efx, efx->link_advertising);
296 311
297 /* Enable and restart AN */ 312 /* Enable and restart AN */
298 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1); 313 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
@@ -305,8 +320,6 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
305 else 320 else
306 reg &= ~MDIO_AN_CTRL1_XNP; 321 reg &= ~MDIO_AN_CTRL1_XNP;
307 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg); 322 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
308
309 return 0;
310} 323}
311 324
312enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx) 325enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 75b37f101231..dbc8e7de2929 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -86,6 +86,9 @@ extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
86/* Set (some of) the PHY settings over MDIO */ 86/* Set (some of) the PHY settings over MDIO */
87extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); 87extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
88 88
89/* Push advertising flags and restart autonegotiation */
90extern void efx_mdio_an_reconfigure(struct efx_nic *efx);
91
89/* Get pause parameters from AN if available (otherwise return 92/* Get pause parameters from AN if available (otherwise return
90 * requested pause parameters) 93 * requested pause parameters)
91 */ 94 */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 32806f9a7e49..f63a05c4e38b 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -517,7 +517,7 @@ static inline bool efx_link_state_equal(const struct efx_link_state *left,
517 * @check_fault: Check fault state. True if fault present. 517 * @check_fault: Check fault state. True if fault present.
518 */ 518 */
519struct efx_mac_operations { 519struct efx_mac_operations {
520 void (*reconfigure) (struct efx_nic *efx); 520 int (*reconfigure) (struct efx_nic *efx);
521 void (*update_stats) (struct efx_nic *efx); 521 void (*update_stats) (struct efx_nic *efx);
522 bool (*check_fault)(struct efx_nic *efx); 522 bool (*check_fault)(struct efx_nic *efx);
523}; 523};
@@ -544,7 +544,7 @@ struct efx_phy_operations {
544 enum efx_mac_type macs; 544 enum efx_mac_type macs;
545 int (*init) (struct efx_nic *efx); 545 int (*init) (struct efx_nic *efx);
546 void (*fini) (struct efx_nic *efx); 546 void (*fini) (struct efx_nic *efx);
547 void (*reconfigure) (struct efx_nic *efx); 547 int (*reconfigure) (struct efx_nic *efx);
548 bool (*poll) (struct efx_nic *efx); 548 bool (*poll) (struct efx_nic *efx);
549 void (*get_settings) (struct efx_nic *efx, 549 void (*get_settings) (struct efx_nic *efx,
550 struct ethtool_cmd *ecmd); 550 struct ethtool_cmd *ecmd);
@@ -730,6 +730,7 @@ union efx_multicast_hash {
730 * @mdio: PHY MDIO interface 730 * @mdio: PHY MDIO interface
731 * @phy_mode: PHY operating mode. Serialised by @mac_lock. 731 * @phy_mode: PHY operating mode. Serialised by @mac_lock.
732 * @xmac_poll_required: XMAC link state needs polling 732 * @xmac_poll_required: XMAC link state needs polling
733 * @link_advertising: Autonegotiation advertising flags
733 * @link_state: Current state of the link 734 * @link_state: Current state of the link
734 * @n_link_state_changes: Number of times the link has changed state 735 * @n_link_state_changes: Number of times the link has changed state
735 * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. 736 * @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
@@ -813,6 +814,7 @@ struct efx_nic {
813 enum efx_phy_mode phy_mode; 814 enum efx_phy_mode phy_mode;
814 815
815 bool xmac_poll_required; 816 bool xmac_poll_required;
817 u32 link_advertising;
816 struct efx_link_state link_state; 818 struct efx_link_state link_state;
817 unsigned int n_link_state_changes; 819 unsigned int n_link_state_changes;
818 820
@@ -858,6 +860,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx)
858 * @stop_stats: Stop the regular fetching of statistics 860 * @stop_stats: Stop the regular fetching of statistics
859 * @push_irq_moderation: Apply interrupt moderation value 861 * @push_irq_moderation: Apply interrupt moderation value
860 * @push_multicast_hash: Apply multicast hash table 862 * @push_multicast_hash: Apply multicast hash table
863 * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY
861 * @default_mac_ops: efx_mac_operations to set at startup 864 * @default_mac_ops: efx_mac_operations to set at startup
862 * @revision: Hardware architecture revision 865 * @revision: Hardware architecture revision
863 * @mem_map_size: Memory BAR mapped size 866 * @mem_map_size: Memory BAR mapped size
@@ -890,6 +893,7 @@ struct efx_nic_type {
890 void (*stop_stats)(struct efx_nic *efx); 893 void (*stop_stats)(struct efx_nic *efx);
891 void (*push_irq_moderation)(struct efx_channel *channel); 894 void (*push_irq_moderation)(struct efx_channel *channel);
892 void (*push_multicast_hash)(struct efx_nic *efx); 895 void (*push_multicast_hash)(struct efx_nic *efx);
896 int (*reconfigure_port)(struct efx_nic *efx);
893 struct efx_mac_operations *default_mac_ops; 897 struct efx_mac_operations *default_mac_ops;
894 898
895 int revision; 899 int revision;
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index 3d7370e39787..4c38516a5525 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -178,7 +178,7 @@ static bool qt202x_phy_poll(struct efx_nic *efx)
178 return efx->link_state.up != was_up; 178 return efx->link_state.up != was_up;
179} 179}
180 180
181static void qt202x_phy_reconfigure(struct efx_nic *efx) 181static int qt202x_phy_reconfigure(struct efx_nic *efx)
182{ 182{
183 struct qt202x_phy_data *phy_data = efx->phy_data; 183 struct qt202x_phy_data *phy_data = efx->phy_data;
184 184
@@ -207,6 +207,8 @@ static void qt202x_phy_reconfigure(struct efx_nic *efx)
207 efx_mdio_phy_reconfigure(efx); 207 efx_mdio_phy_reconfigure(efx);
208 208
209 phy_data->phy_mode = efx->phy_mode; 209 phy_data->phy_mode = efx->phy_mode;
210
211 return 0;
210} 212}
211 213
212static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 214static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
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}
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 1bd79650a00f..c30185393cdc 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -199,15 +199,16 @@ static ssize_t set_phy_short_reach(struct device *dev,
199 const char *buf, size_t count) 199 const char *buf, size_t count)
200{ 200{
201 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 201 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
202 int rc;
202 203
203 rtnl_lock(); 204 rtnl_lock();
204 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, 205 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
205 MDIO_PMA_10GBT_TXPWR_SHORT, 206 MDIO_PMA_10GBT_TXPWR_SHORT,
206 count != 0 && *buf != '0'); 207 count != 0 && *buf != '0');
207 efx_reconfigure_port(efx); 208 rc = efx_reconfigure_port(efx);
208 rtnl_unlock(); 209 rtnl_unlock();
209 210
210 return count; 211 return rc < 0 ? rc : (ssize_t)count;
211} 212}
212 213
213static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach, 214static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
@@ -300,7 +301,6 @@ static int tenxpress_init(struct efx_nic *efx)
300static int tenxpress_phy_init(struct efx_nic *efx) 301static int tenxpress_phy_init(struct efx_nic *efx)
301{ 302{
302 struct tenxpress_phy_data *phy_data; 303 struct tenxpress_phy_data *phy_data;
303 u16 old_adv, adv;
304 int rc = 0; 304 int rc = 0;
305 305
306 falcon_board(efx)->type->init_phy(efx); 306 falcon_board(efx)->type->init_phy(efx);
@@ -335,14 +335,14 @@ static int tenxpress_phy_init(struct efx_nic *efx)
335 if (rc < 0) 335 if (rc < 0)
336 goto fail; 336 goto fail;
337 337
338 /* Set pause advertising */ 338 /* Initialise advertising flags */
339 old_adv = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 339 efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
340 adv = ((old_adv & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)) | 340 ADVERTISED_10000baseT_Full);
341 mii_advertise_flowctrl(efx->wanted_fc)); 341 if (efx->phy_type != PHY_TYPE_SFX7101)
342 if (adv != old_adv) { 342 efx->link_advertising |= (ADVERTISED_1000baseT_Full |
343 efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, adv); 343 ADVERTISED_100baseT_Full);
344 mdio45_nway_restart(&efx->mdio); 344 efx_link_set_wanted_fc(efx, efx->wanted_fc);
345 } 345 efx_mdio_an_reconfigure(efx);
346 346
347 if (efx->phy_type == PHY_TYPE_SFT9001B) { 347 if (efx->phy_type == PHY_TYPE_SFT9001B) {
348 rc = device_create_file(&efx->pci_dev->dev, 348 rc = device_create_file(&efx->pci_dev->dev,
@@ -500,49 +500,41 @@ static void tenxpress_low_power(struct efx_nic *efx)
500 !!(efx->phy_mode & PHY_MODE_LOW_POWER)); 500 !!(efx->phy_mode & PHY_MODE_LOW_POWER));
501} 501}
502 502
503static void tenxpress_phy_reconfigure(struct efx_nic *efx) 503static int tenxpress_phy_reconfigure(struct efx_nic *efx)
504{ 504{
505 struct tenxpress_phy_data *phy_data = efx->phy_data; 505 struct tenxpress_phy_data *phy_data = efx->phy_data;
506 struct ethtool_cmd ecmd;
507 bool phy_mode_change, loop_reset; 506 bool phy_mode_change, loop_reset;
508 507
509 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { 508 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
510 phy_data->phy_mode = efx->phy_mode; 509 phy_data->phy_mode = efx->phy_mode;
511 return; 510 return 0;
512 } 511 }
513 512
514 tenxpress_low_power(efx);
515
516 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && 513 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
517 phy_data->phy_mode != PHY_MODE_NORMAL); 514 phy_data->phy_mode != PHY_MODE_NORMAL);
518 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || 515 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
519 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); 516 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
520 517
521 if (loop_reset || phy_mode_change) { 518 if (loop_reset || phy_mode_change) {
522 int rc; 519 tenxpress_special_reset(efx);
523
524 efx->phy_op->get_settings(efx, &ecmd);
525 520
526 if (loop_reset || phy_mode_change) { 521 /* Reset XAUI if we were in 10G, and are staying
527 tenxpress_special_reset(efx); 522 * in 10G. If we're moving into and out of 10G
528 523 * then xaui will be reset anyway */
529 /* Reset XAUI if we were in 10G, and are staying 524 if (EFX_IS10G(efx))
530 * in 10G. If we're moving into and out of 10G 525 falcon_reset_xaui(efx);
531 * then xaui will be reset anyway */
532 if (EFX_IS10G(efx))
533 falcon_reset_xaui(efx);
534 }
535
536 rc = efx->phy_op->set_settings(efx, &ecmd);
537 WARN_ON(rc);
538 } 526 }
539 527
528 tenxpress_low_power(efx);
540 efx_mdio_transmit_disable(efx); 529 efx_mdio_transmit_disable(efx);
541 efx_mdio_phy_reconfigure(efx); 530 efx_mdio_phy_reconfigure(efx);
542 tenxpress_ext_loopback(efx); 531 tenxpress_ext_loopback(efx);
532 efx_mdio_an_reconfigure(efx);
543 533
544 phy_data->loopback_mode = efx->loopback_mode; 534 phy_data->loopback_mode = efx->loopback_mode;
545 phy_data->phy_mode = efx->phy_mode; 535 phy_data->phy_mode = efx->phy_mode;
536
537 return 0;
546} 538}
547 539
548static void 540static void
@@ -646,6 +638,9 @@ sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
646 /* BIST is automatically run after a special software reset */ 638 /* BIST is automatically run after a special software reset */
647 rc = tenxpress_special_reset(efx); 639 rc = tenxpress_special_reset(efx);
648 results[0] = rc ? -1 : 1; 640 results[0] = rc ? -1 : 1;
641
642 efx_mdio_an_reconfigure(efx);
643
649 return rc; 644 return rc;
650} 645}
651 646
@@ -663,12 +658,8 @@ static const char *const sft9001_test_names[] = {
663 658
664static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) 659static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
665{ 660{
666 struct ethtool_cmd ecmd;
667 int rc = 0, rc2, i, ctrl_reg, res_reg; 661 int rc = 0, rc2, i, ctrl_reg, res_reg;
668 662
669 if (flags & ETH_TEST_FL_OFFLINE)
670 efx->phy_op->get_settings(efx, &ecmd);
671
672 /* Initialise cable diagnostic results to unknown failure */ 663 /* Initialise cable diagnostic results to unknown failure */
673 for (i = 1; i < 9; ++i) 664 for (i = 1; i < 9; ++i)
674 results[i] = -1; 665 results[i] = -1;
@@ -720,9 +711,7 @@ out:
720 if (!rc) 711 if (!rc)
721 rc = rc2; 712 rc = rc2;
722 713
723 rc2 = efx->phy_op->set_settings(efx, &ecmd); 714 efx_mdio_an_reconfigure(efx);
724 if (!rc)
725 rc = rc2;
726 } 715 }
727 716
728 return rc; 717 return rc;
@@ -753,7 +742,6 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
753 742
754 mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); 743 mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
755 744
756 ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
757 if (efx->phy_type != PHY_TYPE_SFX7101) { 745 if (efx->phy_type != PHY_TYPE_SFX7101) {
758 ecmd->supported |= (SUPPORTED_100baseT_Full | 746 ecmd->supported |= (SUPPORTED_100baseT_Full |
759 SUPPORTED_1000baseT_Full); 747 SUPPORTED_1000baseT_Full);