aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-09-01 07:48:50 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-09-03 09:53:48 -0400
commit2467ca46b6bb7672ed59fc74ac6780bf10bcd742 (patch)
treeb7854b4baee29215985a931d8d423eb2b4def39a /drivers/net/sfc
parentbc3c90a2b70652b87cde8de65275d6f41d0f24c3 (diff)
sfc: Cleanup reset code
Move more code from efx_reset() into efx_reset_down() and efx_reset_up(). Stop propagating MAC/PHY setting failures from efx_reset_down() and efx_reset_up() as these should not be fatal. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/efx.c98
1 files changed, 41 insertions, 57 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index f226dcf18c7d..f34dbf2c5b69 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1527,46 +1527,58 @@ static void efx_unregister_netdev(struct efx_nic *efx)
1527 * 1527 *
1528 **************************************************************************/ 1528 **************************************************************************/
1529 1529
1530/* The final hardware and software finalisation before reset. */ 1530/* Tears down the entire software state and most of the hardware state
1531static int efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) 1531 * before reset. */
1532static void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
1532{ 1533{
1533 int rc; 1534 int rc;
1534 1535
1535 EFX_ASSERT_RESET_SERIALISED(efx); 1536 EFX_ASSERT_RESET_SERIALISED(efx);
1536 1537
1538 /* The net_dev->get_stats handler is quite slow, and will fail
1539 * if a fetch is pending over reset. Serialise against it. */
1540 spin_lock(&efx->stats_lock);
1541 spin_unlock(&efx->stats_lock);
1542
1543 efx_stop_all(efx);
1544 mutex_lock(&efx->mac_lock);
1545
1537 rc = falcon_xmac_get_settings(efx, ecmd); 1546 rc = falcon_xmac_get_settings(efx, ecmd);
1538 if (rc) { 1547 if (rc)
1539 EFX_ERR(efx, "could not back up PHY settings\n"); 1548 EFX_ERR(efx, "could not back up PHY settings\n");
1540 goto fail;
1541 }
1542 1549
1543 efx_fini_channels(efx); 1550 efx_fini_channels(efx);
1544 return 0;
1545
1546 fail:
1547 return rc;
1548} 1551}
1549 1552
1550/* The first part of software initialisation after a hardware reset 1553/* This function will always ensure that the locks acquired in
1551 * This function does not handle serialisation with the kernel, it 1554 * efx_reset_down() are released. A failure return code indicates
1552 * assumes the caller has done this */ 1555 * that we were unable to reinitialise the hardware, and the
1553static int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd) 1556 * driver should be disabled. If ok is false, then the rx and tx
1557 * engines are not restarted, pending a RESET_DISABLE. */
1558static int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
1559 bool ok)
1554{ 1560{
1555 int rc; 1561 int rc;
1556 1562
1557 efx_init_channels(efx); 1563 EFX_ASSERT_RESET_SERIALISED(efx);
1558 1564
1559 /* Restore MAC and PHY settings. */ 1565 rc = falcon_init_nic(efx);
1560 rc = falcon_xmac_set_settings(efx, ecmd);
1561 if (rc) { 1566 if (rc) {
1562 EFX_ERR(efx, "could not restore PHY settings\n"); 1567 EFX_ERR(efx, "failed to initialise NIC\n");
1563 goto fail; 1568 ok = false;
1564 } 1569 }
1565 1570
1566 return 0; 1571 if (ok) {
1572 efx_init_channels(efx);
1567 1573
1568 fail: 1574 if (falcon_xmac_set_settings(efx, ecmd))
1569 efx_fini_channels(efx); 1575 EFX_ERR(efx, "could not restore PHY settings\n");
1576 }
1577
1578 mutex_unlock(&efx->mac_lock);
1579
1580 if (ok)
1581 efx_start_all(efx);
1570 return rc; 1582 return rc;
1571} 1583}
1572 1584
@@ -1598,22 +1610,12 @@ static int efx_reset(struct efx_nic *efx)
1598 efx->state = STATE_RESETTING; 1610 efx->state = STATE_RESETTING;
1599 EFX_INFO(efx, "resetting (%d)\n", method); 1611 EFX_INFO(efx, "resetting (%d)\n", method);
1600 1612
1601 /* The net_dev->get_stats handler is quite slow, and will fail 1613 efx_reset_down(efx, &ecmd);
1602 * if a fetch is pending over reset. Serialise against it. */
1603 spin_lock(&efx->stats_lock);
1604 spin_unlock(&efx->stats_lock);
1605
1606 efx_stop_all(efx);
1607 mutex_lock(&efx->mac_lock);
1608
1609 rc = efx_reset_down(efx, &ecmd);
1610 if (rc)
1611 goto fail1;
1612 1614
1613 rc = falcon_reset_hw(efx, method); 1615 rc = falcon_reset_hw(efx, method);
1614 if (rc) { 1616 if (rc) {
1615 EFX_ERR(efx, "failed to reset hardware\n"); 1617 EFX_ERR(efx, "failed to reset hardware\n");
1616 goto fail2; 1618 goto fail;
1617 } 1619 }
1618 1620
1619 /* Allow resets to be rescheduled. */ 1621 /* Allow resets to be rescheduled. */
@@ -1625,46 +1627,28 @@ static int efx_reset(struct efx_nic *efx)
1625 * can respond to requests. */ 1627 * can respond to requests. */
1626 pci_set_master(efx->pci_dev); 1628 pci_set_master(efx->pci_dev);
1627 1629
1628 /* Reinitialise device. This is appropriate in the RESET_TYPE_DISABLE
1629 * case so the driver can talk to external SRAM */
1630 rc = falcon_init_nic(efx);
1631 if (rc) {
1632 EFX_ERR(efx, "failed to initialise NIC\n");
1633 goto fail3;
1634 }
1635
1636 /* Leave device stopped if necessary */ 1630 /* Leave device stopped if necessary */
1637 if (method == RESET_TYPE_DISABLE) { 1631 if (method == RESET_TYPE_DISABLE) {
1638 /* Reinitialise the device anyway so the driver unload sequence
1639 * can talk to the external SRAM */
1640 falcon_init_nic(efx);
1641 rc = -EIO; 1632 rc = -EIO;
1642 goto fail4; 1633 goto fail;
1643 } 1634 }
1644 1635
1645 rc = efx_reset_up(efx, &ecmd); 1636 rc = efx_reset_up(efx, &ecmd, true);
1646 if (rc) 1637 if (rc)
1647 goto fail5; 1638 goto disable;
1648 1639
1649 mutex_unlock(&efx->mac_lock);
1650 EFX_LOG(efx, "reset complete\n"); 1640 EFX_LOG(efx, "reset complete\n");
1651
1652 efx->state = STATE_RUNNING; 1641 efx->state = STATE_RUNNING;
1653 efx_start_all(efx);
1654
1655 unlock_rtnl: 1642 unlock_rtnl:
1656 rtnl_unlock(); 1643 rtnl_unlock();
1657 return 0; 1644 return 0;
1658 1645
1659 fail5: 1646 fail:
1660 fail4: 1647 efx_reset_up(efx, &ecmd, false);
1661 fail3: 1648 disable:
1662 fail2:
1663 fail1:
1664 EFX_ERR(efx, "has been disabled\n"); 1649 EFX_ERR(efx, "has been disabled\n");
1665 efx->state = STATE_DISABLED; 1650 efx->state = STATE_DISABLED;
1666 1651
1667 mutex_unlock(&efx->mac_lock);
1668 rtnl_unlock(); 1652 rtnl_unlock();
1669 efx_unregister_netdev(efx); 1653 efx_unregister_netdev(efx);
1670 efx_fini_port(efx); 1654 efx_fini_port(efx);