diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-09-01 07:48:50 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-03 09:53:48 -0400 |
commit | 2467ca46b6bb7672ed59fc74ac6780bf10bcd742 (patch) | |
tree | b7854b4baee29215985a931d8d423eb2b4def39a /drivers/net/sfc | |
parent | bc3c90a2b70652b87cde8de65275d6f41d0f24c3 (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.c | 98 |
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 |
1531 | static int efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 1531 | * before reset. */ |
1532 | static 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 |
1553 | static 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. */ | ||
1558 | static 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); |