aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-12-13 00:50:08 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 00:58:17 -0500
commit177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97 (patch)
treea6e5e9949f388d48ac20c4efbb2811762ac5f9d4 /drivers
parent356eebb2b3af24cc701823f1e025f04eef333239 (diff)
sfc: Add support for sub-10G speeds
The SFC4000 has a separate MAC for use at sub-10G speeds. Introduce an efx_mac_operations structure with implementations for the two MACs. Switch between the MACs as necessary. PHY settings are independent of the MAC, so add get_settings() and set_settings() to efx_phy_operations. Also add macs field to indicate which MACs the PHY is connected to. 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/Makefile4
-rw-r--r--drivers/net/sfc/efx.c62
-rw-r--r--drivers/net/sfc/enum.h29
-rw-r--r--drivers/net/sfc/ethtool.c38
-rw-r--r--drivers/net/sfc/falcon.c179
-rw-r--r--drivers/net/sfc/falcon.h3
-rw-r--r--drivers/net/sfc/falcon_gmac.c233
-rw-r--r--drivers/net/sfc/falcon_hwdefs.h156
-rw-r--r--drivers/net/sfc/falcon_xmac.c222
-rw-r--r--drivers/net/sfc/mac.h16
-rw-r--r--drivers/net/sfc/net_driver.h31
-rw-r--r--drivers/net/sfc/selftest.c26
-rw-r--r--drivers/net/sfc/selftest.h2
-rw-r--r--drivers/net/sfc/sfe4001.c2
-rw-r--r--drivers/net/sfc/tenxpress.c10
-rw-r--r--drivers/net/sfc/xfp_phy.c7
16 files changed, 699 insertions, 321 deletions
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index e507daa4f0e8..b89f9be3cb13 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -1,5 +1,5 @@
1sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \ 1sfc-y += efx.o falcon.o tx.o rx.o falcon_gmac.o \
2 selftest.o ethtool.o xfp_phy.o \ 2 falcon_xmac.o selftest.o ethtool.o xfp_phy.o \
3 mdio_10g.o tenxpress.o boards.o sfe4001.o 3 mdio_10g.o tenxpress.o boards.o sfe4001.o
4sfc-$(CONFIG_SFC_MTD) += mtd.o 4sfc-$(CONFIG_SFC_MTD) += mtd.o
5 5
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 90820d4046f8..7214ea6f7e1d 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -27,7 +27,6 @@
27#include "efx.h" 27#include "efx.h"
28#include "mdio_10g.h" 28#include "mdio_10g.h"
29#include "falcon.h" 29#include "falcon.h"
30#include "mac.h"
31 30
32#define EFX_MAX_MTU (9 * 1024) 31#define EFX_MAX_MTU (9 * 1024)
33 32
@@ -575,10 +574,28 @@ void __efx_reconfigure_port(struct efx_nic *efx)
575 netif_addr_unlock_bh(efx->net_dev); 574 netif_addr_unlock_bh(efx->net_dev);
576 } 575 }
577 576
578 falcon_reconfigure_xmac(efx); 577 falcon_deconfigure_mac_wrapper(efx);
578
579 /* Reconfigure the PHY, disabling transmit in mac level loopback. */
580 if (LOOPBACK_INTERNAL(efx))
581 efx->phy_mode |= PHY_MODE_TX_DISABLED;
582 else
583 efx->phy_mode &= ~PHY_MODE_TX_DISABLED;
584 efx->phy_op->reconfigure(efx);
585
586 if (falcon_switch_mac(efx))
587 goto fail;
588
589 efx->mac_op->reconfigure(efx);
579 590
580 /* Inform kernel of loss/gain of carrier */ 591 /* Inform kernel of loss/gain of carrier */
581 efx_link_status_changed(efx); 592 efx_link_status_changed(efx);
593 return;
594
595fail:
596 EFX_ERR(efx, "failed to reconfigure MAC\n");
597 efx->phy_op->fini(efx);
598 efx->port_initialized = false;
582} 599}
583 600
584/* Reinitialise the MAC to pick up new PHY settings, even if the port is 601/* Reinitialise the MAC to pick up new PHY settings, even if the port is
@@ -648,18 +665,25 @@ static int efx_init_port(struct efx_nic *efx)
648 665
649 EFX_LOG(efx, "init port\n"); 666 EFX_LOG(efx, "init port\n");
650 667
651 /* Initialise the MAC and PHY */ 668 rc = efx->phy_op->init(efx);
652 rc = falcon_init_xmac(efx);
653 if (rc) 669 if (rc)
654 return rc; 670 return rc;
671 efx->phy_op->reconfigure(efx);
672
673 mutex_lock(&efx->mac_lock);
674 rc = falcon_switch_mac(efx);
675 mutex_unlock(&efx->mac_lock);
676 if (rc)
677 goto fail;
678 efx->mac_op->reconfigure(efx);
655 679
656 efx->port_initialized = true; 680 efx->port_initialized = true;
657 efx->stats_enabled = true; 681 efx->stats_enabled = true;
658
659 /* Reconfigure port to program MAC registers */
660 falcon_reconfigure_xmac(efx);
661
662 return 0; 682 return 0;
683
684fail:
685 efx->phy_op->fini(efx);
686 return rc;
663} 687}
664 688
665/* Allow efx_reconfigure_port() to be scheduled, and close the window 689/* Allow efx_reconfigure_port() to be scheduled, and close the window
@@ -702,7 +726,7 @@ static void efx_fini_port(struct efx_nic *efx)
702 if (!efx->port_initialized) 726 if (!efx->port_initialized)
703 return; 727 return;
704 728
705 falcon_fini_xmac(efx); 729 efx->phy_op->fini(efx);
706 efx->port_initialized = false; 730 efx->port_initialized = false;
707 731
708 efx->link_up = false; 732 efx->link_up = false;
@@ -1179,7 +1203,6 @@ static void efx_monitor(struct work_struct *data)
1179{ 1203{
1180 struct efx_nic *efx = container_of(data, struct efx_nic, 1204 struct efx_nic *efx = container_of(data, struct efx_nic,
1181 monitor_work.work); 1205 monitor_work.work);
1182 int rc = 0;
1183 1206
1184 EFX_TRACE(efx, "hardware monitor executing on CPU %d\n", 1207 EFX_TRACE(efx, "hardware monitor executing on CPU %d\n",
1185 raw_smp_processor_id()); 1208 raw_smp_processor_id());
@@ -1195,7 +1218,7 @@ static void efx_monitor(struct work_struct *data)
1195 } 1218 }
1196 1219
1197 if (efx->port_enabled) 1220 if (efx->port_enabled)
1198 rc = falcon_check_xmac(efx); 1221 efx->mac_op->check_hw(efx);
1199 mutex_unlock(&efx->mac_lock); 1222 mutex_unlock(&efx->mac_lock);
1200 1223
1201 queue_delayed_work(efx->workqueue, &efx->monitor_work, 1224 queue_delayed_work(efx->workqueue, &efx->monitor_work,
@@ -1331,7 +1354,7 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
1331 if (!spin_trylock(&efx->stats_lock)) 1354 if (!spin_trylock(&efx->stats_lock))
1332 return stats; 1355 return stats;
1333 if (efx->stats_enabled) { 1356 if (efx->stats_enabled) {
1334 falcon_update_stats_xmac(efx); 1357 efx->mac_op->update_stats(efx);
1335 falcon_update_nic_stats(efx); 1358 falcon_update_nic_stats(efx);
1336 } 1359 }
1337 spin_unlock(&efx->stats_lock); 1360 spin_unlock(&efx->stats_lock);
@@ -1519,7 +1542,7 @@ static int efx_register_netdev(struct efx_nic *efx)
1519 netif_carrier_off(efx->net_dev); 1542 netif_carrier_off(efx->net_dev);
1520 1543
1521 /* Clear MAC statistics */ 1544 /* Clear MAC statistics */
1522 falcon_update_stats_xmac(efx); 1545 efx->mac_op->update_stats(efx);
1523 memset(&efx->mac_stats, 0, sizeof(efx->mac_stats)); 1546 memset(&efx->mac_stats, 0, sizeof(efx->mac_stats));
1524 1547
1525 rc = register_netdev(net_dev); 1548 rc = register_netdev(net_dev);
@@ -1575,8 +1598,6 @@ static void efx_unregister_netdev(struct efx_nic *efx)
1575 * before reset. */ 1598 * before reset. */
1576void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) 1599void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
1577{ 1600{
1578 int rc;
1579
1580 EFX_ASSERT_RESET_SERIALISED(efx); 1601 EFX_ASSERT_RESET_SERIALISED(efx);
1581 1602
1582 /* The net_dev->get_stats handler is quite slow, and will fail 1603 /* The net_dev->get_stats handler is quite slow, and will fail
@@ -1589,9 +1610,7 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
1589 mutex_lock(&efx->mac_lock); 1610 mutex_lock(&efx->mac_lock);
1590 mutex_lock(&efx->spi_lock); 1611 mutex_lock(&efx->spi_lock);
1591 1612
1592 rc = falcon_xmac_get_settings(efx, ecmd); 1613 efx->phy_op->get_settings(efx, ecmd);
1593 if (rc)
1594 EFX_ERR(efx, "could not back up PHY settings\n");
1595 1614
1596 efx_fini_channels(efx); 1615 efx_fini_channels(efx);
1597} 1616}
@@ -1616,7 +1635,7 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
1616 if (ok) { 1635 if (ok) {
1617 efx_init_channels(efx); 1636 efx_init_channels(efx);
1618 1637
1619 if (falcon_xmac_set_settings(efx, ecmd)) 1638 if (efx->phy_op->set_settings(efx, ecmd))
1620 EFX_ERR(efx, "could not restore PHY settings\n"); 1639 EFX_ERR(efx, "could not restore PHY settings\n");
1621 } 1640 }
1622 1641
@@ -1779,6 +1798,10 @@ int efx_port_dummy_op_int(struct efx_nic *efx)
1779void efx_port_dummy_op_void(struct efx_nic *efx) {} 1798void efx_port_dummy_op_void(struct efx_nic *efx) {}
1780void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {} 1799void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {}
1781 1800
1801static struct efx_mac_operations efx_dummy_mac_operations = {
1802 .reconfigure = efx_port_dummy_op_void,
1803};
1804
1782static struct efx_phy_operations efx_dummy_phy_operations = { 1805static struct efx_phy_operations efx_dummy_phy_operations = {
1783 .init = efx_port_dummy_op_int, 1806 .init = efx_port_dummy_op_int,
1784 .reconfigure = efx_port_dummy_op_void, 1807 .reconfigure = efx_port_dummy_op_void,
@@ -1831,6 +1854,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
1831 spin_lock_init(&efx->netif_stop_lock); 1854 spin_lock_init(&efx->netif_stop_lock);
1832 spin_lock_init(&efx->stats_lock); 1855 spin_lock_init(&efx->stats_lock);
1833 mutex_init(&efx->mac_lock); 1856 mutex_init(&efx->mac_lock);
1857 efx->mac_op = &efx_dummy_mac_operations;
1834 efx->phy_op = &efx_dummy_phy_operations; 1858 efx->phy_op = &efx_dummy_phy_operations;
1835 efx->mii.dev = net_dev; 1859 efx->mii.dev = net_dev;
1836 INIT_WORK(&efx->reconfigure_work, efx_reconfigure_work); 1860 INIT_WORK(&efx->reconfigure_work, efx_reconfigure_work);
diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h
index 41e758e8fdb1..0c2e41ce8b4a 100644
--- a/drivers/net/sfc/enum.h
+++ b/drivers/net/sfc/enum.h
@@ -1,6 +1,6 @@
1/**************************************************************************** 1/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards 2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2007 Solarflare Communications Inc. 3 * Copyright 2007-2008 Solarflare Communications Inc.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published 6 * under the terms of the GNU General Public License version 2 as published
@@ -13,22 +13,24 @@
13/** 13/**
14 * enum efx_loopback_mode - loopback modes 14 * enum efx_loopback_mode - loopback modes
15 * @LOOPBACK_NONE: no loopback 15 * @LOOPBACK_NONE: no loopback
16 * @LOOPBACK_XGMII: loopback within MAC at XGMII level 16 * @LOOPBACK_GMAC: loopback within GMAC at unspecified level
17 * @LOOPBACK_XGXS: loopback within MAC at XGXS level 17 * @LOOPBACK_XGMII: loopback within XMAC at XGMII level
18 * @LOOPBACK_XAUI: loopback within MAC at XAUI level 18 * @LOOPBACK_XGXS: loopback within XMAC at XGXS level
19 * @LOOPBACK_PHYXS: loopback within PHY at PHYXS level 19 * @LOOPBACK_XAUI: loopback within XMAC at XAUI level
20 * @LOOPBACK_PCS: loopback within PHY at PCS level 20 * @LOOPBACK_GPHY: loopback within 1G PHY at unspecified level
21 * @LOOPBACK_PMAPMD: loopback within PHY at PMAPMD level 21 * @LOOPBACK_PHYXS: loopback within 10G PHY at PHYXS level
22 * @LOOPBACK_PCS: loopback within 10G PHY at PCS level
23 * @LOOPBACK_PMAPMD: loopback within 10G PHY at PMAPMD level
22 * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!) 24 * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!)
23 */ 25 */
24/* Please keep in order and up-to-date w.r.t the following two #defines */ 26/* Please keep in order and up-to-date w.r.t the following two #defines */
25enum efx_loopback_mode { 27enum efx_loopback_mode {
26 LOOPBACK_NONE = 0, 28 LOOPBACK_NONE = 0,
27 LOOPBACK_MAC = 1, 29 LOOPBACK_GMAC = 1,
28 LOOPBACK_XGMII = 2, 30 LOOPBACK_XGMII = 2,
29 LOOPBACK_XGXS = 3, 31 LOOPBACK_XGXS = 3,
30 LOOPBACK_XAUI = 4, 32 LOOPBACK_XAUI = 4,
31 LOOPBACK_PHY = 5, 33 LOOPBACK_GPHY = 5,
32 LOOPBACK_PHYXS = 6, 34 LOOPBACK_PHYXS = 6,
33 LOOPBACK_PCS = 7, 35 LOOPBACK_PCS = 7,
34 LOOPBACK_PMAPMD = 8, 36 LOOPBACK_PMAPMD = 8,
@@ -45,15 +47,16 @@ extern const char *efx_loopback_mode_names[];
45 LOOPBACK_MODE_NAME(efx->loopback_mode) 47 LOOPBACK_MODE_NAME(efx->loopback_mode)
46 48
47/* These loopbacks occur within the controller */ 49/* These loopbacks occur within the controller */
48#define LOOPBACKS_10G_INTERNAL ((1 << LOOPBACK_XGMII)| \ 50#define LOOPBACKS_INTERNAL ((1 << LOOPBACK_GMAC) | \
49 (1 << LOOPBACK_XGXS) | \ 51 (1 << LOOPBACK_XGMII)| \
50 (1 << LOOPBACK_XAUI)) 52 (1 << LOOPBACK_XGXS) | \
53 (1 << LOOPBACK_XAUI))
51 54
52#define LOOPBACK_MASK(_efx) \ 55#define LOOPBACK_MASK(_efx) \
53 (1 << (_efx)->loopback_mode) 56 (1 << (_efx)->loopback_mode)
54 57
55#define LOOPBACK_INTERNAL(_efx) \ 58#define LOOPBACK_INTERNAL(_efx) \
56 (!!(LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx))) 59 (!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx)))
57 60
58#define LOOPBACK_OUT_OF(_from, _to, _mask) \ 61#define LOOPBACK_OUT_OF(_from, _to, _mask) \
59 ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask))) 62 ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask)))
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 43d6d8b4429a..1b33f89df4d5 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -17,15 +17,14 @@
17#include "ethtool.h" 17#include "ethtool.h"
18#include "falcon.h" 18#include "falcon.h"
19#include "spi.h" 19#include "spi.h"
20#include "mac.h"
21 20
22const char *efx_loopback_mode_names[] = { 21const char *efx_loopback_mode_names[] = {
23 [LOOPBACK_NONE] = "NONE", 22 [LOOPBACK_NONE] = "NONE",
24 [LOOPBACK_MAC] = "MAC", 23 [LOOPBACK_GMAC] = "GMAC",
25 [LOOPBACK_XGMII] = "XGMII", 24 [LOOPBACK_XGMII] = "XGMII",
26 [LOOPBACK_XGXS] = "XGXS", 25 [LOOPBACK_XGXS] = "XGXS",
27 [LOOPBACK_XAUI] = "XAUI", 26 [LOOPBACK_XAUI] = "XAUI",
28 [LOOPBACK_PHY] = "PHY", 27 [LOOPBACK_GPHY] = "GPHY",
29 [LOOPBACK_PHYXS] = "PHYXS", 28 [LOOPBACK_PHYXS] = "PHYXS",
30 [LOOPBACK_PCS] = "PCS", 29 [LOOPBACK_PCS] = "PCS",
31 [LOOPBACK_PMAPMD] = "PMA/PMD", 30 [LOOPBACK_PMAPMD] = "PMA/PMD",
@@ -200,13 +199,15 @@ int efx_ethtool_get_settings(struct net_device *net_dev,
200 struct ethtool_cmd *ecmd) 199 struct ethtool_cmd *ecmd)
201{ 200{
202 struct efx_nic *efx = netdev_priv(net_dev); 201 struct efx_nic *efx = netdev_priv(net_dev);
203 int rc;
204 202
205 mutex_lock(&efx->mac_lock); 203 mutex_lock(&efx->mac_lock);
206 rc = falcon_xmac_get_settings(efx, ecmd); 204 efx->phy_op->get_settings(efx, ecmd);
207 mutex_unlock(&efx->mac_lock); 205 mutex_unlock(&efx->mac_lock);
208 206
209 return rc; 207 /* Falcon GMAC does not support 1000Mbps HD */
208 ecmd->supported &= ~SUPPORTED_1000baseT_Half;
209
210 return 0;
210} 211}
211 212
212/* This must be called with rtnl_lock held. */ 213/* This must be called with rtnl_lock held. */
@@ -216,8 +217,15 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
216 struct efx_nic *efx = netdev_priv(net_dev); 217 struct efx_nic *efx = netdev_priv(net_dev);
217 int rc; 218 int rc;
218 219
220 /* Falcon GMAC does not support 1000Mbps HD */
221 if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
222 EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
223 " setting\n");
224 return -EINVAL;
225 }
226
219 mutex_lock(&efx->mac_lock); 227 mutex_lock(&efx->mac_lock);
220 rc = falcon_xmac_set_settings(efx, ecmd); 228 rc = efx->phy_op->set_settings(efx, ecmd);
221 mutex_unlock(&efx->mac_lock); 229 mutex_unlock(&efx->mac_lock);
222 if (!rc) 230 if (!rc)
223 efx_reconfigure_port(efx); 231 efx_reconfigure_port(efx);
@@ -362,10 +370,6 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
362 EFX_PORT_NAME, "phy", NULL); 370 EFX_PORT_NAME, "phy", NULL);
363 371
364 /* Loopback tests */ 372 /* Loopback tests */
365 efx_fill_test(n++, strings, data, &tests->loopback_speed,
366 EFX_PORT_NAME, "loopback.speed", NULL);
367 efx_fill_test(n++, strings, data, &tests->loopback_full_duplex,
368 EFX_PORT_NAME, "loopback.full_duplex", NULL);
369 for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { 373 for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) {
370 if (!(efx->loopback_modes & (1 << mode))) 374 if (!(efx->loopback_modes & (1 << mode)))
371 continue; 375 continue;
@@ -671,22 +675,14 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
671{ 675{
672 struct efx_nic *efx = netdev_priv(net_dev); 676 struct efx_nic *efx = netdev_priv(net_dev);
673 enum efx_fc_type flow_control = efx->flow_control; 677 enum efx_fc_type flow_control = efx->flow_control;
674 int rc;
675 678
676 flow_control &= ~(EFX_FC_RX | EFX_FC_TX | EFX_FC_AUTO); 679 flow_control &= ~(EFX_FC_RX | EFX_FC_TX | EFX_FC_AUTO);
677 flow_control |= pause->rx_pause ? EFX_FC_RX : 0; 680 flow_control |= pause->rx_pause ? EFX_FC_RX : 0;
678 flow_control |= pause->tx_pause ? EFX_FC_TX : 0; 681 flow_control |= pause->tx_pause ? EFX_FC_TX : 0;
679 flow_control |= pause->autoneg ? EFX_FC_AUTO : 0; 682 flow_control |= pause->autoneg ? EFX_FC_AUTO : 0;
680 683
681 /* Try to push the pause parameters */ 684 efx_reconfigure_port(efx);
682 mutex_lock(&efx->mac_lock); 685 return 0;
683 rc = falcon_xmac_set_pause(efx, flow_control);
684 mutex_unlock(&efx->mac_lock);
685
686 if (!rc)
687 efx_reconfigure_port(efx);
688
689 return rc;
690} 686}
691 687
692static void efx_ethtool_get_pauseparam(struct net_device *net_dev, 688static 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 448bba9eed09..f09eded40fba 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1168,6 +1168,19 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic)
1168 falcon_generate_event(channel, &test_event); 1168 falcon_generate_event(channel, &test_event);
1169} 1169}
1170 1170
1171void falcon_sim_phy_event(struct efx_nic *efx)
1172{
1173 efx_qword_t phy_event;
1174
1175 EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE);
1176 if (EFX_IS10G(efx))
1177 EFX_SET_OWORD_FIELD(phy_event, XG_PHY_INTR, 1);
1178 else
1179 EFX_SET_OWORD_FIELD(phy_event, G_PHY0_INTR, 1);
1180
1181 falcon_generate_event(&efx->channel[0], &phy_event);
1182}
1183
1171/************************************************************************** 1184/**************************************************************************
1172 * 1185 *
1173 * Flush handling 1186 * Flush handling
@@ -1839,40 +1852,61 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
1839 * 1852 *
1840 ************************************************************************** 1853 **************************************************************************
1841 */ 1854 */
1842void falcon_drain_tx_fifo(struct efx_nic *efx) 1855
1856static int falcon_reset_macs(struct efx_nic *efx)
1843{ 1857{
1844 efx_oword_t temp; 1858 efx_oword_t reg;
1845 int count; 1859 int count;
1846 1860
1847 if ((falcon_rev(efx) < FALCON_REV_B0) || 1861 if (falcon_rev(efx) < FALCON_REV_B0) {
1848 (efx->loopback_mode != LOOPBACK_NONE)) 1862 /* It's not safe to use GLB_CTL_REG to reset the
1849 return; 1863 * macs, so instead use the internal MAC resets
1864 */
1865 if (!EFX_IS10G(efx)) {
1866 EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 1);
1867 falcon_write(efx, &reg, GM_CFG1_REG);
1868 udelay(1000);
1869
1870 EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 0);
1871 falcon_write(efx, &reg, GM_CFG1_REG);
1872 udelay(1000);
1873 return 0;
1874 } else {
1875 EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1);
1876 falcon_write(efx, &reg, XM_GLB_CFG_REG);
1877
1878 for (count = 0; count < 10000; count++) {
1879 falcon_read(efx, &reg, XM_GLB_CFG_REG);
1880 if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0)
1881 return 0;
1882 udelay(10);
1883 }
1850 1884
1851 falcon_read(efx, &temp, MAC0_CTRL_REG_KER); 1885 EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
1852 /* There is no point in draining more than once */ 1886 return -ETIMEDOUT;
1853 if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) 1887 }
1854 return; 1888 }
1855 1889
1856 /* MAC stats will fail whilst the TX fifo is draining. Serialise 1890 /* MAC stats will fail whilst the TX fifo is draining. Serialise
1857 * the drain sequence with the statistics fetch */ 1891 * the drain sequence with the statistics fetch */
1858 spin_lock(&efx->stats_lock); 1892 spin_lock(&efx->stats_lock);
1859 1893
1860 EFX_SET_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0, 1); 1894 falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
1861 falcon_write(efx, &temp, MAC0_CTRL_REG_KER); 1895 EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1);
1896 falcon_write(efx, &reg, MAC0_CTRL_REG_KER);
1862 1897
1863 /* Reset the MAC and EM block. */ 1898 falcon_read(efx, &reg, GLB_CTL_REG_KER);
1864 falcon_read(efx, &temp, GLB_CTL_REG_KER); 1899 EFX_SET_OWORD_FIELD(reg, RST_XGTX, 1);
1865 EFX_SET_OWORD_FIELD(temp, RST_XGTX, 1); 1900 EFX_SET_OWORD_FIELD(reg, RST_XGRX, 1);
1866 EFX_SET_OWORD_FIELD(temp, RST_XGRX, 1); 1901 EFX_SET_OWORD_FIELD(reg, RST_EM, 1);
1867 EFX_SET_OWORD_FIELD(temp, RST_EM, 1); 1902 falcon_write(efx, &reg, GLB_CTL_REG_KER);
1868 falcon_write(efx, &temp, GLB_CTL_REG_KER);
1869 1903
1870 count = 0; 1904 count = 0;
1871 while (1) { 1905 while (1) {
1872 falcon_read(efx, &temp, GLB_CTL_REG_KER); 1906 falcon_read(efx, &reg, GLB_CTL_REG_KER);
1873 if (!EFX_OWORD_FIELD(temp, RST_XGTX) && 1907 if (!EFX_OWORD_FIELD(reg, RST_XGTX) &&
1874 !EFX_OWORD_FIELD(temp, RST_XGRX) && 1908 !EFX_OWORD_FIELD(reg, RST_XGRX) &&
1875 !EFX_OWORD_FIELD(temp, RST_EM)) { 1909 !EFX_OWORD_FIELD(reg, RST_EM)) {
1876 EFX_LOG(efx, "Completed MAC reset after %d loops\n", 1910 EFX_LOG(efx, "Completed MAC reset after %d loops\n",
1877 count); 1911 count);
1878 break; 1912 break;
@@ -1889,21 +1923,39 @@ void falcon_drain_tx_fifo(struct efx_nic *efx)
1889 1923
1890 /* If we've reset the EM block and the link is up, then 1924 /* If we've reset the EM block and the link is up, then
1891 * we'll have to kick the XAUI link so the PHY can recover */ 1925 * we'll have to kick the XAUI link so the PHY can recover */
1892 if (efx->link_up && EFX_WORKAROUND_5147(efx)) 1926 if (efx->link_up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx))
1893 falcon_reset_xaui(efx); 1927 falcon_reset_xaui(efx);
1928
1929 return 0;
1930}
1931
1932void falcon_drain_tx_fifo(struct efx_nic *efx)
1933{
1934 efx_oword_t reg;
1935
1936 if ((falcon_rev(efx) < FALCON_REV_B0) ||
1937 (efx->loopback_mode != LOOPBACK_NONE))
1938 return;
1939
1940 falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
1941 /* There is no point in draining more than once */
1942 if (EFX_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0))
1943 return;
1944
1945 falcon_reset_macs(efx);
1894} 1946}
1895 1947
1896void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) 1948void falcon_deconfigure_mac_wrapper(struct efx_nic *efx)
1897{ 1949{
1898 efx_oword_t temp; 1950 efx_oword_t reg;
1899 1951
1900 if (falcon_rev(efx) < FALCON_REV_B0) 1952 if (falcon_rev(efx) < FALCON_REV_B0)
1901 return; 1953 return;
1902 1954
1903 /* Isolate the MAC -> RX */ 1955 /* Isolate the MAC -> RX */
1904 falcon_read(efx, &temp, RX_CFG_REG_KER); 1956 falcon_read(efx, &reg, RX_CFG_REG_KER);
1905 EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 0); 1957 EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 0);
1906 falcon_write(efx, &temp, RX_CFG_REG_KER); 1958 falcon_write(efx, &reg, RX_CFG_REG_KER);
1907 1959
1908 if (!efx->link_up) 1960 if (!efx->link_up)
1909 falcon_drain_tx_fifo(efx); 1961 falcon_drain_tx_fifo(efx);
@@ -2030,7 +2082,8 @@ static int falcon_gmii_wait(struct efx_nic *efx)
2030 efx_dword_t md_stat; 2082 efx_dword_t md_stat;
2031 int count; 2083 int count;
2032 2084
2033 for (count = 0; count < 1000; count++) { /* wait upto 10ms */ 2085 /* wait upto 50ms - taken max from datasheet */
2086 for (count = 0; count < 5000; count++) {
2034 falcon_readl(efx, &md_stat, MD_STAT_REG_KER); 2087 falcon_readl(efx, &md_stat, MD_STAT_REG_KER);
2035 if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) { 2088 if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) {
2036 if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 || 2089 if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 ||
@@ -2206,10 +2259,59 @@ static int falcon_probe_phy(struct efx_nic *efx)
2206 return -1; 2259 return -1;
2207 } 2260 }
2208 2261
2209 efx->loopback_modes = LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks; 2262 if (efx->phy_op->macs & EFX_XMAC)
2263 efx->loopback_modes |= ((1 << LOOPBACK_XGMII) |
2264 (1 << LOOPBACK_XGXS) |
2265 (1 << LOOPBACK_XAUI));
2266 if (efx->phy_op->macs & EFX_GMAC)
2267 efx->loopback_modes |= (1 << LOOPBACK_GMAC);
2268 efx->loopback_modes |= efx->phy_op->loopbacks;
2269
2210 return 0; 2270 return 0;
2211} 2271}
2212 2272
2273int falcon_switch_mac(struct efx_nic *efx)
2274{
2275 struct efx_mac_operations *old_mac_op = efx->mac_op;
2276 efx_oword_t nic_stat;
2277 unsigned strap_val;
2278
2279 /* Internal loopbacks override the phy speed setting */
2280 if (efx->loopback_mode == LOOPBACK_GMAC) {
2281 efx->link_speed = 1000;
2282 efx->link_fd = true;
2283 } else if (LOOPBACK_INTERNAL(efx)) {
2284 efx->link_speed = 10000;
2285 efx->link_fd = true;
2286 }
2287
2288 efx->mac_op = (EFX_IS10G(efx) ?
2289 &falcon_xmac_operations : &falcon_gmac_operations);
2290 if (old_mac_op == efx->mac_op)
2291 return 0;
2292
2293 WARN_ON(!mutex_is_locked(&efx->mac_lock));
2294
2295 /* Not all macs support a mac-level link state */
2296 efx->mac_up = true;
2297
2298 falcon_read(efx, &nic_stat, NIC_STAT_REG);
2299 strap_val = EFX_IS10G(efx) ? 5 : 3;
2300 if (falcon_rev(efx) >= FALCON_REV_B0) {
2301 EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_EN, 1);
2302 EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_OVR, strap_val);
2303 falcon_write(efx, &nic_stat, NIC_STAT_REG);
2304 } else {
2305 /* Falcon A1 does not support 1G/10G speed switching
2306 * and must not be used with a PHY that does. */
2307 BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val);
2308 }
2309
2310
2311 EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
2312 return falcon_reset_macs(efx);
2313}
2314
2213/* This call is responsible for hooking in the MAC and PHY operations */ 2315/* This call is responsible for hooking in the MAC and PHY operations */
2214int falcon_probe_port(struct efx_nic *efx) 2316int falcon_probe_port(struct efx_nic *efx)
2215{ 2317{
@@ -2362,6 +2464,10 @@ static struct {
2362 EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) }, 2464 EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) },
2363 { DP_CTRL_REG, 2465 { DP_CTRL_REG,
2364 EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) }, 2466 EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) },
2467 { GM_CFG2_REG,
2468 EFX_OWORD32(0x00007337, 0x00000000, 0x00000000, 0x00000000) },
2469 { GMF_CFG0_REG,
2470 EFX_OWORD32(0x00001F1F, 0x00000000, 0x00000000, 0x00000000) },
2365 { XM_GLB_CFG_REG, 2471 { XM_GLB_CFG_REG,
2366 EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) }, 2472 EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) },
2367 { XM_TX_CFG_REG, 2473 { XM_TX_CFG_REG,
@@ -2687,6 +2793,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
2687static int falcon_probe_nic_variant(struct efx_nic *efx) 2793static int falcon_probe_nic_variant(struct efx_nic *efx)
2688{ 2794{
2689 efx_oword_t altera_build; 2795 efx_oword_t altera_build;
2796 efx_oword_t nic_stat;
2690 2797
2691 falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER); 2798 falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER);
2692 if (EFX_OWORD_FIELD(altera_build, VER_ALL)) { 2799 if (EFX_OWORD_FIELD(altera_build, VER_ALL)) {
@@ -2694,27 +2801,20 @@ static int falcon_probe_nic_variant(struct efx_nic *efx)
2694 return -ENODEV; 2801 return -ENODEV;
2695 } 2802 }
2696 2803
2804 falcon_read(efx, &nic_stat, NIC_STAT_REG);
2805
2697 switch (falcon_rev(efx)) { 2806 switch (falcon_rev(efx)) {
2698 case FALCON_REV_A0: 2807 case FALCON_REV_A0:
2699 case 0xff: 2808 case 0xff:
2700 EFX_ERR(efx, "Falcon rev A0 not supported\n"); 2809 EFX_ERR(efx, "Falcon rev A0 not supported\n");
2701 return -ENODEV; 2810 return -ENODEV;
2702 2811
2703 case FALCON_REV_A1:{ 2812 case FALCON_REV_A1:
2704 efx_oword_t nic_stat;
2705
2706 falcon_read(efx, &nic_stat, NIC_STAT_REG);
2707
2708 if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) { 2813 if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) {
2709 EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); 2814 EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n");
2710 return -ENODEV; 2815 return -ENODEV;
2711 } 2816 }
2712 if (!EFX_OWORD_FIELD(nic_stat, STRAP_10G)) {
2713 EFX_ERR(efx, "1G mode not supported\n");
2714 return -ENODEV;
2715 }
2716 break; 2817 break;
2717 }
2718 2818
2719 case FALCON_REV_B0: 2819 case FALCON_REV_B0:
2720 break; 2820 break;
@@ -2724,6 +2824,9 @@ static int falcon_probe_nic_variant(struct efx_nic *efx)
2724 return -ENODEV; 2824 return -ENODEV;
2725 } 2825 }
2726 2826
2827 /* Initial assumed speed */
2828 efx->link_speed = EFX_OWORD_FIELD(nic_stat, STRAP_10G) ? 10000 : 1000;
2829
2727 return 0; 2830 return 0;
2728} 2831}
2729 2832
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index be025ba7a6c6..7869c3d74383 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -12,6 +12,7 @@
12#define EFX_FALCON_H 12#define EFX_FALCON_H
13 13
14#include "net_driver.h" 14#include "net_driver.h"
15#include "efx.h"
15 16
16/* 17/*
17 * Falcon hardware control 18 * Falcon hardware control
@@ -65,6 +66,7 @@ extern int falcon_probe_port(struct efx_nic *efx);
65extern void falcon_remove_port(struct efx_nic *efx); 66extern void falcon_remove_port(struct efx_nic *efx);
66 67
67/* MAC/PHY */ 68/* MAC/PHY */
69extern int falcon_switch_mac(struct efx_nic *efx);
68extern bool falcon_xaui_link_ok(struct efx_nic *efx); 70extern bool falcon_xaui_link_ok(struct efx_nic *efx);
69extern int falcon_dma_stats(struct efx_nic *efx, 71extern int falcon_dma_stats(struct efx_nic *efx,
70 unsigned int done_offset); 72 unsigned int done_offset);
@@ -77,6 +79,7 @@ extern int falcon_init_interrupt(struct efx_nic *efx);
77extern void falcon_enable_interrupts(struct efx_nic *efx); 79extern void falcon_enable_interrupts(struct efx_nic *efx);
78extern void falcon_generate_test_event(struct efx_channel *channel, 80extern void falcon_generate_test_event(struct efx_channel *channel,
79 unsigned int magic); 81 unsigned int magic);
82extern void falcon_sim_phy_event(struct efx_nic *efx);
80extern void falcon_generate_interrupt(struct efx_nic *efx); 83extern void falcon_generate_interrupt(struct efx_nic *efx);
81extern void falcon_set_int_moderation(struct efx_channel *channel); 84extern void falcon_set_int_moderation(struct efx_channel *channel);
82extern void falcon_disable_interrupts(struct efx_nic *efx); 85extern void falcon_disable_interrupts(struct efx_nic *efx);
diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c
new file mode 100644
index 000000000000..247f8025ef00
--- /dev/null
+++ b/drivers/net/sfc/falcon_gmac.c
@@ -0,0 +1,233 @@
1/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2006 Fen Systems Ltd.
4 * Copyright 2006-2008 Solarflare Communications Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation, incorporated herein by reference.
9 */
10
11#include <linux/delay.h>
12#include "net_driver.h"
13#include "efx.h"
14#include "falcon.h"
15#include "mac.h"
16#include "falcon_hwdefs.h"
17#include "falcon_io.h"
18#include "gmii.h"
19
20/**************************************************************************
21 *
22 * MAC operations
23 *
24 *************************************************************************/
25
26static void falcon_reconfigure_gmac(struct efx_nic *efx)
27{
28 bool loopback, tx_fc, rx_fc, bytemode;
29 int if_mode;
30 unsigned int max_frame_len;
31 efx_oword_t reg;
32
33 /* Configuration register 1 */
34 tx_fc = (efx->flow_control & EFX_FC_TX) || !efx->link_fd;
35 rx_fc = !!(efx->flow_control & EFX_FC_RX);
36 loopback = (efx->loopback_mode == LOOPBACK_GMAC);
37 bytemode = (efx->link_speed == 1000);
38
39 EFX_POPULATE_OWORD_5(reg,
40 GM_LOOP, loopback,
41 GM_TX_EN, 1,
42 GM_TX_FC_EN, tx_fc,
43 GM_RX_EN, 1,
44 GM_RX_FC_EN, rx_fc);
45 falcon_write(efx, &reg, GM_CFG1_REG);
46 udelay(10);
47
48 /* Configuration register 2 */
49 if_mode = (bytemode) ? 2 : 1;
50 EFX_POPULATE_OWORD_5(reg,
51 GM_IF_MODE, if_mode,
52 GM_PAD_CRC_EN, 1,
53 GM_LEN_CHK, 1,
54 GM_FD, efx->link_fd,
55 GM_PAMBL_LEN, 0x7/*datasheet recommended */);
56
57 falcon_write(efx, &reg, GM_CFG2_REG);
58 udelay(10);
59
60 /* Max frame len register */
61 max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
62 EFX_POPULATE_OWORD_1(reg, GM_MAX_FLEN, max_frame_len);
63 falcon_write(efx, &reg, GM_MAX_FLEN_REG);
64 udelay(10);
65
66 /* FIFO configuration register 0 */
67 EFX_POPULATE_OWORD_5(reg,
68 GMF_FTFENREQ, 1,
69 GMF_STFENREQ, 1,
70 GMF_FRFENREQ, 1,
71 GMF_SRFENREQ, 1,
72 GMF_WTMENREQ, 1);
73 falcon_write(efx, &reg, GMF_CFG0_REG);
74 udelay(10);
75
76 /* FIFO configuration register 1 */
77 EFX_POPULATE_OWORD_2(reg,
78 GMF_CFGFRTH, 0x12,
79 GMF_CFGXOFFRTX, 0xffff);
80 falcon_write(efx, &reg, GMF_CFG1_REG);
81 udelay(10);
82
83 /* FIFO configuration register 2 */
84 EFX_POPULATE_OWORD_2(reg,
85 GMF_CFGHWM, 0x3f,
86 GMF_CFGLWM, 0xa);
87 falcon_write(efx, &reg, GMF_CFG2_REG);
88 udelay(10);
89
90 /* FIFO configuration register 3 */
91 EFX_POPULATE_OWORD_2(reg,
92 GMF_CFGHWMFT, 0x1c,
93 GMF_CFGFTTH, 0x08);
94 falcon_write(efx, &reg, GMF_CFG3_REG);
95 udelay(10);
96
97 /* FIFO configuration register 4 */
98 EFX_POPULATE_OWORD_1(reg, GMF_HSTFLTRFRM_PAUSE, 1);
99 falcon_write(efx, &reg, GMF_CFG4_REG);
100 udelay(10);
101
102 /* FIFO configuration register 5 */
103 falcon_read(efx, &reg, GMF_CFG5_REG);
104 EFX_SET_OWORD_FIELD(reg, GMF_CFGBYTMODE, bytemode);
105 EFX_SET_OWORD_FIELD(reg, GMF_CFGHDPLX, !efx->link_fd);
106 EFX_SET_OWORD_FIELD(reg, GMF_HSTDRPLT64, !efx->link_fd);
107 EFX_SET_OWORD_FIELD(reg, GMF_HSTFLTRFRMDC_PAUSE, 0);
108 falcon_write(efx, &reg, GMF_CFG5_REG);
109 udelay(10);
110
111 /* MAC address */
112 EFX_POPULATE_OWORD_4(reg,
113 GM_HWADDR_5, efx->net_dev->dev_addr[5],
114 GM_HWADDR_4, efx->net_dev->dev_addr[4],
115 GM_HWADDR_3, efx->net_dev->dev_addr[3],
116 GM_HWADDR_2, efx->net_dev->dev_addr[2]);
117 falcon_write(efx, &reg, GM_ADR1_REG);
118 udelay(10);
119 EFX_POPULATE_OWORD_2(reg,
120 GM_HWADDR_1, efx->net_dev->dev_addr[1],
121 GM_HWADDR_0, efx->net_dev->dev_addr[0]);
122 falcon_write(efx, &reg, GM_ADR2_REG);
123 udelay(10);
124
125 falcon_reconfigure_mac_wrapper(efx);
126}
127
128static void falcon_update_stats_gmac(struct efx_nic *efx)
129{
130 struct efx_mac_stats *mac_stats = &efx->mac_stats;
131 unsigned long old_rx_pause, old_tx_pause;
132 unsigned long new_rx_pause, new_tx_pause;
133 int rc;
134
135 rc = falcon_dma_stats(efx, GDmaDone_offset);
136 if (rc)
137 return;
138
139 /* Pause frames are erroneously counted as errors (SFC bug 3269) */
140 old_rx_pause = mac_stats->rx_pause;
141 old_tx_pause = mac_stats->tx_pause;
142
143 /* Update MAC stats from DMAed values */
144 FALCON_STAT(efx, GRxGoodOct, rx_good_bytes);
145 FALCON_STAT(efx, GRxBadOct, rx_bad_bytes);
146 FALCON_STAT(efx, GRxMissPkt, rx_missed);
147 FALCON_STAT(efx, GRxFalseCRS, rx_false_carrier);
148 FALCON_STAT(efx, GRxPausePkt, rx_pause);
149 FALCON_STAT(efx, GRxBadPkt, rx_bad);
150 FALCON_STAT(efx, GRxUcastPkt, rx_unicast);
151 FALCON_STAT(efx, GRxMcastPkt, rx_multicast);
152 FALCON_STAT(efx, GRxBcastPkt, rx_broadcast);
153 FALCON_STAT(efx, GRxGoodLt64Pkt, rx_good_lt64);
154 FALCON_STAT(efx, GRxBadLt64Pkt, rx_bad_lt64);
155 FALCON_STAT(efx, GRx64Pkt, rx_64);
156 FALCON_STAT(efx, GRx65to127Pkt, rx_65_to_127);
157 FALCON_STAT(efx, GRx128to255Pkt, rx_128_to_255);
158 FALCON_STAT(efx, GRx256to511Pkt, rx_256_to_511);
159 FALCON_STAT(efx, GRx512to1023Pkt, rx_512_to_1023);
160 FALCON_STAT(efx, GRx1024to15xxPkt, rx_1024_to_15xx);
161 FALCON_STAT(efx, GRx15xxtoJumboPkt, rx_15xx_to_jumbo);
162 FALCON_STAT(efx, GRxGtJumboPkt, rx_gtjumbo);
163 FALCON_STAT(efx, GRxFcsErr64to15xxPkt, rx_bad_64_to_15xx);
164 FALCON_STAT(efx, GRxFcsErr15xxtoJumboPkt, rx_bad_15xx_to_jumbo);
165 FALCON_STAT(efx, GRxFcsErrGtJumboPkt, rx_bad_gtjumbo);
166 FALCON_STAT(efx, GTxGoodBadOct, tx_bytes);
167 FALCON_STAT(efx, GTxGoodOct, tx_good_bytes);
168 FALCON_STAT(efx, GTxSglColPkt, tx_single_collision);
169 FALCON_STAT(efx, GTxMultColPkt, tx_multiple_collision);
170 FALCON_STAT(efx, GTxExColPkt, tx_excessive_collision);
171 FALCON_STAT(efx, GTxDefPkt, tx_deferred);
172 FALCON_STAT(efx, GTxLateCol, tx_late_collision);
173 FALCON_STAT(efx, GTxExDefPkt, tx_excessive_deferred);
174 FALCON_STAT(efx, GTxPausePkt, tx_pause);
175 FALCON_STAT(efx, GTxBadPkt, tx_bad);
176 FALCON_STAT(efx, GTxUcastPkt, tx_unicast);
177 FALCON_STAT(efx, GTxMcastPkt, tx_multicast);
178 FALCON_STAT(efx, GTxBcastPkt, tx_broadcast);
179 FALCON_STAT(efx, GTxLt64Pkt, tx_lt64);
180 FALCON_STAT(efx, GTx64Pkt, tx_64);
181 FALCON_STAT(efx, GTx65to127Pkt, tx_65_to_127);
182 FALCON_STAT(efx, GTx128to255Pkt, tx_128_to_255);
183 FALCON_STAT(efx, GTx256to511Pkt, tx_256_to_511);
184 FALCON_STAT(efx, GTx512to1023Pkt, tx_512_to_1023);
185 FALCON_STAT(efx, GTx1024to15xxPkt, tx_1024_to_15xx);
186 FALCON_STAT(efx, GTx15xxtoJumboPkt, tx_15xx_to_jumbo);
187 FALCON_STAT(efx, GTxGtJumboPkt, tx_gtjumbo);
188 FALCON_STAT(efx, GTxNonTcpUdpPkt, tx_non_tcpudp);
189 FALCON_STAT(efx, GTxMacSrcErrPkt, tx_mac_src_error);
190 FALCON_STAT(efx, GTxIpSrcErrPkt, tx_ip_src_error);
191
192 /* Pause frames are erroneously counted as errors (SFC bug 3269) */
193 new_rx_pause = mac_stats->rx_pause;
194 new_tx_pause = mac_stats->tx_pause;
195 mac_stats->rx_bad -= (new_rx_pause - old_rx_pause);
196 mac_stats->tx_bad -= (new_tx_pause - old_tx_pause);
197
198 /* Derive stats that the MAC doesn't provide directly */
199 mac_stats->tx_bad_bytes =
200 mac_stats->tx_bytes - mac_stats->tx_good_bytes;
201 mac_stats->tx_packets =
202 mac_stats->tx_lt64 + mac_stats->tx_64 +
203 mac_stats->tx_65_to_127 + mac_stats->tx_128_to_255 +
204 mac_stats->tx_256_to_511 + mac_stats->tx_512_to_1023 +
205 mac_stats->tx_1024_to_15xx + mac_stats->tx_15xx_to_jumbo +
206 mac_stats->tx_gtjumbo;
207 mac_stats->tx_collision =
208 mac_stats->tx_single_collision +
209 mac_stats->tx_multiple_collision +
210 mac_stats->tx_excessive_collision +
211 mac_stats->tx_late_collision;
212 mac_stats->rx_bytes =
213 mac_stats->rx_good_bytes + mac_stats->rx_bad_bytes;
214 mac_stats->rx_packets =
215 mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64 +
216 mac_stats->rx_64 + mac_stats->rx_65_to_127 +
217 mac_stats->rx_128_to_255 + mac_stats->rx_256_to_511 +
218 mac_stats->rx_512_to_1023 + mac_stats->rx_1024_to_15xx +
219 mac_stats->rx_15xx_to_jumbo + mac_stats->rx_gtjumbo;
220 mac_stats->rx_good = mac_stats->rx_packets - mac_stats->rx_bad;
221 mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64;
222}
223
224static int falcon_check_gmac(struct efx_nic *efx)
225{
226 return efx->phy_op->check_hw(efx);
227}
228
229struct efx_mac_operations falcon_gmac_operations = {
230 .reconfigure = falcon_reconfigure_gmac,
231 .update_stats = falcon_update_stats_gmac,
232 .check_hw = falcon_check_gmac,
233};
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index 040e70ed4ec7..5553df888b84 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -111,12 +111,18 @@
111 111
112/* NIC status register */ 112/* NIC status register */
113#define NIC_STAT_REG 0x0200 113#define NIC_STAT_REG 0x0200
114#define EE_STRAP_EN_LBN 31
115#define EE_STRAP_EN_WIDTH 1
116#define EE_STRAP_OVR_LBN 24
117#define EE_STRAP_OVR_WIDTH 4
114#define ONCHIP_SRAM_LBN 16 118#define ONCHIP_SRAM_LBN 16
115#define ONCHIP_SRAM_WIDTH 1 119#define ONCHIP_SRAM_WIDTH 1
116#define SF_PRST_LBN 9 120#define SF_PRST_LBN 9
117#define SF_PRST_WIDTH 1 121#define SF_PRST_WIDTH 1
118#define EE_PRST_LBN 8 122#define EE_PRST_LBN 8
119#define EE_PRST_WIDTH 1 123#define EE_PRST_WIDTH 1
124#define STRAP_PINS_LBN 0
125#define STRAP_PINS_WIDTH 3
120/* These bit definitions are extrapolated from the list of numerical 126/* These bit definitions are extrapolated from the list of numerical
121 * values for STRAP_PINS. 127 * values for STRAP_PINS.
122 */ 128 */
@@ -492,6 +498,107 @@
492#define MAC_MCAST_HASH_REG0_KER 0xca0 498#define MAC_MCAST_HASH_REG0_KER 0xca0
493#define MAC_MCAST_HASH_REG1_KER 0xcb0 499#define MAC_MCAST_HASH_REG1_KER 0xcb0
494 500
501/* GMAC configuration register 1 */
502#define GM_CFG1_REG 0xe00
503#define GM_SW_RST_LBN 31
504#define GM_SW_RST_WIDTH 1
505#define GM_LOOP_LBN 8
506#define GM_LOOP_WIDTH 1
507#define GM_RX_FC_EN_LBN 5
508#define GM_RX_FC_EN_WIDTH 1
509#define GM_TX_FC_EN_LBN 4
510#define GM_TX_FC_EN_WIDTH 1
511#define GM_RX_EN_LBN 2
512#define GM_RX_EN_WIDTH 1
513#define GM_TX_EN_LBN 0
514#define GM_TX_EN_WIDTH 1
515
516/* GMAC configuration register 2 */
517#define GM_CFG2_REG 0xe10
518#define GM_PAMBL_LEN_LBN 12
519#define GM_PAMBL_LEN_WIDTH 4
520#define GM_IF_MODE_LBN 8
521#define GM_IF_MODE_WIDTH 2
522#define GM_LEN_CHK_LBN 4
523#define GM_LEN_CHK_WIDTH 1
524#define GM_PAD_CRC_EN_LBN 2
525#define GM_PAD_CRC_EN_WIDTH 1
526#define GM_FD_LBN 0
527#define GM_FD_WIDTH 1
528
529/* GMAC maximum frame length register */
530#define GM_MAX_FLEN_REG 0xe40
531#define GM_MAX_FLEN_LBN 0
532#define GM_MAX_FLEN_WIDTH 16
533
534/* GMAC station address register 1 */
535#define GM_ADR1_REG 0xf00
536#define GM_HWADDR_5_LBN 24
537#define GM_HWADDR_5_WIDTH 8
538#define GM_HWADDR_4_LBN 16
539#define GM_HWADDR_4_WIDTH 8
540#define GM_HWADDR_3_LBN 8
541#define GM_HWADDR_3_WIDTH 8
542#define GM_HWADDR_2_LBN 0
543#define GM_HWADDR_2_WIDTH 8
544
545/* GMAC station address register 2 */
546#define GM_ADR2_REG 0xf10
547#define GM_HWADDR_1_LBN 24
548#define GM_HWADDR_1_WIDTH 8
549#define GM_HWADDR_0_LBN 16
550#define GM_HWADDR_0_WIDTH 8
551
552/* GMAC FIFO configuration register 0 */
553#define GMF_CFG0_REG 0xf20
554#define GMF_FTFENREQ_LBN 12
555#define GMF_FTFENREQ_WIDTH 1
556#define GMF_STFENREQ_LBN 11
557#define GMF_STFENREQ_WIDTH 1
558#define GMF_FRFENREQ_LBN 10
559#define GMF_FRFENREQ_WIDTH 1
560#define GMF_SRFENREQ_LBN 9
561#define GMF_SRFENREQ_WIDTH 1
562#define GMF_WTMENREQ_LBN 8
563#define GMF_WTMENREQ_WIDTH 1
564
565/* GMAC FIFO configuration register 1 */
566#define GMF_CFG1_REG 0xf30
567#define GMF_CFGFRTH_LBN 16
568#define GMF_CFGFRTH_WIDTH 5
569#define GMF_CFGXOFFRTX_LBN 0
570#define GMF_CFGXOFFRTX_WIDTH 16
571
572/* GMAC FIFO configuration register 2 */
573#define GMF_CFG2_REG 0xf40
574#define GMF_CFGHWM_LBN 16
575#define GMF_CFGHWM_WIDTH 6
576#define GMF_CFGLWM_LBN 0
577#define GMF_CFGLWM_WIDTH 6
578
579/* GMAC FIFO configuration register 3 */
580#define GMF_CFG3_REG 0xf50
581#define GMF_CFGHWMFT_LBN 16
582#define GMF_CFGHWMFT_WIDTH 6
583#define GMF_CFGFTTH_LBN 0
584#define GMF_CFGFTTH_WIDTH 6
585
586/* GMAC FIFO configuration register 4 */
587#define GMF_CFG4_REG 0xf60
588#define GMF_HSTFLTRFRM_PAUSE_LBN 12
589#define GMF_HSTFLTRFRM_PAUSE_WIDTH 12
590
591/* GMAC FIFO configuration register 5 */
592#define GMF_CFG5_REG 0xf70
593#define GMF_CFGHDPLX_LBN 22
594#define GMF_CFGHDPLX_WIDTH 1
595#define GMF_CFGBYTMODE_LBN 19
596#define GMF_CFGBYTMODE_WIDTH 1
597#define GMF_HSTDRPLT64_LBN 18
598#define GMF_HSTDRPLT64_WIDTH 1
599#define GMF_HSTFLTRFRMDC_PAUSE_LBN 12
600#define GMF_HSTFLTRFRMDC_PAUSE_WIDTH 1
601
495/* XGMAC address register low */ 602/* XGMAC address register low */
496#define XM_ADR_LO_REG 0x1200 603#define XM_ADR_LO_REG 0x1200
497#define XM_ADR_3_LBN 24 604#define XM_ADR_3_LBN 24
@@ -962,54 +1069,103 @@
962 ************************************************************************** 1069 **************************************************************************
963 * 1070 *
964 */ 1071 */
1072
965#define GRxGoodOct_offset 0x0 1073#define GRxGoodOct_offset 0x0
1074#define GRxGoodOct_WIDTH 48
966#define GRxBadOct_offset 0x8 1075#define GRxBadOct_offset 0x8
1076#define GRxBadOct_WIDTH 48
967#define GRxMissPkt_offset 0x10 1077#define GRxMissPkt_offset 0x10
1078#define GRxMissPkt_WIDTH 32
968#define GRxFalseCRS_offset 0x14 1079#define GRxFalseCRS_offset 0x14
1080#define GRxFalseCRS_WIDTH 32
969#define GRxPausePkt_offset 0x18 1081#define GRxPausePkt_offset 0x18
1082#define GRxPausePkt_WIDTH 32
970#define GRxBadPkt_offset 0x1C 1083#define GRxBadPkt_offset 0x1C
1084#define GRxBadPkt_WIDTH 32
971#define GRxUcastPkt_offset 0x20 1085#define GRxUcastPkt_offset 0x20
1086#define GRxUcastPkt_WIDTH 32
972#define GRxMcastPkt_offset 0x24 1087#define GRxMcastPkt_offset 0x24
1088#define GRxMcastPkt_WIDTH 32
973#define GRxBcastPkt_offset 0x28 1089#define GRxBcastPkt_offset 0x28
1090#define GRxBcastPkt_WIDTH 32
974#define GRxGoodLt64Pkt_offset 0x2C 1091#define GRxGoodLt64Pkt_offset 0x2C
1092#define GRxGoodLt64Pkt_WIDTH 32
975#define GRxBadLt64Pkt_offset 0x30 1093#define GRxBadLt64Pkt_offset 0x30
1094#define GRxBadLt64Pkt_WIDTH 32
976#define GRx64Pkt_offset 0x34 1095#define GRx64Pkt_offset 0x34
1096#define GRx64Pkt_WIDTH 32
977#define GRx65to127Pkt_offset 0x38 1097#define GRx65to127Pkt_offset 0x38
1098#define GRx65to127Pkt_WIDTH 32
978#define GRx128to255Pkt_offset 0x3C 1099#define GRx128to255Pkt_offset 0x3C
1100#define GRx128to255Pkt_WIDTH 32
979#define GRx256to511Pkt_offset 0x40 1101#define GRx256to511Pkt_offset 0x40
1102#define GRx256to511Pkt_WIDTH 32
980#define GRx512to1023Pkt_offset 0x44 1103#define GRx512to1023Pkt_offset 0x44
1104#define GRx512to1023Pkt_WIDTH 32
981#define GRx1024to15xxPkt_offset 0x48 1105#define GRx1024to15xxPkt_offset 0x48
1106#define GRx1024to15xxPkt_WIDTH 32
982#define GRx15xxtoJumboPkt_offset 0x4C 1107#define GRx15xxtoJumboPkt_offset 0x4C
1108#define GRx15xxtoJumboPkt_WIDTH 32
983#define GRxGtJumboPkt_offset 0x50 1109#define GRxGtJumboPkt_offset 0x50
1110#define GRxGtJumboPkt_WIDTH 32
984#define GRxFcsErr64to15xxPkt_offset 0x54 1111#define GRxFcsErr64to15xxPkt_offset 0x54
1112#define GRxFcsErr64to15xxPkt_WIDTH 32
985#define GRxFcsErr15xxtoJumboPkt_offset 0x58 1113#define GRxFcsErr15xxtoJumboPkt_offset 0x58
1114#define GRxFcsErr15xxtoJumboPkt_WIDTH 32
986#define GRxFcsErrGtJumboPkt_offset 0x5C 1115#define GRxFcsErrGtJumboPkt_offset 0x5C
1116#define GRxFcsErrGtJumboPkt_WIDTH 32
987#define GTxGoodBadOct_offset 0x80 1117#define GTxGoodBadOct_offset 0x80
1118#define GTxGoodBadOct_WIDTH 48
988#define GTxGoodOct_offset 0x88 1119#define GTxGoodOct_offset 0x88
1120#define GTxGoodOct_WIDTH 48
989#define GTxSglColPkt_offset 0x90 1121#define GTxSglColPkt_offset 0x90
1122#define GTxSglColPkt_WIDTH 32
990#define GTxMultColPkt_offset 0x94 1123#define GTxMultColPkt_offset 0x94
1124#define GTxMultColPkt_WIDTH 32
991#define GTxExColPkt_offset 0x98 1125#define GTxExColPkt_offset 0x98
1126#define GTxExColPkt_WIDTH 32
992#define GTxDefPkt_offset 0x9C 1127#define GTxDefPkt_offset 0x9C
1128#define GTxDefPkt_WIDTH 32
993#define GTxLateCol_offset 0xA0 1129#define GTxLateCol_offset 0xA0
1130#define GTxLateCol_WIDTH 32
994#define GTxExDefPkt_offset 0xA4 1131#define GTxExDefPkt_offset 0xA4
1132#define GTxExDefPkt_WIDTH 32
995#define GTxPausePkt_offset 0xA8 1133#define GTxPausePkt_offset 0xA8
1134#define GTxPausePkt_WIDTH 32
996#define GTxBadPkt_offset 0xAC 1135#define GTxBadPkt_offset 0xAC
1136#define GTxBadPkt_WIDTH 32
997#define GTxUcastPkt_offset 0xB0 1137#define GTxUcastPkt_offset 0xB0
1138#define GTxUcastPkt_WIDTH 32
998#define GTxMcastPkt_offset 0xB4 1139#define GTxMcastPkt_offset 0xB4
1140#define GTxMcastPkt_WIDTH 32
999#define GTxBcastPkt_offset 0xB8 1141#define GTxBcastPkt_offset 0xB8
1142#define GTxBcastPkt_WIDTH 32
1000#define GTxLt64Pkt_offset 0xBC 1143#define GTxLt64Pkt_offset 0xBC
1144#define GTxLt64Pkt_WIDTH 32
1001#define GTx64Pkt_offset 0xC0 1145#define GTx64Pkt_offset 0xC0
1146#define GTx64Pkt_WIDTH 32
1002#define GTx65to127Pkt_offset 0xC4 1147#define GTx65to127Pkt_offset 0xC4
1148#define GTx65to127Pkt_WIDTH 32
1003#define GTx128to255Pkt_offset 0xC8 1149#define GTx128to255Pkt_offset 0xC8
1150#define GTx128to255Pkt_WIDTH 32
1004#define GTx256to511Pkt_offset 0xCC 1151#define GTx256to511Pkt_offset 0xCC
1152#define GTx256to511Pkt_WIDTH 32
1005#define GTx512to1023Pkt_offset 0xD0 1153#define GTx512to1023Pkt_offset 0xD0
1154#define GTx512to1023Pkt_WIDTH 32
1006#define GTx1024to15xxPkt_offset 0xD4 1155#define GTx1024to15xxPkt_offset 0xD4
1156#define GTx1024to15xxPkt_WIDTH 32
1007#define GTx15xxtoJumboPkt_offset 0xD8 1157#define GTx15xxtoJumboPkt_offset 0xD8
1158#define GTx15xxtoJumboPkt_WIDTH 32
1008#define GTxGtJumboPkt_offset 0xDC 1159#define GTxGtJumboPkt_offset 0xDC
1160#define GTxGtJumboPkt_WIDTH 32
1009#define GTxNonTcpUdpPkt_offset 0xE0 1161#define GTxNonTcpUdpPkt_offset 0xE0
1162#define GTxNonTcpUdpPkt_WIDTH 16
1010#define GTxMacSrcErrPkt_offset 0xE4 1163#define GTxMacSrcErrPkt_offset 0xE4
1164#define GTxMacSrcErrPkt_WIDTH 16
1011#define GTxIpSrcErrPkt_offset 0xE8 1165#define GTxIpSrcErrPkt_offset 0xE8
1166#define GTxIpSrcErrPkt_WIDTH 16
1012#define GDmaDone_offset 0xEC 1167#define GDmaDone_offset 0xEC
1168#define GDmaDone_WIDTH 32
1013 1169
1014#define XgRxOctets_offset 0x0 1170#define XgRxOctets_offset 0x0
1015#define XgRxOctets_WIDTH 48 1171#define XgRxOctets_WIDTH 48
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 4a54d0933e72..2206eada3463 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -25,24 +25,6 @@
25 * MAC operations 25 * MAC operations
26 * 26 *
27 *************************************************************************/ 27 *************************************************************************/
28static int falcon_reset_xmac(struct efx_nic *efx)
29{
30 efx_oword_t reg;
31 int count;
32
33 EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1);
34 falcon_write(efx, &reg, XM_GLB_CFG_REG);
35
36 for (count = 0; count < 10000; count++) { /* wait upto 100ms */
37 falcon_read(efx, &reg, XM_GLB_CFG_REG);
38 if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0)
39 return 0;
40 udelay(10);
41 }
42
43 EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
44 return -ETIMEDOUT;
45}
46 28
47/* Configure the XAUI driver that is an output from Falcon */ 29/* Configure the XAUI driver that is an output from Falcon */
48static void falcon_setup_xaui(struct efx_nic *efx) 30static void falcon_setup_xaui(struct efx_nic *efx)
@@ -98,31 +80,20 @@ int falcon_reset_xaui(struct efx_nic *efx)
98 return -ETIMEDOUT; 80 return -ETIMEDOUT;
99} 81}
100 82
101static bool falcon_xgmii_status(struct efx_nic *efx) 83static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
102{ 84{
103 efx_oword_t reg; 85 efx_oword_t reg;
104 86
105 if (falcon_rev(efx) < FALCON_REV_B0) 87 if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
106 return true; 88 return;
107
108 /* The ISR latches, so clear it and re-read */
109 falcon_read(efx, &reg, XM_MGT_INT_REG_B0);
110 falcon_read(efx, &reg, XM_MGT_INT_REG_B0);
111
112 if (EFX_OWORD_FIELD(reg, XM_LCLFLT) ||
113 EFX_OWORD_FIELD(reg, XM_RMTFLT)) {
114 EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
115 return false;
116 }
117
118 return true;
119}
120 89
121static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) 90 /* We expect xgmii faults if the wireside link is up */
122{ 91 if (!EFX_WORKAROUND_5147(efx) || !efx->link_up)
123 efx_oword_t reg; 92 return;
124 93
125 if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) 94 /* We can only use this interrupt to signal the negative edge of
95 * xaui_align [we have to poll the positive edge]. */
96 if (!efx->mac_up)
126 return; 97 return;
127 98
128 /* Flush the ISR */ 99 /* Flush the ISR */
@@ -135,35 +106,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
135 falcon_write(efx, &reg, XM_MGT_INT_MSK_REG_B0); 106 falcon_write(efx, &reg, XM_MGT_INT_MSK_REG_B0);
136} 107}
137 108
138int falcon_init_xmac(struct efx_nic *efx) 109/* Get status of XAUI link */
139{
140 int rc;
141
142 /* Initialize the PHY first so the clock is around */
143 rc = efx->phy_op->init(efx);
144 if (rc)
145 goto fail1;
146
147 rc = falcon_reset_xaui(efx);
148 if (rc)
149 goto fail2;
150
151 /* Wait again. Give the PHY and MAC time to come back */
152 schedule_timeout_uninterruptible(HZ / 10);
153
154 rc = falcon_reset_xmac(efx);
155 if (rc)
156 goto fail2;
157
158 falcon_mask_status_intr(efx, true);
159 return 0;
160
161 fail2:
162 efx->phy_op->fini(efx);
163 fail1:
164 return rc;
165}
166
167bool falcon_xaui_link_ok(struct efx_nic *efx) 110bool falcon_xaui_link_ok(struct efx_nic *efx)
168{ 111{
169 efx_oword_t reg; 112 efx_oword_t reg;
@@ -187,18 +130,10 @@ bool falcon_xaui_link_ok(struct efx_nic *efx)
187 EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET); 130 EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET);
188 falcon_write(efx, &reg, XX_CORE_STAT_REG); 131 falcon_write(efx, &reg, XX_CORE_STAT_REG);
189 132
190 /* If the link is up, then check the phy side of the xaui link 133 /* If the link is up, then check the phy side of the xaui link */
191 * (error conditions from the wire side propoagate back through 134 if (efx->link_up && link_ok)
192 * the phy to the xaui side). */
193 if (efx->link_up && link_ok) {
194 if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS)) 135 if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
195 link_ok = mdio_clause45_phyxgxs_lane_sync(efx); 136 link_ok = mdio_clause45_phyxgxs_lane_sync(efx);
196 }
197
198 /* If the PHY and XAUI links are up, then check the mac's xgmii
199 * fault state */
200 if (efx->link_up && link_ok)
201 link_ok = falcon_xgmii_status(efx);
202 137
203 return link_ok; 138 return link_ok;
204} 139}
@@ -310,70 +245,39 @@ static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
310 245
311/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails 246/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
312 * to come back up. Bash it until it comes back up */ 247 * to come back up. Bash it until it comes back up */
313static bool falcon_check_xaui_link_up(struct efx_nic *efx) 248static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
314{ 249{
315 int max_tries, tries; 250 efx->mac_up = falcon_xaui_link_ok(efx);
316 tries = EFX_WORKAROUND_5147(efx) ? 5 : 1;
317 max_tries = tries;
318 251
319 if ((efx->loopback_mode == LOOPBACK_NETWORK) || 252 if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
320 (efx->phy_type == PHY_TYPE_NONE) ||
321 efx_phy_mode_disabled(efx->phy_mode)) 253 efx_phy_mode_disabled(efx->phy_mode))
322 return false; 254 /* XAUI link is expected to be down */
323 255 return;
324 while (tries) {
325 if (falcon_xaui_link_ok(efx))
326 return true;
327 256
328 EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", 257 while (!efx->mac_up && tries) {
329 __func__, tries); 258 EFX_LOG(efx, "bashing xaui\n");
330 falcon_reset_xaui(efx); 259 falcon_reset_xaui(efx);
331 udelay(200); 260 udelay(200);
332 tries--;
333 }
334 261
335 EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n", 262 efx->mac_up = falcon_xaui_link_ok(efx);
336 max_tries); 263 --tries;
337 return false; 264 }
338} 265}
339 266
340void falcon_reconfigure_xmac(struct efx_nic *efx) 267static void falcon_reconfigure_xmac(struct efx_nic *efx)
341{ 268{
342 bool xaui_link_ok;
343
344 falcon_mask_status_intr(efx, false); 269 falcon_mask_status_intr(efx, false);
345 270
346 falcon_deconfigure_mac_wrapper(efx);
347
348 /* Reconfigure the PHY, disabling transmit in mac level loopback. */
349 if (LOOPBACK_INTERNAL(efx))
350 efx->phy_mode |= PHY_MODE_TX_DISABLED;
351 else
352 efx->phy_mode &= ~PHY_MODE_TX_DISABLED;
353 efx->phy_op->reconfigure(efx);
354
355 falcon_reconfigure_xgxs_core(efx); 271 falcon_reconfigure_xgxs_core(efx);
356 falcon_reconfigure_xmac_core(efx); 272 falcon_reconfigure_xmac_core(efx);
357 273
358 falcon_reconfigure_mac_wrapper(efx); 274 falcon_reconfigure_mac_wrapper(efx);
359 275
360 /* Ensure XAUI link is up */ 276 falcon_check_xaui_link_up(efx, 5);
361 xaui_link_ok = falcon_check_xaui_link_up(efx); 277 falcon_mask_status_intr(efx, true);
362
363 if (xaui_link_ok && efx->link_up)
364 falcon_mask_status_intr(efx, true);
365}
366
367void falcon_fini_xmac(struct efx_nic *efx)
368{
369 /* Isolate the MAC - PHY */
370 falcon_deconfigure_mac_wrapper(efx);
371
372 /* Potentially power down the PHY */
373 efx->phy_op->fini(efx);
374} 278}
375 279
376void falcon_update_stats_xmac(struct efx_nic *efx) 280static void falcon_update_stats_xmac(struct efx_nic *efx)
377{ 281{
378 struct efx_mac_stats *mac_stats = &efx->mac_stats; 282 struct efx_mac_stats *mac_stats = &efx->mac_stats;
379 int rc; 283 int rc;
@@ -438,7 +342,7 @@ void falcon_update_stats_xmac(struct efx_nic *efx)
438 mac_stats->rx_control * 64); 342 mac_stats->rx_control * 64);
439} 343}
440 344
441int falcon_check_xmac(struct efx_nic *efx) 345static int falcon_check_xmac(struct efx_nic *efx)
442{ 346{
443 bool xaui_link_ok; 347 bool xaui_link_ok;
444 int rc; 348 int rc;
@@ -463,72 +367,8 @@ int falcon_check_xmac(struct efx_nic *efx)
463 return rc; 367 return rc;
464} 368}
465 369
466/* Simulate a PHY event */ 370struct efx_mac_operations falcon_xmac_operations = {
467void falcon_xmac_sim_phy_event(struct efx_nic *efx) 371 .reconfigure = falcon_reconfigure_xmac,
468{ 372 .update_stats = falcon_update_stats_xmac,
469 efx_qword_t phy_event; 373 .check_hw = falcon_check_xmac,
470 374};
471 EFX_POPULATE_QWORD_2(phy_event,
472 EV_CODE, GLOBAL_EV_DECODE,
473 XG_PHY_INTR, 1);
474 falcon_generate_event(&efx->channel[0], &phy_event);
475}
476
477int falcon_xmac_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
478{
479 mdio_clause45_get_settings(efx, ecmd);
480 ecmd->transceiver = XCVR_INTERNAL;
481 ecmd->phy_address = efx->mii.phy_id;
482 ecmd->autoneg = AUTONEG_DISABLE;
483 ecmd->duplex = DUPLEX_FULL;
484 return 0;
485}
486
487int falcon_xmac_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
488{
489 if (ecmd->transceiver != XCVR_INTERNAL)
490 return -EINVAL;
491 if (ecmd->autoneg != AUTONEG_DISABLE)
492 return -EINVAL;
493 if (ecmd->duplex != DUPLEX_FULL)
494 return -EINVAL;
495
496 return mdio_clause45_set_settings(efx, ecmd);
497}
498
499
500int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control)
501{
502 bool reset;
503
504 if (flow_control & EFX_FC_AUTO) {
505 EFX_LOG(efx, "10G does not support flow control "
506 "autonegotiation\n");
507 return -EINVAL;
508 }
509
510 if ((flow_control & EFX_FC_TX) && !(flow_control & EFX_FC_RX))
511 return -EINVAL;
512
513 /* TX flow control may automatically turn itself off if the
514 * link partner (intermittently) stops responding to pause
515 * frames. There isn't any indication that this has happened,
516 * so the best we do is leave it up to the user to spot this
517 * and fix it be cycling transmit flow control on this end. */
518 reset = ((flow_control & EFX_FC_TX) &&
519 !(efx->flow_control & EFX_FC_TX));
520 if (EFX_WORKAROUND_11482(efx) && reset) {
521 if (falcon_rev(efx) >= FALCON_REV_B0) {
522 /* Recover by resetting the EM block */
523 if (efx->link_up)
524 falcon_drain_tx_fifo(efx);
525 } else {
526 /* Schedule a reset to recover */
527 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
528 }
529 }
530
531 efx->flow_control = flow_control;
532
533 return 0;
534}
diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h
index a31571c69137..4e7074278fe1 100644
--- a/drivers/net/sfc/mac.h
+++ b/drivers/net/sfc/mac.h
@@ -1,7 +1,7 @@
1/**************************************************************************** 1/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards 2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2006 Fen Systems Ltd. 3 * Copyright 2005-2006 Fen Systems Ltd.
4 * Copyright 2006-2007 Solarflare Communications Inc. 4 * Copyright 2006-2008 Solarflare Communications Inc.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published 7 * under the terms of the GNU General Public License version 2 as published
@@ -13,17 +13,7 @@
13 13
14#include "net_driver.h" 14#include "net_driver.h"
15 15
16extern int falcon_init_xmac(struct efx_nic *efx); 16extern struct efx_mac_operations falcon_gmac_operations;
17extern void falcon_reconfigure_xmac(struct efx_nic *efx); 17extern struct efx_mac_operations falcon_xmac_operations;
18extern void falcon_update_stats_xmac(struct efx_nic *efx);
19extern void falcon_fini_xmac(struct efx_nic *efx);
20extern int falcon_check_xmac(struct efx_nic *efx);
21extern void falcon_xmac_sim_phy_event(struct efx_nic *efx);
22extern int falcon_xmac_get_settings(struct efx_nic *efx,
23 struct ethtool_cmd *ecmd);
24extern int falcon_xmac_set_settings(struct efx_nic *efx,
25 struct ethtool_cmd *ecmd);
26extern int falcon_xmac_set_pause(struct efx_nic *efx,
27 enum efx_fc_type pause_params);
28 18
29#endif 19#endif
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 6cac5ed427ba..883086e39455 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -463,6 +463,8 @@ enum phy_type {
463 463
464#define PHY_ADDR_INVALID 0xff 464#define PHY_ADDR_INVALID 0xff
465 465
466#define EFX_IS10G(efx) ((efx)->link_speed == 10000)
467
466enum nic_state { 468enum nic_state {
467 STATE_INIT = 0, 469 STATE_INIT = 0,
468 STATE_RUNNING = 1, 470 STATE_RUNNING = 1,
@@ -503,6 +505,24 @@ enum efx_fc_type {
503 EFX_FC_AUTO = 4, 505 EFX_FC_AUTO = 4,
504}; 506};
505 507
508/* Supported MAC bit-mask */
509enum efx_mac_type {
510 EFX_GMAC = 1,
511 EFX_XMAC = 2,
512};
513
514/**
515 * struct efx_mac_operations - Efx MAC operations table
516 * @reconfigure: Reconfigure MAC. Serialised by the mac_lock
517 * @update_stats: Update statistics
518 * @check_hw: Check hardware. Serialised by the mac_lock
519 */
520struct efx_mac_operations {
521 void (*reconfigure) (struct efx_nic *efx);
522 void (*update_stats) (struct efx_nic *efx);
523 int (*check_hw) (struct efx_nic *efx);
524};
525
506/** 526/**
507 * struct efx_phy_operations - Efx PHY operations table 527 * struct efx_phy_operations - Efx PHY operations table
508 * @init: Initialise PHY 528 * @init: Initialise PHY
@@ -511,16 +531,23 @@ enum efx_fc_type {
511 * @clear_interrupt: Clear down interrupt 531 * @clear_interrupt: Clear down interrupt
512 * @blink: Blink LEDs 532 * @blink: Blink LEDs
513 * @check_hw: Check hardware 533 * @check_hw: Check hardware
534 * @get_settings: Get ethtool settings. Serialised by the mac_lock.
535 * @set_settings: Set ethtool settings. Serialised by the mac_lock.
514 * @mmds: MMD presence mask 536 * @mmds: MMD presence mask
515 * @loopbacks: Supported loopback modes mask 537 * @loopbacks: Supported loopback modes mask
516 */ 538 */
517struct efx_phy_operations { 539struct efx_phy_operations {
540 enum efx_mac_type macs;
518 int (*init) (struct efx_nic *efx); 541 int (*init) (struct efx_nic *efx);
519 void (*fini) (struct efx_nic *efx); 542 void (*fini) (struct efx_nic *efx);
520 void (*reconfigure) (struct efx_nic *efx); 543 void (*reconfigure) (struct efx_nic *efx);
521 void (*clear_interrupt) (struct efx_nic *efx); 544 void (*clear_interrupt) (struct efx_nic *efx);
522 int (*check_hw) (struct efx_nic *efx); 545 int (*check_hw) (struct efx_nic *efx);
523 int (*test) (struct efx_nic *efx); 546 int (*test) (struct efx_nic *efx);
547 void (*get_settings) (struct efx_nic *efx,
548 struct ethtool_cmd *ecmd);
549 int (*set_settings) (struct efx_nic *efx,
550 struct ethtool_cmd *ecmd);
524 int mmds; 551 int mmds;
525 unsigned loopbacks; 552 unsigned loopbacks;
526}; 553};
@@ -686,6 +713,7 @@ union efx_multicast_hash {
686 * @stats_lock: Statistics update lock. Serialises statistics fetches 713 * @stats_lock: Statistics update lock. Serialises statistics fetches
687 * @stats_enabled: Temporarily disable statistics fetches. 714 * @stats_enabled: Temporarily disable statistics fetches.
688 * Serialised by @stats_lock 715 * Serialised by @stats_lock
716 * @mac_op: MAC interface
689 * @mac_address: Permanent MAC address 717 * @mac_address: Permanent MAC address
690 * @phy_type: PHY type 718 * @phy_type: PHY type
691 * @phy_lock: PHY access lock 719 * @phy_lock: PHY access lock
@@ -693,6 +721,7 @@ union efx_multicast_hash {
693 * @phy_data: PHY private data (including PHY-specific stats) 721 * @phy_data: PHY private data (including PHY-specific stats)
694 * @mii: PHY interface 722 * @mii: PHY interface
695 * @phy_mode: PHY operating mode. Serialised by @mac_lock. 723 * @phy_mode: PHY operating mode. Serialised by @mac_lock.
724 * @mac_up: MAC link state
696 * @link_up: Link status 725 * @link_up: Link status
697 * @link_fd: Link is full duplex 726 * @link_fd: Link is full duplex
698 * @link_speed: Link speed (Mbps) 727 * @link_speed: Link speed (Mbps)
@@ -763,6 +792,7 @@ struct efx_nic {
763 spinlock_t stats_lock; 792 spinlock_t stats_lock;
764 bool stats_enabled; 793 bool stats_enabled;
765 794
795 struct efx_mac_operations *mac_op;
766 unsigned char mac_address[ETH_ALEN]; 796 unsigned char mac_address[ETH_ALEN];
767 797
768 enum phy_type phy_type; 798 enum phy_type phy_type;
@@ -772,6 +802,7 @@ struct efx_nic {
772 struct mii_if_info mii; 802 struct mii_if_info mii;
773 enum efx_phy_mode phy_mode; 803 enum efx_phy_mode phy_mode;
774 804
805 bool mac_up;
775 bool link_up; 806 bool link_up;
776 bool link_fd; 807 bool link_fd;
777 unsigned int link_speed; 808 unsigned int link_speed;
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 362956e3fe17..8142e37a518f 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -26,7 +26,6 @@
26#include "selftest.h" 26#include "selftest.h"
27#include "boards.h" 27#include "boards.h"
28#include "workarounds.h" 28#include "workarounds.h"
29#include "mac.h"
30#include "spi.h" 29#include "spi.h"
31#include "falcon_io.h" 30#include "falcon_io.h"
32#include "mdio_10g.h" 31#include "mdio_10g.h"
@@ -105,9 +104,11 @@ static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests)
105 goto out; 104 goto out;
106 } 105 }
107 106
108 rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0); 107 if (EFX_IS10G(efx)) {
109 if (rc) 108 rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0);
110 goto out; 109 if (rc)
110 goto out;
111 }
111 112
112out: 113out:
113 mutex_unlock(&efx->mac_lock); 114 mutex_unlock(&efx->mac_lock);
@@ -598,7 +599,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd,
598 do { 599 do {
599 struct efx_channel *channel = &efx->channel[0]; 600 struct efx_channel *channel = &efx->channel[0];
600 601
601 falcon_check_xmac(efx); 602 efx->mac_op->check_hw(efx);
602 schedule_timeout_uninterruptible(HZ / 10); 603 schedule_timeout_uninterruptible(HZ / 10);
603 if (channel->work_pending) 604 if (channel->work_pending)
604 efx_process_channel_now(channel); 605 efx_process_channel_now(channel);
@@ -606,13 +607,12 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd,
606 flush_workqueue(efx->workqueue); 607 flush_workqueue(efx->workqueue);
607 rmb(); 608 rmb();
608 609
609 /* efx->link_up can be 1 even if the XAUI link is down, 610 /* We need both the phy and xaui links to be ok.
610 * (bug5762). Usually, it's not worth bothering with the 611 * rather than relying on the falcon_xmac irq/poll
611 * difference, but for selftests, we need that extra 612 * regime, just poll xaui directly */
612 * guarantee that the link is really, really, up.
613 */
614 link_up = efx->link_up; 613 link_up = efx->link_up;
615 if (!falcon_xaui_link_ok(efx)) 614 if (link_up && EFX_IS10G(efx) &&
615 !falcon_xaui_link_ok(efx))
616 link_up = false; 616 link_up = false;
617 617
618 } while ((++count < 20) && !link_up); 618 } while ((++count < 20) && !link_up);
@@ -721,7 +721,6 @@ int efx_offline_test(struct efx_nic *efx,
721 if (ecmd_test.autoneg == AUTONEG_ENABLE) { 721 if (ecmd_test.autoneg == AUTONEG_ENABLE) {
722 ecmd_test.autoneg = AUTONEG_DISABLE; 722 ecmd_test.autoneg = AUTONEG_DISABLE;
723 ecmd_test.duplex = DUPLEX_FULL; 723 ecmd_test.duplex = DUPLEX_FULL;
724 ecmd_test.speed = SPEED_10000;
725 } 724 }
726 efx->loopback_mode = LOOPBACK_NONE; 725 efx->loopback_mode = LOOPBACK_NONE;
727 726
@@ -732,9 +731,6 @@ int efx_offline_test(struct efx_nic *efx,
732 return rc; 731 return rc;
733 } 732 }
734 733
735 tests->loopback_speed = ecmd_test.speed;
736 tests->loopback_full_duplex = ecmd_test.duplex;
737
738 rc = efx_test_phy(efx, tests); 734 rc = efx_test_phy(efx, tests);
739 if (rc && !rc2) 735 if (rc && !rc2)
740 rc2 = rc; 736 rc2 = rc;
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h
index fc15df15d766..252f7d717242 100644
--- a/drivers/net/sfc/selftest.h
+++ b/drivers/net/sfc/selftest.h
@@ -39,8 +39,6 @@ struct efx_self_tests {
39 /* offline tests */ 39 /* offline tests */
40 int registers; 40 int registers;
41 int phy; 41 int phy;
42 int loopback_speed;
43 int loopback_full_duplex;
44 struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; 42 struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1];
45}; 43};
46 44
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index aa576c559ec8..af652844baee 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -176,7 +176,7 @@ static int sfe4001_check_hw(struct efx_nic *efx)
176 s32 status; 176 s32 status;
177 177
178 /* If XAUI link is up then do not monitor */ 178 /* If XAUI link is up then do not monitor */
179 if (EFX_WORKAROUND_7884(efx) && falcon_xaui_link_ok(efx)) 179 if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
180 return 0; 180 return 0;
181 181
182 /* Check the powered status of the PHY. Lack of power implies that 182 /* Check the powered status of the PHY. Lack of power implies that
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 197b5449ab18..d60353bb40b6 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -1,6 +1,6 @@
1/**************************************************************************** 1/****************************************************************************
2 * Driver for Solarflare 802.3an compliant PHY 2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2007 Solarflare Communications Inc. 3 * Copyright 2007-2008 Solarflare Communications Inc.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published 6 * under the terms of the GNU General Public License version 2 as published
@@ -15,7 +15,6 @@
15#include "phy.h" 15#include "phy.h"
16#include "falcon_hwdefs.h" 16#include "falcon_hwdefs.h"
17#include "boards.h" 17#include "boards.h"
18#include "mac.h"
19 18
20/* We expect these MMDs to be in the package */ 19/* We expect these MMDs to be in the package */
21/* AN not here as mdio_check_mmds() requires STAT2 support */ 20/* AN not here as mdio_check_mmds() requires STAT2 support */
@@ -381,7 +380,7 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx)
381 link_ok = tenxpress_link_ok(efx, true); 380 link_ok = tenxpress_link_ok(efx, true);
382 381
383 if (link_ok != efx->link_up) 382 if (link_ok != efx->link_up)
384 falcon_xmac_sim_phy_event(efx); 383 falcon_sim_phy_event(efx);
385 384
386 if (phy_data->phy_mode != PHY_MODE_NORMAL) 385 if (phy_data->phy_mode != PHY_MODE_NORMAL)
387 return 0; 386 return 0;
@@ -453,12 +452,15 @@ static int tenxpress_phy_test(struct efx_nic *efx)
453} 452}
454 453
455struct efx_phy_operations falcon_tenxpress_phy_ops = { 454struct efx_phy_operations falcon_tenxpress_phy_ops = {
455 .macs = EFX_XMAC,
456 .init = tenxpress_phy_init, 456 .init = tenxpress_phy_init,
457 .reconfigure = tenxpress_phy_reconfigure, 457 .reconfigure = tenxpress_phy_reconfigure,
458 .check_hw = tenxpress_phy_check_hw, 458 .check_hw = tenxpress_phy_check_hw,
459 .fini = tenxpress_phy_fini, 459 .fini = tenxpress_phy_fini,
460 .clear_interrupt = tenxpress_phy_clear_interrupt, 460 .clear_interrupt = tenxpress_phy_clear_interrupt,
461 .test = tenxpress_phy_test, 461 .test = tenxpress_phy_test,
462 .get_settings = mdio_clause45_get_settings,
463 .set_settings = mdio_clause45_set_settings,
462 .mmds = TENXPRESS_REQUIRED_DEVS, 464 .mmds = TENXPRESS_REQUIRED_DEVS,
463 .loopbacks = TENXPRESS_LOOPBACKS, 465 .loopbacks = TENXPRESS_LOOPBACKS,
464}; 466};
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index 0413d135e4aa..d4e203ddcf1c 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -17,7 +17,7 @@
17#include "mdio_10g.h" 17#include "mdio_10g.h"
18#include "xenpack.h" 18#include "xenpack.h"
19#include "phy.h" 19#include "phy.h"
20#include "mac.h" 20#include "falcon.h"
21 21
22#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \ 22#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \
23 MDIO_MMDREG_DEVS_PMAPMD | \ 23 MDIO_MMDREG_DEVS_PMAPMD | \
@@ -125,7 +125,7 @@ static int xfp_phy_check_hw(struct efx_nic *efx)
125 int link_up = xfp_link_ok(efx); 125 int link_up = xfp_link_ok(efx);
126 /* Simulate a PHY event if link state has changed */ 126 /* Simulate a PHY event if link state has changed */
127 if (link_up != efx->link_up) 127 if (link_up != efx->link_up)
128 falcon_xmac_sim_phy_event(efx); 128 falcon_sim_phy_event(efx);
129 129
130 rc = efx->board_info.monitor(efx); 130 rc = efx->board_info.monitor(efx);
131 if (rc) { 131 if (rc) {
@@ -169,11 +169,14 @@ static void xfp_phy_fini(struct efx_nic *efx)
169} 169}
170 170
171struct efx_phy_operations falcon_xfp_phy_ops = { 171struct efx_phy_operations falcon_xfp_phy_ops = {
172 .macs = EFX_XMAC,
172 .init = xfp_phy_init, 173 .init = xfp_phy_init,
173 .reconfigure = xfp_phy_reconfigure, 174 .reconfigure = xfp_phy_reconfigure,
174 .check_hw = xfp_phy_check_hw, 175 .check_hw = xfp_phy_check_hw,
175 .fini = xfp_phy_fini, 176 .fini = xfp_phy_fini,
176 .clear_interrupt = xfp_phy_clear_interrupt, 177 .clear_interrupt = xfp_phy_clear_interrupt,
178 .get_settings = mdio_clause45_get_settings,
179 .set_settings = mdio_clause45_set_settings,
177 .mmds = XFP_REQUIRED_DEVS, 180 .mmds = XFP_REQUIRED_DEVS,
178 .loopbacks = XFP_LOOPBACKS, 181 .loopbacks = XFP_LOOPBACKS,
179}; 182};