aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/efx.c
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/net/sfc/efx.c
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/net/sfc/efx.c')
-rw-r--r--drivers/net/sfc/efx.c62
1 files changed, 43 insertions, 19 deletions
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);