diff options
| -rw-r--r-- | drivers/net/igb/e1000_82575.c | 11 | ||||
| -rw-r--r-- | drivers/net/igb/igb.h | 9 | ||||
| -rw-r--r-- | drivers/net/igb/igb_main.c | 24 | ||||
| -rw-r--r-- | drivers/net/sfc/efx.c | 59 | ||||
| -rw-r--r-- | drivers/net/sfc/efx.h | 9 | ||||
| -rw-r--r-- | drivers/net/sfc/ethtool.c | 3 | ||||
| -rw-r--r-- | drivers/net/sfc/falcon.c | 32 | ||||
| -rw-r--r-- | drivers/net/sfc/mdio_10g.c | 191 | ||||
| -rw-r--r-- | drivers/net/sfc/mdio_10g.h | 3 | ||||
| -rw-r--r-- | drivers/net/sfc/net_driver.h | 9 | ||||
| -rw-r--r-- | drivers/net/sfc/phy.h | 1 | ||||
| -rw-r--r-- | drivers/net/sfc/selftest.c | 7 | ||||
| -rw-r--r-- | drivers/net/sfc/sfe4001.c | 42 | ||||
| -rw-r--r-- | drivers/net/sfc/tenxpress.c | 213 | ||||
| -rw-r--r-- | drivers/net/sfc/workarounds.h | 12 | ||||
| -rw-r--r-- | drivers/net/sky2.c | 6 | ||||
| -rw-r--r-- | net/ipv6/ip6mr.c | 1 | ||||
| -rw-r--r-- | net/packet/af_packet.c | 9 |
18 files changed, 313 insertions, 328 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index f5e2e7235fcb..13ca73f96ec6 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
| @@ -699,11 +699,18 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw) | |||
| 699 | 699 | ||
| 700 | /* SGMII link check is done through the PCS register. */ | 700 | /* SGMII link check is done through the PCS register. */ |
| 701 | if ((hw->phy.media_type != e1000_media_type_copper) || | 701 | if ((hw->phy.media_type != e1000_media_type_copper) || |
| 702 | (igb_sgmii_active_82575(hw))) | 702 | (igb_sgmii_active_82575(hw))) { |
| 703 | ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed, | 703 | ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed, |
| 704 | &duplex); | 704 | &duplex); |
| 705 | else | 705 | /* |
| 706 | * Use this flag to determine if link needs to be checked or | ||
| 707 | * not. If we have link clear the flag so that we do not | ||
| 708 | * continue to check for link. | ||
| 709 | */ | ||
| 710 | hw->mac.get_link_status = !hw->mac.serdes_has_link; | ||
| 711 | } else { | ||
| 706 | ret_val = igb_check_for_copper_link(hw); | 712 | ret_val = igb_check_for_copper_link(hw); |
| 713 | } | ||
| 707 | 714 | ||
| 708 | return ret_val; | 715 | return ret_val; |
| 709 | } | 716 | } |
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 5a27825cc48a..aebef8e48e76 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h | |||
| @@ -300,11 +300,10 @@ struct igb_adapter { | |||
| 300 | 300 | ||
| 301 | #define IGB_FLAG_HAS_MSI (1 << 0) | 301 | #define IGB_FLAG_HAS_MSI (1 << 0) |
| 302 | #define IGB_FLAG_MSI_ENABLE (1 << 1) | 302 | #define IGB_FLAG_MSI_ENABLE (1 << 1) |
| 303 | #define IGB_FLAG_HAS_DCA (1 << 2) | 303 | #define IGB_FLAG_DCA_ENABLED (1 << 2) |
| 304 | #define IGB_FLAG_DCA_ENABLED (1 << 3) | 304 | #define IGB_FLAG_IN_NETPOLL (1 << 3) |
| 305 | #define IGB_FLAG_IN_NETPOLL (1 << 5) | 305 | #define IGB_FLAG_QUAD_PORT_A (1 << 4) |
| 306 | #define IGB_FLAG_QUAD_PORT_A (1 << 6) | 306 | #define IGB_FLAG_NEED_CTX_IDX (1 << 5) |
| 307 | #define IGB_FLAG_NEED_CTX_IDX (1 << 7) | ||
| 308 | 307 | ||
| 309 | enum e1000_state_t { | 308 | enum e1000_state_t { |
| 310 | __IGB_TESTING, | 309 | __IGB_TESTING, |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index b82b0fb2056c..a50db5398fa5 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
| @@ -206,10 +206,11 @@ static int __init igb_init_module(void) | |||
| 206 | 206 | ||
| 207 | global_quad_port_a = 0; | 207 | global_quad_port_a = 0; |
| 208 | 208 | ||
| 209 | ret = pci_register_driver(&igb_driver); | ||
| 210 | #ifdef CONFIG_IGB_DCA | 209 | #ifdef CONFIG_IGB_DCA |
| 211 | dca_register_notify(&dca_notifier); | 210 | dca_register_notify(&dca_notifier); |
| 212 | #endif | 211 | #endif |
| 212 | |||
| 213 | ret = pci_register_driver(&igb_driver); | ||
| 213 | return ret; | 214 | return ret; |
| 214 | } | 215 | } |
| 215 | 216 | ||
| @@ -1156,11 +1157,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
| 1156 | 1157 | ||
| 1157 | /* set flags */ | 1158 | /* set flags */ |
| 1158 | switch (hw->mac.type) { | 1159 | switch (hw->mac.type) { |
| 1159 | case e1000_82576: | ||
| 1160 | case e1000_82575: | 1160 | case e1000_82575: |
| 1161 | adapter->flags |= IGB_FLAG_HAS_DCA; | ||
| 1162 | adapter->flags |= IGB_FLAG_NEED_CTX_IDX; | 1161 | adapter->flags |= IGB_FLAG_NEED_CTX_IDX; |
| 1163 | break; | 1162 | break; |
| 1163 | case e1000_82576: | ||
| 1164 | default: | 1164 | default: |
| 1165 | break; | 1165 | break; |
| 1166 | } | 1166 | } |
| @@ -1310,8 +1310,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
| 1310 | goto err_register; | 1310 | goto err_register; |
| 1311 | 1311 | ||
| 1312 | #ifdef CONFIG_IGB_DCA | 1312 | #ifdef CONFIG_IGB_DCA |
| 1313 | if ((adapter->flags & IGB_FLAG_HAS_DCA) && | 1313 | if (dca_add_requester(&pdev->dev) == 0) { |
| 1314 | (dca_add_requester(&pdev->dev) == 0)) { | ||
| 1315 | adapter->flags |= IGB_FLAG_DCA_ENABLED; | 1314 | adapter->flags |= IGB_FLAG_DCA_ENABLED; |
| 1316 | dev_info(&pdev->dev, "DCA enabled\n"); | 1315 | dev_info(&pdev->dev, "DCA enabled\n"); |
| 1317 | /* Always use CB2 mode, difference is masked | 1316 | /* Always use CB2 mode, difference is masked |
| @@ -1835,11 +1834,11 @@ static void igb_setup_rctl(struct igb_adapter *adapter) | |||
| 1835 | rctl |= E1000_RCTL_SECRC; | 1834 | rctl |= E1000_RCTL_SECRC; |
| 1836 | 1835 | ||
| 1837 | /* | 1836 | /* |
| 1838 | * disable store bad packets, long packet enable, and clear size bits. | 1837 | * disable store bad packets and clear size bits. |
| 1839 | */ | 1838 | */ |
| 1840 | rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256); | 1839 | rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256); |
| 1841 | 1840 | ||
| 1842 | if (adapter->netdev->mtu > ETH_DATA_LEN) | 1841 | /* enable LPE when to prevent packets larger than max_frame_size */ |
| 1843 | rctl |= E1000_RCTL_LPE; | 1842 | rctl |= E1000_RCTL_LPE; |
| 1844 | 1843 | ||
| 1845 | /* Setup buffer sizes */ | 1844 | /* Setup buffer sizes */ |
| @@ -1865,7 +1864,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter) | |||
| 1865 | */ | 1864 | */ |
| 1866 | /* allocations using alloc_page take too long for regular MTU | 1865 | /* allocations using alloc_page take too long for regular MTU |
| 1867 | * so only enable packet split for jumbo frames */ | 1866 | * so only enable packet split for jumbo frames */ |
| 1868 | if (rctl & E1000_RCTL_LPE) { | 1867 | if (adapter->netdev->mtu > ETH_DATA_LEN) { |
| 1869 | adapter->rx_ps_hdr_size = IGB_RXBUFFER_128; | 1868 | adapter->rx_ps_hdr_size = IGB_RXBUFFER_128; |
| 1870 | srrctl |= adapter->rx_ps_hdr_size << | 1869 | srrctl |= adapter->rx_ps_hdr_size << |
| 1871 | E1000_SRRCTL_BSIZEHDRSIZE_SHIFT; | 1870 | E1000_SRRCTL_BSIZEHDRSIZE_SHIFT; |
| @@ -3473,19 +3472,16 @@ static int __igb_notify_dca(struct device *dev, void *data) | |||
| 3473 | struct e1000_hw *hw = &adapter->hw; | 3472 | struct e1000_hw *hw = &adapter->hw; |
| 3474 | unsigned long event = *(unsigned long *)data; | 3473 | unsigned long event = *(unsigned long *)data; |
| 3475 | 3474 | ||
| 3476 | if (!(adapter->flags & IGB_FLAG_HAS_DCA)) | ||
| 3477 | goto out; | ||
| 3478 | |||
| 3479 | switch (event) { | 3475 | switch (event) { |
| 3480 | case DCA_PROVIDER_ADD: | 3476 | case DCA_PROVIDER_ADD: |
| 3481 | /* if already enabled, don't do it again */ | 3477 | /* if already enabled, don't do it again */ |
| 3482 | if (adapter->flags & IGB_FLAG_DCA_ENABLED) | 3478 | if (adapter->flags & IGB_FLAG_DCA_ENABLED) |
| 3483 | break; | 3479 | break; |
| 3484 | adapter->flags |= IGB_FLAG_DCA_ENABLED; | ||
| 3485 | /* Always use CB2 mode, difference is masked | 3480 | /* Always use CB2 mode, difference is masked |
| 3486 | * in the CB driver. */ | 3481 | * in the CB driver. */ |
| 3487 | wr32(E1000_DCA_CTRL, 2); | 3482 | wr32(E1000_DCA_CTRL, 2); |
| 3488 | if (dca_add_requester(dev) == 0) { | 3483 | if (dca_add_requester(dev) == 0) { |
| 3484 | adapter->flags |= IGB_FLAG_DCA_ENABLED; | ||
| 3489 | dev_info(&adapter->pdev->dev, "DCA enabled\n"); | 3485 | dev_info(&adapter->pdev->dev, "DCA enabled\n"); |
| 3490 | igb_setup_dca(adapter); | 3486 | igb_setup_dca(adapter); |
| 3491 | break; | 3487 | break; |
| @@ -3502,7 +3498,7 @@ static int __igb_notify_dca(struct device *dev, void *data) | |||
| 3502 | } | 3498 | } |
| 3503 | break; | 3499 | break; |
| 3504 | } | 3500 | } |
| 3505 | out: | 3501 | |
| 3506 | return 0; | 3502 | return 0; |
| 3507 | } | 3503 | } |
| 3508 | 3504 | ||
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 7673fd92eaf5..ab0e09bf154d 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
| @@ -676,9 +676,8 @@ static int efx_init_port(struct efx_nic *efx) | |||
| 676 | rc = efx->phy_op->init(efx); | 676 | rc = efx->phy_op->init(efx); |
| 677 | if (rc) | 677 | if (rc) |
| 678 | return rc; | 678 | return rc; |
| 679 | efx->phy_op->reconfigure(efx); | ||
| 680 | |||
| 681 | mutex_lock(&efx->mac_lock); | 679 | mutex_lock(&efx->mac_lock); |
| 680 | efx->phy_op->reconfigure(efx); | ||
| 682 | rc = falcon_switch_mac(efx); | 681 | rc = falcon_switch_mac(efx); |
| 683 | mutex_unlock(&efx->mac_lock); | 682 | mutex_unlock(&efx->mac_lock); |
| 684 | if (rc) | 683 | if (rc) |
| @@ -686,7 +685,7 @@ static int efx_init_port(struct efx_nic *efx) | |||
| 686 | efx->mac_op->reconfigure(efx); | 685 | efx->mac_op->reconfigure(efx); |
| 687 | 686 | ||
| 688 | efx->port_initialized = true; | 687 | efx->port_initialized = true; |
| 689 | efx->stats_enabled = true; | 688 | efx_stats_enable(efx); |
| 690 | return 0; | 689 | return 0; |
| 691 | 690 | ||
| 692 | fail: | 691 | fail: |
| @@ -735,6 +734,7 @@ static void efx_fini_port(struct efx_nic *efx) | |||
| 735 | if (!efx->port_initialized) | 734 | if (!efx->port_initialized) |
| 736 | return; | 735 | return; |
| 737 | 736 | ||
| 737 | efx_stats_disable(efx); | ||
| 738 | efx->phy_op->fini(efx); | 738 | efx->phy_op->fini(efx); |
| 739 | efx->port_initialized = false; | 739 | efx->port_initialized = false; |
| 740 | 740 | ||
| @@ -1361,6 +1361,20 @@ static int efx_net_stop(struct net_device *net_dev) | |||
| 1361 | return 0; | 1361 | return 0; |
| 1362 | } | 1362 | } |
| 1363 | 1363 | ||
| 1364 | void efx_stats_disable(struct efx_nic *efx) | ||
| 1365 | { | ||
| 1366 | spin_lock(&efx->stats_lock); | ||
| 1367 | ++efx->stats_disable_count; | ||
| 1368 | spin_unlock(&efx->stats_lock); | ||
| 1369 | } | ||
| 1370 | |||
| 1371 | void efx_stats_enable(struct efx_nic *efx) | ||
| 1372 | { | ||
| 1373 | spin_lock(&efx->stats_lock); | ||
| 1374 | --efx->stats_disable_count; | ||
| 1375 | spin_unlock(&efx->stats_lock); | ||
| 1376 | } | ||
| 1377 | |||
| 1364 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ | 1378 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ |
| 1365 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) | 1379 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) |
| 1366 | { | 1380 | { |
| @@ -1369,12 +1383,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev) | |||
| 1369 | struct net_device_stats *stats = &net_dev->stats; | 1383 | struct net_device_stats *stats = &net_dev->stats; |
| 1370 | 1384 | ||
| 1371 | /* Update stats if possible, but do not wait if another thread | 1385 | /* Update stats if possible, but do not wait if another thread |
| 1372 | * is updating them (or resetting the NIC); slightly stale | 1386 | * is updating them or if MAC stats fetches are temporarily |
| 1373 | * stats are acceptable. | 1387 | * disabled; slightly stale stats are acceptable. |
| 1374 | */ | 1388 | */ |
| 1375 | if (!spin_trylock(&efx->stats_lock)) | 1389 | if (!spin_trylock(&efx->stats_lock)) |
| 1376 | return stats; | 1390 | return stats; |
| 1377 | if (efx->stats_enabled) { | 1391 | if (!efx->stats_disable_count) { |
| 1378 | efx->mac_op->update_stats(efx); | 1392 | efx->mac_op->update_stats(efx); |
| 1379 | falcon_update_nic_stats(efx); | 1393 | falcon_update_nic_stats(efx); |
| 1380 | } | 1394 | } |
| @@ -1622,16 +1636,12 @@ static void efx_unregister_netdev(struct efx_nic *efx) | |||
| 1622 | 1636 | ||
| 1623 | /* Tears down the entire software state and most of the hardware state | 1637 | /* Tears down the entire software state and most of the hardware state |
| 1624 | * before reset. */ | 1638 | * before reset. */ |
| 1625 | void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 1639 | void efx_reset_down(struct efx_nic *efx, enum reset_type method, |
| 1640 | struct ethtool_cmd *ecmd) | ||
| 1626 | { | 1641 | { |
| 1627 | EFX_ASSERT_RESET_SERIALISED(efx); | 1642 | EFX_ASSERT_RESET_SERIALISED(efx); |
| 1628 | 1643 | ||
| 1629 | /* The net_dev->get_stats handler is quite slow, and will fail | 1644 | efx_stats_disable(efx); |
| 1630 | * if a fetch is pending over reset. Serialise against it. */ | ||
| 1631 | spin_lock(&efx->stats_lock); | ||
| 1632 | efx->stats_enabled = false; | ||
| 1633 | spin_unlock(&efx->stats_lock); | ||
| 1634 | |||
| 1635 | efx_stop_all(efx); | 1645 | efx_stop_all(efx); |
| 1636 | mutex_lock(&efx->mac_lock); | 1646 | mutex_lock(&efx->mac_lock); |
| 1637 | mutex_lock(&efx->spi_lock); | 1647 | mutex_lock(&efx->spi_lock); |
| @@ -1639,6 +1649,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) | |||
| 1639 | efx->phy_op->get_settings(efx, ecmd); | 1649 | efx->phy_op->get_settings(efx, ecmd); |
| 1640 | 1650 | ||
| 1641 | efx_fini_channels(efx); | 1651 | efx_fini_channels(efx); |
| 1652 | if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) | ||
| 1653 | efx->phy_op->fini(efx); | ||
| 1642 | } | 1654 | } |
| 1643 | 1655 | ||
| 1644 | /* This function will always ensure that the locks acquired in | 1656 | /* This function will always ensure that the locks acquired in |
| @@ -1646,7 +1658,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) | |||
| 1646 | * that we were unable to reinitialise the hardware, and the | 1658 | * that we were unable to reinitialise the hardware, and the |
| 1647 | * driver should be disabled. If ok is false, then the rx and tx | 1659 | * driver should be disabled. If ok is false, then the rx and tx |
| 1648 | * engines are not restarted, pending a RESET_DISABLE. */ | 1660 | * engines are not restarted, pending a RESET_DISABLE. */ |
| 1649 | int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok) | 1661 | int efx_reset_up(struct efx_nic *efx, enum reset_type method, |
| 1662 | struct ethtool_cmd *ecmd, bool ok) | ||
| 1650 | { | 1663 | { |
| 1651 | int rc; | 1664 | int rc; |
| 1652 | 1665 | ||
| @@ -1658,6 +1671,15 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok) | |||
| 1658 | ok = false; | 1671 | ok = false; |
| 1659 | } | 1672 | } |
| 1660 | 1673 | ||
| 1674 | if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) { | ||
| 1675 | if (ok) { | ||
| 1676 | rc = efx->phy_op->init(efx); | ||
| 1677 | if (rc) | ||
| 1678 | ok = false; | ||
| 1679 | } else | ||
| 1680 | efx->port_initialized = false; | ||
| 1681 | } | ||
| 1682 | |||
| 1661 | if (ok) { | 1683 | if (ok) { |
| 1662 | efx_init_channels(efx); | 1684 | efx_init_channels(efx); |
| 1663 | 1685 | ||
| @@ -1670,7 +1692,7 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok) | |||
| 1670 | 1692 | ||
| 1671 | if (ok) { | 1693 | if (ok) { |
| 1672 | efx_start_all(efx); | 1694 | efx_start_all(efx); |
| 1673 | efx->stats_enabled = true; | 1695 | efx_stats_enable(efx); |
| 1674 | } | 1696 | } |
| 1675 | return rc; | 1697 | return rc; |
| 1676 | } | 1698 | } |
| @@ -1702,7 +1724,7 @@ static int efx_reset(struct efx_nic *efx) | |||
| 1702 | 1724 | ||
| 1703 | EFX_INFO(efx, "resetting (%d)\n", method); | 1725 | EFX_INFO(efx, "resetting (%d)\n", method); |
| 1704 | 1726 | ||
| 1705 | efx_reset_down(efx, &ecmd); | 1727 | efx_reset_down(efx, method, &ecmd); |
| 1706 | 1728 | ||
| 1707 | rc = falcon_reset_hw(efx, method); | 1729 | rc = falcon_reset_hw(efx, method); |
| 1708 | if (rc) { | 1730 | if (rc) { |
| @@ -1721,10 +1743,10 @@ static int efx_reset(struct efx_nic *efx) | |||
| 1721 | 1743 | ||
| 1722 | /* Leave device stopped if necessary */ | 1744 | /* Leave device stopped if necessary */ |
| 1723 | if (method == RESET_TYPE_DISABLE) { | 1745 | if (method == RESET_TYPE_DISABLE) { |
| 1724 | efx_reset_up(efx, &ecmd, false); | 1746 | efx_reset_up(efx, method, &ecmd, false); |
| 1725 | rc = -EIO; | 1747 | rc = -EIO; |
| 1726 | } else { | 1748 | } else { |
| 1727 | rc = efx_reset_up(efx, &ecmd, true); | 1749 | rc = efx_reset_up(efx, method, &ecmd, true); |
| 1728 | } | 1750 | } |
| 1729 | 1751 | ||
| 1730 | out_disable: | 1752 | out_disable: |
| @@ -1876,6 +1898,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
| 1876 | efx->rx_checksum_enabled = true; | 1898 | efx->rx_checksum_enabled = true; |
| 1877 | spin_lock_init(&efx->netif_stop_lock); | 1899 | spin_lock_init(&efx->netif_stop_lock); |
| 1878 | spin_lock_init(&efx->stats_lock); | 1900 | spin_lock_init(&efx->stats_lock); |
| 1901 | efx->stats_disable_count = 1; | ||
| 1879 | mutex_init(&efx->mac_lock); | 1902 | mutex_init(&efx->mac_lock); |
| 1880 | efx->mac_op = &efx_dummy_mac_operations; | 1903 | efx->mac_op = &efx_dummy_mac_operations; |
| 1881 | efx->phy_op = &efx_dummy_phy_operations; | 1904 | efx->phy_op = &efx_dummy_phy_operations; |
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 0dd7a532c78a..55d0f131b0e9 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h | |||
| @@ -36,13 +36,16 @@ extern void efx_process_channel_now(struct efx_channel *channel); | |||
| 36 | extern void efx_flush_queues(struct efx_nic *efx); | 36 | extern void efx_flush_queues(struct efx_nic *efx); |
| 37 | 37 | ||
| 38 | /* Ports */ | 38 | /* Ports */ |
| 39 | extern void efx_stats_disable(struct efx_nic *efx); | ||
| 40 | extern void efx_stats_enable(struct efx_nic *efx); | ||
| 39 | extern void efx_reconfigure_port(struct efx_nic *efx); | 41 | extern void efx_reconfigure_port(struct efx_nic *efx); |
| 40 | extern void __efx_reconfigure_port(struct efx_nic *efx); | 42 | extern void __efx_reconfigure_port(struct efx_nic *efx); |
| 41 | 43 | ||
| 42 | /* Reset handling */ | 44 | /* Reset handling */ |
| 43 | extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd); | 45 | extern void efx_reset_down(struct efx_nic *efx, enum reset_type method, |
| 44 | extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, | 46 | struct ethtool_cmd *ecmd); |
| 45 | bool ok); | 47 | extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, |
| 48 | struct ethtool_cmd *ecmd, bool ok); | ||
| 46 | 49 | ||
| 47 | /* Global */ | 50 | /* Global */ |
| 48 | extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); | 51 | extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 53d259e90187..7b5924c039b3 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
| @@ -219,9 +219,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev, | |||
| 219 | struct efx_nic *efx = netdev_priv(net_dev); | 219 | struct efx_nic *efx = netdev_priv(net_dev); |
| 220 | int rc; | 220 | int rc; |
| 221 | 221 | ||
| 222 | if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg) | ||
| 223 | return -EINVAL; | ||
| 224 | |||
| 225 | /* Falcon GMAC does not support 1000Mbps HD */ | 222 | /* Falcon GMAC does not support 1000Mbps HD */ |
| 226 | if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { | 223 | if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { |
| 227 | EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" | 224 | EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 5b9f2d9cc4ed..d5378e60fcdd 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
| @@ -824,10 +824,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, | |||
| 824 | rx_ev_pause_frm ? " [PAUSE]" : ""); | 824 | rx_ev_pause_frm ? " [PAUSE]" : ""); |
| 825 | } | 825 | } |
| 826 | #endif | 826 | #endif |
| 827 | |||
| 828 | if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) && | ||
| 829 | efx->phy_type == PHY_TYPE_SFX7101)) | ||
| 830 | tenxpress_crc_err(efx); | ||
| 831 | } | 827 | } |
| 832 | 828 | ||
| 833 | /* Handle receive events that are not in-order. */ | 829 | /* Handle receive events that are not in-order. */ |
| @@ -1887,7 +1883,7 @@ static int falcon_reset_macs(struct efx_nic *efx) | |||
| 1887 | 1883 | ||
| 1888 | /* MAC stats will fail whilst the TX fifo is draining. Serialise | 1884 | /* MAC stats will fail whilst the TX fifo is draining. Serialise |
| 1889 | * the drain sequence with the statistics fetch */ | 1885 | * the drain sequence with the statistics fetch */ |
| 1890 | spin_lock(&efx->stats_lock); | 1886 | efx_stats_disable(efx); |
| 1891 | 1887 | ||
| 1892 | falcon_read(efx, ®, MAC0_CTRL_REG_KER); | 1888 | falcon_read(efx, ®, MAC0_CTRL_REG_KER); |
| 1893 | EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1); | 1889 | EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1); |
| @@ -1917,7 +1913,7 @@ static int falcon_reset_macs(struct efx_nic *efx) | |||
| 1917 | udelay(10); | 1913 | udelay(10); |
| 1918 | } | 1914 | } |
| 1919 | 1915 | ||
| 1920 | spin_unlock(&efx->stats_lock); | 1916 | efx_stats_enable(efx); |
| 1921 | 1917 | ||
| 1922 | /* If we've reset the EM block and the link is up, then | 1918 | /* If we've reset the EM block and the link is up, then |
| 1923 | * we'll have to kick the XAUI link so the PHY can recover */ | 1919 | * we'll have to kick the XAUI link so the PHY can recover */ |
| @@ -2277,6 +2273,10 @@ int falcon_switch_mac(struct efx_nic *efx) | |||
| 2277 | struct efx_mac_operations *old_mac_op = efx->mac_op; | 2273 | struct efx_mac_operations *old_mac_op = efx->mac_op; |
| 2278 | efx_oword_t nic_stat; | 2274 | efx_oword_t nic_stat; |
| 2279 | unsigned strap_val; | 2275 | unsigned strap_val; |
| 2276 | int rc = 0; | ||
| 2277 | |||
| 2278 | /* Don't try to fetch MAC stats while we're switching MACs */ | ||
| 2279 | efx_stats_disable(efx); | ||
| 2280 | 2280 | ||
| 2281 | /* Internal loopbacks override the phy speed setting */ | 2281 | /* Internal loopbacks override the phy speed setting */ |
| 2282 | if (efx->loopback_mode == LOOPBACK_GMAC) { | 2282 | if (efx->loopback_mode == LOOPBACK_GMAC) { |
| @@ -2287,16 +2287,12 @@ int falcon_switch_mac(struct efx_nic *efx) | |||
| 2287 | efx->link_fd = true; | 2287 | efx->link_fd = true; |
| 2288 | } | 2288 | } |
| 2289 | 2289 | ||
| 2290 | WARN_ON(!mutex_is_locked(&efx->mac_lock)); | ||
| 2290 | efx->mac_op = (EFX_IS10G(efx) ? | 2291 | efx->mac_op = (EFX_IS10G(efx) ? |
| 2291 | &falcon_xmac_operations : &falcon_gmac_operations); | 2292 | &falcon_xmac_operations : &falcon_gmac_operations); |
| 2292 | if (old_mac_op == efx->mac_op) | ||
| 2293 | return 0; | ||
| 2294 | |||
| 2295 | WARN_ON(!mutex_is_locked(&efx->mac_lock)); | ||
| 2296 | |||
| 2297 | /* Not all macs support a mac-level link state */ | ||
| 2298 | efx->mac_up = true; | ||
| 2299 | 2293 | ||
| 2294 | /* Always push the NIC_STAT_REG setting even if the mac hasn't | ||
| 2295 | * changed, because this function is run post online reset */ | ||
| 2300 | falcon_read(efx, &nic_stat, NIC_STAT_REG); | 2296 | falcon_read(efx, &nic_stat, NIC_STAT_REG); |
| 2301 | strap_val = EFX_IS10G(efx) ? 5 : 3; | 2297 | strap_val = EFX_IS10G(efx) ? 5 : 3; |
| 2302 | if (falcon_rev(efx) >= FALCON_REV_B0) { | 2298 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
| @@ -2309,9 +2305,17 @@ int falcon_switch_mac(struct efx_nic *efx) | |||
| 2309 | BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val); | 2305 | BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val); |
| 2310 | } | 2306 | } |
| 2311 | 2307 | ||
| 2308 | if (old_mac_op == efx->mac_op) | ||
| 2309 | goto out; | ||
| 2312 | 2310 | ||
| 2313 | EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); | 2311 | EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); |
| 2314 | return falcon_reset_macs(efx); | 2312 | /* Not all macs support a mac-level link state */ |
| 2313 | efx->mac_up = true; | ||
| 2314 | |||
| 2315 | rc = falcon_reset_macs(efx); | ||
| 2316 | out: | ||
| 2317 | efx_stats_enable(efx); | ||
| 2318 | return rc; | ||
| 2315 | } | 2319 | } |
| 2316 | 2320 | ||
| 2317 | /* This call is responsible for hooking in the MAC and PHY operations */ | 2321 | /* This call is responsible for hooking in the MAC and PHY operations */ |
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index f6a16428113d..f9e2f95c3b48 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "net_driver.h" | 15 | #include "net_driver.h" |
| 16 | #include "mdio_10g.h" | 16 | #include "mdio_10g.h" |
| 17 | #include "boards.h" | 17 | #include "boards.h" |
| 18 | #include "workarounds.h" | ||
| 18 | 19 | ||
| 19 | int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, | 20 | int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, |
| 20 | int spins, int spintime) | 21 | int spins, int spintime) |
| @@ -179,17 +180,12 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) | |||
| 179 | return false; | 180 | return false; |
| 180 | else if (efx_phy_mode_disabled(efx->phy_mode)) | 181 | else if (efx_phy_mode_disabled(efx->phy_mode)) |
| 181 | return false; | 182 | return false; |
| 182 | else if (efx->loopback_mode == LOOPBACK_PHYXS) { | 183 | else if (efx->loopback_mode == LOOPBACK_PHYXS) |
| 183 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | | 184 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | |
| 184 | MDIO_MMDREG_DEVS_PCS | | 185 | MDIO_MMDREG_DEVS_PCS | |
| 185 | MDIO_MMDREG_DEVS_PMAPMD | | 186 | MDIO_MMDREG_DEVS_PMAPMD | |
| 186 | MDIO_MMDREG_DEVS_AN); | 187 | MDIO_MMDREG_DEVS_AN); |
| 187 | if (!mmd_mask) { | 188 | else if (efx->loopback_mode == LOOPBACK_PCS) |
| 188 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, | ||
| 189 | MDIO_PHYXS_STATUS2); | ||
| 190 | return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN)); | ||
| 191 | } | ||
| 192 | } else if (efx->loopback_mode == LOOPBACK_PCS) | ||
| 193 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | | 189 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | |
| 194 | MDIO_MMDREG_DEVS_PMAPMD | | 190 | MDIO_MMDREG_DEVS_PMAPMD | |
| 195 | MDIO_MMDREG_DEVS_AN); | 191 | MDIO_MMDREG_DEVS_AN); |
| @@ -197,6 +193,13 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) | |||
| 197 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD | | 193 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD | |
| 198 | MDIO_MMDREG_DEVS_AN); | 194 | MDIO_MMDREG_DEVS_AN); |
| 199 | 195 | ||
| 196 | if (!mmd_mask) { | ||
| 197 | /* Use presence of XGMII faults in leui of link state */ | ||
| 198 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, | ||
| 199 | MDIO_PHYXS_STATUS2); | ||
| 200 | return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN)); | ||
| 201 | } | ||
| 202 | |||
| 200 | while (mmd_mask) { | 203 | while (mmd_mask) { |
| 201 | if (mmd_mask & 1) { | 204 | if (mmd_mask & 1) { |
| 202 | /* Double reads because link state is latched, and a | 205 | /* Double reads because link state is latched, and a |
| @@ -263,7 +266,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx, | |||
| 263 | } | 266 | } |
| 264 | } | 267 | } |
| 265 | 268 | ||
| 266 | static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp) | 269 | static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr) |
| 267 | { | 270 | { |
| 268 | int phy_id = efx->mii.phy_id; | 271 | int phy_id = efx->mii.phy_id; |
| 269 | u32 result = 0; | 272 | u32 result = 0; |
| @@ -278,9 +281,6 @@ static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp) | |||
| 278 | result |= ADVERTISED_100baseT_Half; | 281 | result |= ADVERTISED_100baseT_Half; |
| 279 | if (reg & ADVERTISE_100FULL) | 282 | if (reg & ADVERTISE_100FULL) |
| 280 | result |= ADVERTISED_100baseT_Full; | 283 | result |= ADVERTISED_100baseT_Full; |
| 281 | if (reg & LPA_RESV) | ||
| 282 | result |= xnp; | ||
| 283 | |||
| 284 | return result; | 284 | return result; |
| 285 | } | 285 | } |
| 286 | 286 | ||
| @@ -310,7 +310,7 @@ void mdio_clause45_get_settings(struct efx_nic *efx, | |||
| 310 | */ | 310 | */ |
| 311 | void mdio_clause45_get_settings_ext(struct efx_nic *efx, | 311 | void mdio_clause45_get_settings_ext(struct efx_nic *efx, |
| 312 | struct ethtool_cmd *ecmd, | 312 | struct ethtool_cmd *ecmd, |
| 313 | u32 xnp, u32 xnp_lpa) | 313 | u32 npage_adv, u32 npage_lpa) |
| 314 | { | 314 | { |
| 315 | int phy_id = efx->mii.phy_id; | 315 | int phy_id = efx->mii.phy_id; |
| 316 | int reg; | 316 | int reg; |
| @@ -361,8 +361,8 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx, | |||
| 361 | ecmd->autoneg = AUTONEG_ENABLE; | 361 | ecmd->autoneg = AUTONEG_ENABLE; |
| 362 | ecmd->advertising |= | 362 | ecmd->advertising |= |
| 363 | ADVERTISED_Autoneg | | 363 | ADVERTISED_Autoneg | |
| 364 | mdio_clause45_get_an(efx, | 364 | mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) | |
| 365 | MDIO_AN_ADVERTISE, xnp); | 365 | npage_adv; |
| 366 | } else | 366 | } else |
| 367 | ecmd->autoneg = AUTONEG_DISABLE; | 367 | ecmd->autoneg = AUTONEG_DISABLE; |
| 368 | } else | 368 | } else |
| @@ -371,27 +371,30 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx, | |||
| 371 | if (ecmd->autoneg) { | 371 | if (ecmd->autoneg) { |
| 372 | /* If AN is complete, report best common mode, | 372 | /* If AN is complete, report best common mode, |
| 373 | * otherwise report best advertised mode. */ | 373 | * otherwise report best advertised mode. */ |
| 374 | u32 common = ecmd->advertising; | 374 | u32 modes = 0; |
| 375 | if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | 375 | if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, |
| 376 | MDIO_MMDREG_STAT1) & | 376 | MDIO_MMDREG_STAT1) & |
| 377 | (1 << MDIO_AN_STATUS_AN_DONE_LBN)) { | 377 | (1 << MDIO_AN_STATUS_AN_DONE_LBN)) |
| 378 | common &= mdio_clause45_get_an(efx, MDIO_AN_LPA, | 378 | modes = (ecmd->advertising & |
| 379 | xnp_lpa); | 379 | (mdio_clause45_get_an(efx, MDIO_AN_LPA) | |
| 380 | } | 380 | npage_lpa)); |
| 381 | if (common & ADVERTISED_10000baseT_Full) { | 381 | if (modes == 0) |
| 382 | modes = ecmd->advertising; | ||
| 383 | |||
| 384 | if (modes & ADVERTISED_10000baseT_Full) { | ||
| 382 | ecmd->speed = SPEED_10000; | 385 | ecmd->speed = SPEED_10000; |
| 383 | ecmd->duplex = DUPLEX_FULL; | 386 | ecmd->duplex = DUPLEX_FULL; |
| 384 | } else if (common & (ADVERTISED_1000baseT_Full | | 387 | } else if (modes & (ADVERTISED_1000baseT_Full | |
| 385 | ADVERTISED_1000baseT_Half)) { | 388 | ADVERTISED_1000baseT_Half)) { |
| 386 | ecmd->speed = SPEED_1000; | 389 | ecmd->speed = SPEED_1000; |
| 387 | ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full); | 390 | ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full); |
| 388 | } else if (common & (ADVERTISED_100baseT_Full | | 391 | } else if (modes & (ADVERTISED_100baseT_Full | |
| 389 | ADVERTISED_100baseT_Half)) { | 392 | ADVERTISED_100baseT_Half)) { |
| 390 | ecmd->speed = SPEED_100; | 393 | ecmd->speed = SPEED_100; |
| 391 | ecmd->duplex = !!(common & ADVERTISED_100baseT_Full); | 394 | ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); |
| 392 | } else { | 395 | } else { |
| 393 | ecmd->speed = SPEED_10; | 396 | ecmd->speed = SPEED_10; |
| 394 | ecmd->duplex = !!(common & ADVERTISED_10baseT_Full); | 397 | ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); |
| 395 | } | 398 | } |
| 396 | } else { | 399 | } else { |
| 397 | /* Report forced settings */ | 400 | /* Report forced settings */ |
| @@ -415,7 +418,7 @@ int mdio_clause45_set_settings(struct efx_nic *efx, | |||
| 415 | int phy_id = efx->mii.phy_id; | 418 | int phy_id = efx->mii.phy_id; |
| 416 | struct ethtool_cmd prev; | 419 | struct ethtool_cmd prev; |
| 417 | u32 required; | 420 | u32 required; |
| 418 | int ctrl1_bits, reg; | 421 | int reg; |
| 419 | 422 | ||
| 420 | efx->phy_op->get_settings(efx, &prev); | 423 | efx->phy_op->get_settings(efx, &prev); |
| 421 | 424 | ||
| @@ -430,99 +433,83 @@ int mdio_clause45_set_settings(struct efx_nic *efx, | |||
| 430 | if (prev.port != PORT_TP || ecmd->port != PORT_TP) | 433 | if (prev.port != PORT_TP || ecmd->port != PORT_TP) |
| 431 | return -EINVAL; | 434 | return -EINVAL; |
| 432 | 435 | ||
| 433 | /* Check that PHY supports these settings and work out the | 436 | /* Check that PHY supports these settings */ |
| 434 | * basic control bits */ | 437 | if (ecmd->autoneg) { |
| 435 | if (ecmd->duplex) { | 438 | required = SUPPORTED_Autoneg; |
| 439 | } else if (ecmd->duplex) { | ||
| 436 | switch (ecmd->speed) { | 440 | switch (ecmd->speed) { |
| 437 | case SPEED_10: | 441 | case SPEED_10: required = SUPPORTED_10baseT_Full; break; |
| 438 | ctrl1_bits = BMCR_FULLDPLX; | 442 | case SPEED_100: required = SUPPORTED_100baseT_Full; break; |
| 439 | required = SUPPORTED_10baseT_Full; | 443 | default: return -EINVAL; |
| 440 | break; | ||
| 441 | case SPEED_100: | ||
| 442 | ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX; | ||
| 443 | required = SUPPORTED_100baseT_Full; | ||
| 444 | break; | ||
| 445 | case SPEED_1000: | ||
| 446 | ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX; | ||
| 447 | required = SUPPORTED_1000baseT_Full; | ||
| 448 | break; | ||
| 449 | case SPEED_10000: | ||
| 450 | ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 | | ||
| 451 | BMCR_FULLDPLX); | ||
| 452 | required = SUPPORTED_10000baseT_Full; | ||
| 453 | break; | ||
| 454 | default: | ||
| 455 | return -EINVAL; | ||
| 456 | } | 444 | } |
| 457 | } else { | 445 | } else { |
| 458 | switch (ecmd->speed) { | 446 | switch (ecmd->speed) { |
| 459 | case SPEED_10: | 447 | case SPEED_10: required = SUPPORTED_10baseT_Half; break; |
| 460 | ctrl1_bits = 0; | 448 | case SPEED_100: required = SUPPORTED_100baseT_Half; break; |
| 461 | required = SUPPORTED_10baseT_Half; | 449 | default: return -EINVAL; |
| 462 | break; | ||
| 463 | case SPEED_100: | ||
| 464 | ctrl1_bits = BMCR_SPEED100; | ||
| 465 | required = SUPPORTED_100baseT_Half; | ||
| 466 | break; | ||
| 467 | case SPEED_1000: | ||
| 468 | ctrl1_bits = BMCR_SPEED1000; | ||
| 469 | required = SUPPORTED_1000baseT_Half; | ||
| 470 | break; | ||
| 471 | default: | ||
| 472 | return -EINVAL; | ||
| 473 | } | 450 | } |
| 474 | } | 451 | } |
| 475 | if (ecmd->autoneg) | ||
| 476 | required |= SUPPORTED_Autoneg; | ||
| 477 | required |= ecmd->advertising; | 452 | required |= ecmd->advertising; |
| 478 | if (required & ~prev.supported) | 453 | if (required & ~prev.supported) |
| 479 | return -EINVAL; | 454 | return -EINVAL; |
| 480 | 455 | ||
| 481 | /* Set the basic control bits */ | 456 | if (ecmd->autoneg) { |
| 482 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | 457 | bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full |
| 483 | MDIO_MMDREG_CTRL1); | 458 | || EFX_WORKAROUND_13204(efx)); |
| 484 | reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c); | 459 | |
| 485 | reg |= ctrl1_bits; | 460 | /* Set up the base page */ |
| 486 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1, | 461 | reg = ADVERTISE_CSMA; |
| 487 | reg); | 462 | if (ecmd->advertising & ADVERTISED_10baseT_Half) |
| 488 | 463 | reg |= ADVERTISE_10HALF; | |
| 489 | /* Set the AN registers */ | 464 | if (ecmd->advertising & ADVERTISED_10baseT_Full) |
| 490 | if (ecmd->autoneg != prev.autoneg || | 465 | reg |= ADVERTISE_10FULL; |
| 491 | ecmd->advertising != prev.advertising) { | 466 | if (ecmd->advertising & ADVERTISED_100baseT_Half) |
| 492 | bool xnp = false; | 467 | reg |= ADVERTISE_100HALF; |
| 493 | 468 | if (ecmd->advertising & ADVERTISED_100baseT_Full) | |
| 494 | if (efx->phy_op->set_xnp_advertise) | 469 | reg |= ADVERTISE_100FULL; |
| 495 | xnp = efx->phy_op->set_xnp_advertise(efx, | 470 | if (xnp) |
| 496 | ecmd->advertising); | 471 | reg |= ADVERTISE_RESV; |
| 497 | 472 | else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | | |
| 498 | if (ecmd->autoneg) { | 473 | ADVERTISED_1000baseT_Full)) |
| 499 | reg = 0; | 474 | reg |= ADVERTISE_NPAGE; |
| 500 | if (ecmd->advertising & ADVERTISED_10baseT_Half) | 475 | reg |= efx_fc_advertise(efx->wanted_fc); |
| 501 | reg |= ADVERTISE_10HALF; | 476 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, |
| 502 | if (ecmd->advertising & ADVERTISED_10baseT_Full) | 477 | MDIO_AN_ADVERTISE, reg); |
| 503 | reg |= ADVERTISE_10FULL; | 478 | |
| 504 | if (ecmd->advertising & ADVERTISED_100baseT_Half) | 479 | /* Set up the (extended) next page if necessary */ |
| 505 | reg |= ADVERTISE_100HALF; | 480 | if (efx->phy_op->set_npage_adv) |
| 506 | if (ecmd->advertising & ADVERTISED_100baseT_Full) | 481 | efx->phy_op->set_npage_adv(efx, ecmd->advertising); |
| 507 | reg |= ADVERTISE_100FULL; | ||
| 508 | if (xnp) | ||
| 509 | reg |= ADVERTISE_RESV; | ||
| 510 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, | ||
| 511 | MDIO_AN_ADVERTISE, reg); | ||
| 512 | } | ||
| 513 | 482 | ||
| 483 | /* Enable and restart AN */ | ||
| 514 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | 484 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, |
| 515 | MDIO_MMDREG_CTRL1); | 485 | MDIO_MMDREG_CTRL1); |
| 516 | if (ecmd->autoneg) | 486 | reg |= BMCR_ANENABLE; |
| 517 | reg |= BMCR_ANENABLE | BMCR_ANRESTART; | 487 | if (!(EFX_WORKAROUND_15195(efx) && |
| 518 | else | 488 | LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)) |
| 519 | reg &= ~BMCR_ANENABLE; | 489 | reg |= BMCR_ANRESTART; |
| 520 | if (xnp) | 490 | if (xnp) |
| 521 | reg |= 1 << MDIO_AN_CTRL_XNP_LBN; | 491 | reg |= 1 << MDIO_AN_CTRL_XNP_LBN; |
| 522 | else | 492 | else |
| 523 | reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); | 493 | reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); |
| 524 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, | 494 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, |
| 525 | MDIO_MMDREG_CTRL1, reg); | 495 | MDIO_MMDREG_CTRL1, reg); |
| 496 | } else { | ||
| 497 | /* Disable AN */ | ||
| 498 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, | ||
| 499 | MDIO_MMDREG_CTRL1, | ||
| 500 | __ffs(BMCR_ANENABLE), false); | ||
| 501 | |||
| 502 | /* Set the basic control bits */ | ||
| 503 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
| 504 | MDIO_MMDREG_CTRL1); | ||
| 505 | reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | | ||
| 506 | 0x003c); | ||
| 507 | if (ecmd->speed == SPEED_100) | ||
| 508 | reg |= BMCR_SPEED100; | ||
| 509 | if (ecmd->duplex) | ||
| 510 | reg |= BMCR_FULLDPLX; | ||
| 511 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
| 512 | MDIO_MMDREG_CTRL1, reg); | ||
| 526 | } | 513 | } |
| 527 | 514 | ||
| 528 | return 0; | 515 | return 0; |
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 09bf801d0569..8ba49773ce7e 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h | |||
| @@ -155,7 +155,8 @@ | |||
| 155 | #define MDIO_AN_XNP 22 | 155 | #define MDIO_AN_XNP 22 |
| 156 | #define MDIO_AN_LPA_XNP 25 | 156 | #define MDIO_AN_LPA_XNP 25 |
| 157 | 157 | ||
| 158 | #define MDIO_AN_10GBT_ADVERTISE 32 | 158 | #define MDIO_AN_10GBT_CTRL 32 |
| 159 | #define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12 | ||
| 159 | #define MDIO_AN_10GBT_STATUS (33) | 160 | #define MDIO_AN_10GBT_STATUS (33) |
| 160 | #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ | 161 | #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ |
| 161 | #define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ | 162 | #define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 5f255f75754e..e019ad1fb9a0 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
| @@ -566,7 +566,7 @@ struct efx_mac_operations { | |||
| 566 | * @poll: Poll for hardware state. Serialised by the mac_lock. | 566 | * @poll: Poll for hardware state. Serialised by the mac_lock. |
| 567 | * @get_settings: Get ethtool settings. Serialised by the mac_lock. | 567 | * @get_settings: Get ethtool settings. Serialised by the mac_lock. |
| 568 | * @set_settings: Set ethtool settings. Serialised by the mac_lock. | 568 | * @set_settings: Set ethtool settings. Serialised by the mac_lock. |
| 569 | * @set_xnp_advertise: Set abilities advertised in Extended Next Page | 569 | * @set_npage_adv: Set abilities advertised in (Extended) Next Page |
| 570 | * (only needed where AN bit is set in mmds) | 570 | * (only needed where AN bit is set in mmds) |
| 571 | * @num_tests: Number of PHY-specific tests/results | 571 | * @num_tests: Number of PHY-specific tests/results |
| 572 | * @test_names: Names of the tests/results | 572 | * @test_names: Names of the tests/results |
| @@ -586,7 +586,7 @@ struct efx_phy_operations { | |||
| 586 | struct ethtool_cmd *ecmd); | 586 | struct ethtool_cmd *ecmd); |
| 587 | int (*set_settings) (struct efx_nic *efx, | 587 | int (*set_settings) (struct efx_nic *efx, |
| 588 | struct ethtool_cmd *ecmd); | 588 | struct ethtool_cmd *ecmd); |
| 589 | bool (*set_xnp_advertise) (struct efx_nic *efx, u32); | 589 | void (*set_npage_adv) (struct efx_nic *efx, u32); |
| 590 | u32 num_tests; | 590 | u32 num_tests; |
| 591 | const char *const *test_names; | 591 | const char *const *test_names; |
| 592 | int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); | 592 | int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); |
| @@ -754,8 +754,7 @@ union efx_multicast_hash { | |||
| 754 | * &struct net_device_stats. | 754 | * &struct net_device_stats. |
| 755 | * @stats_buffer: DMA buffer for statistics | 755 | * @stats_buffer: DMA buffer for statistics |
| 756 | * @stats_lock: Statistics update lock. Serialises statistics fetches | 756 | * @stats_lock: Statistics update lock. Serialises statistics fetches |
| 757 | * @stats_enabled: Temporarily disable statistics fetches. | 757 | * @stats_disable_count: Nest count for disabling statistics fetches |
| 758 | * Serialised by @stats_lock | ||
| 759 | * @mac_op: MAC interface | 758 | * @mac_op: MAC interface |
| 760 | * @mac_address: Permanent MAC address | 759 | * @mac_address: Permanent MAC address |
| 761 | * @phy_type: PHY type | 760 | * @phy_type: PHY type |
| @@ -837,7 +836,7 @@ struct efx_nic { | |||
| 837 | struct efx_mac_stats mac_stats; | 836 | struct efx_mac_stats mac_stats; |
| 838 | struct efx_buffer stats_buffer; | 837 | struct efx_buffer stats_buffer; |
| 839 | spinlock_t stats_lock; | 838 | spinlock_t stats_lock; |
| 840 | bool stats_enabled; | 839 | unsigned int stats_disable_count; |
| 841 | 840 | ||
| 842 | struct efx_mac_operations *mac_op; | 841 | struct efx_mac_operations *mac_op; |
| 843 | unsigned char mac_address[ETH_ALEN]; | 842 | unsigned char mac_address[ETH_ALEN]; |
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index 58c493ef81bb..07e855c148bc 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h | |||
| @@ -17,7 +17,6 @@ extern struct efx_phy_operations falcon_sfx7101_phy_ops; | |||
| 17 | extern struct efx_phy_operations falcon_sft9001_phy_ops; | 17 | extern struct efx_phy_operations falcon_sft9001_phy_ops; |
| 18 | 18 | ||
| 19 | extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); | 19 | extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); |
| 20 | extern void tenxpress_crc_err(struct efx_nic *efx); | ||
| 21 | 20 | ||
| 22 | /**************************************************************************** | 21 | /**************************************************************************** |
| 23 | * Exported functions from the driver for XFP optical PHYs | 22 | * Exported functions from the driver for XFP optical PHYs |
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index dba0d64d50cd..0a598084c513 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c | |||
| @@ -665,6 +665,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, | |||
| 665 | { | 665 | { |
| 666 | enum efx_loopback_mode loopback_mode = efx->loopback_mode; | 666 | enum efx_loopback_mode loopback_mode = efx->loopback_mode; |
| 667 | int phy_mode = efx->phy_mode; | 667 | int phy_mode = efx->phy_mode; |
| 668 | enum reset_type reset_method = RESET_TYPE_INVISIBLE; | ||
| 668 | struct ethtool_cmd ecmd; | 669 | struct ethtool_cmd ecmd; |
| 669 | struct efx_channel *channel; | 670 | struct efx_channel *channel; |
| 670 | int rc_test = 0, rc_reset = 0, rc; | 671 | int rc_test = 0, rc_reset = 0, rc; |
| @@ -718,21 +719,21 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, | |||
| 718 | mutex_unlock(&efx->mac_lock); | 719 | mutex_unlock(&efx->mac_lock); |
| 719 | 720 | ||
| 720 | /* free up all consumers of SRAM (including all the queues) */ | 721 | /* free up all consumers of SRAM (including all the queues) */ |
| 721 | efx_reset_down(efx, &ecmd); | 722 | efx_reset_down(efx, reset_method, &ecmd); |
| 722 | 723 | ||
| 723 | rc = efx_test_chip(efx, tests); | 724 | rc = efx_test_chip(efx, tests); |
| 724 | if (rc && !rc_test) | 725 | if (rc && !rc_test) |
| 725 | rc_test = rc; | 726 | rc_test = rc; |
| 726 | 727 | ||
| 727 | /* reset the chip to recover from the register test */ | 728 | /* reset the chip to recover from the register test */ |
| 728 | rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL); | 729 | rc_reset = falcon_reset_hw(efx, reset_method); |
| 729 | 730 | ||
| 730 | /* Ensure that the phy is powered and out of loopback | 731 | /* Ensure that the phy is powered and out of loopback |
| 731 | * for the bist and loopback tests */ | 732 | * for the bist and loopback tests */ |
| 732 | efx->phy_mode &= ~PHY_MODE_LOW_POWER; | 733 | efx->phy_mode &= ~PHY_MODE_LOW_POWER; |
| 733 | efx->loopback_mode = LOOPBACK_NONE; | 734 | efx->loopback_mode = LOOPBACK_NONE; |
| 734 | 735 | ||
| 735 | rc = efx_reset_up(efx, &ecmd, rc_reset == 0); | 736 | rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0); |
| 736 | if (rc && !rc_reset) | 737 | if (rc && !rc_reset) |
| 737 | rc_reset = rc; | 738 | rc_reset = rc; |
| 738 | 739 | ||
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 16b80acb9992..cb25ae5b257a 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c | |||
| @@ -186,19 +186,22 @@ static int sfn4111t_reset(struct efx_nic *efx) | |||
| 186 | { | 186 | { |
| 187 | efx_oword_t reg; | 187 | efx_oword_t reg; |
| 188 | 188 | ||
| 189 | /* GPIO pins are also used for I2C, so block that temporarily */ | 189 | /* GPIO 3 and the GPIO register are shared with I2C, so block that */ |
| 190 | mutex_lock(&efx->i2c_adap.bus_lock); | 190 | mutex_lock(&efx->i2c_adap.bus_lock); |
| 191 | 191 | ||
| 192 | /* Pull RST_N (GPIO 2) low then let it up again, setting the | ||
| 193 | * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the | ||
| 194 | * output enables; the output levels should always be 0 (low) | ||
| 195 | * and we rely on external pull-ups. */ | ||
| 192 | falcon_read(efx, ®, GPIO_CTL_REG_KER); | 196 | falcon_read(efx, ®, GPIO_CTL_REG_KER); |
| 193 | EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true); | 197 | EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true); |
| 194 | EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false); | ||
| 195 | falcon_write(efx, ®, GPIO_CTL_REG_KER); | 198 | falcon_write(efx, ®, GPIO_CTL_REG_KER); |
| 196 | msleep(1000); | 199 | msleep(1000); |
| 197 | EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true); | 200 | EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false); |
| 198 | EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true); | 201 | EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, |
| 199 | EFX_SET_OWORD_FIELD(reg, GPIO3_OUT, | 202 | !!(efx->phy_mode & PHY_MODE_SPECIAL)); |
| 200 | !(efx->phy_mode & PHY_MODE_SPECIAL)); | ||
| 201 | falcon_write(efx, ®, GPIO_CTL_REG_KER); | 203 | falcon_write(efx, ®, GPIO_CTL_REG_KER); |
| 204 | msleep(1); | ||
| 202 | 205 | ||
| 203 | mutex_unlock(&efx->i2c_adap.bus_lock); | 206 | mutex_unlock(&efx->i2c_adap.bus_lock); |
| 204 | 207 | ||
| @@ -232,12 +235,18 @@ static ssize_t set_phy_flash_cfg(struct device *dev, | |||
| 232 | } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { | 235 | } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { |
| 233 | err = -EBUSY; | 236 | err = -EBUSY; |
| 234 | } else { | 237 | } else { |
| 238 | /* Reset the PHY, reconfigure the MAC and enable/disable | ||
| 239 | * MAC stats accordingly. */ | ||
| 235 | efx->phy_mode = new_mode; | 240 | efx->phy_mode = new_mode; |
| 241 | if (new_mode & PHY_MODE_SPECIAL) | ||
| 242 | efx_stats_disable(efx); | ||
| 236 | if (efx->board_info.type == EFX_BOARD_SFE4001) | 243 | if (efx->board_info.type == EFX_BOARD_SFE4001) |
| 237 | err = sfe4001_poweron(efx); | 244 | err = sfe4001_poweron(efx); |
| 238 | else | 245 | else |
| 239 | err = sfn4111t_reset(efx); | 246 | err = sfn4111t_reset(efx); |
| 240 | efx_reconfigure_port(efx); | 247 | efx_reconfigure_port(efx); |
| 248 | if (!(new_mode & PHY_MODE_SPECIAL)) | ||
| 249 | efx_stats_enable(efx); | ||
| 241 | } | 250 | } |
| 242 | rtnl_unlock(); | 251 | rtnl_unlock(); |
| 243 | 252 | ||
| @@ -326,6 +335,11 @@ int sfe4001_init(struct efx_nic *efx) | |||
| 326 | efx->board_info.monitor = sfe4001_check_hw; | 335 | efx->board_info.monitor = sfe4001_check_hw; |
| 327 | efx->board_info.fini = sfe4001_fini; | 336 | efx->board_info.fini = sfe4001_fini; |
| 328 | 337 | ||
| 338 | if (efx->phy_mode & PHY_MODE_SPECIAL) { | ||
| 339 | /* PHY won't generate a 156.25 MHz clock and MAC stats fetch | ||
| 340 | * will fail. */ | ||
| 341 | efx_stats_disable(efx); | ||
| 342 | } | ||
| 329 | rc = sfe4001_poweron(efx); | 343 | rc = sfe4001_poweron(efx); |
| 330 | if (rc) | 344 | if (rc) |
| 331 | goto fail_ioexp; | 345 | goto fail_ioexp; |
| @@ -372,17 +386,25 @@ static void sfn4111t_fini(struct efx_nic *efx) | |||
| 372 | i2c_unregister_device(efx->board_info.hwmon_client); | 386 | i2c_unregister_device(efx->board_info.hwmon_client); |
| 373 | } | 387 | } |
| 374 | 388 | ||
| 375 | static struct i2c_board_info sfn4111t_hwmon_info = { | 389 | static struct i2c_board_info sfn4111t_a0_hwmon_info = { |
| 376 | I2C_BOARD_INFO("max6647", 0x4e), | 390 | I2C_BOARD_INFO("max6647", 0x4e), |
| 377 | .irq = -1, | 391 | .irq = -1, |
| 378 | }; | 392 | }; |
| 379 | 393 | ||
| 394 | static struct i2c_board_info sfn4111t_r5_hwmon_info = { | ||
| 395 | I2C_BOARD_INFO("max6646", 0x4d), | ||
| 396 | .irq = -1, | ||
| 397 | }; | ||
| 398 | |||
| 380 | int sfn4111t_init(struct efx_nic *efx) | 399 | int sfn4111t_init(struct efx_nic *efx) |
| 381 | { | 400 | { |
| 382 | int rc; | 401 | int rc; |
| 383 | 402 | ||
| 384 | efx->board_info.hwmon_client = | 403 | efx->board_info.hwmon_client = |
| 385 | i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info); | 404 | i2c_new_device(&efx->i2c_adap, |
| 405 | (efx->board_info.minor < 5) ? | ||
| 406 | &sfn4111t_a0_hwmon_info : | ||
| 407 | &sfn4111t_r5_hwmon_info); | ||
| 386 | if (!efx->board_info.hwmon_client) | 408 | if (!efx->board_info.hwmon_client) |
| 387 | return -EIO; | 409 | return -EIO; |
| 388 | 410 | ||
| @@ -394,8 +416,10 @@ int sfn4111t_init(struct efx_nic *efx) | |||
| 394 | if (rc) | 416 | if (rc) |
| 395 | goto fail_hwmon; | 417 | goto fail_hwmon; |
| 396 | 418 | ||
| 397 | if (efx->phy_mode & PHY_MODE_SPECIAL) | 419 | if (efx->phy_mode & PHY_MODE_SPECIAL) { |
| 420 | efx_stats_disable(efx); | ||
| 398 | sfn4111t_reset(efx); | 421 | sfn4111t_reset(efx); |
| 422 | } | ||
| 399 | 423 | ||
| 400 | return 0; | 424 | return 0; |
| 401 | 425 | ||
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 9ecb77da9545..f0efd246962c 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
| @@ -67,6 +67,8 @@ | |||
| 67 | #define PMA_PMD_EXT_CLK312_WIDTH 1 | 67 | #define PMA_PMD_EXT_CLK312_WIDTH 1 |
| 68 | #define PMA_PMD_EXT_LPOWER_LBN 12 | 68 | #define PMA_PMD_EXT_LPOWER_LBN 12 |
| 69 | #define PMA_PMD_EXT_LPOWER_WIDTH 1 | 69 | #define PMA_PMD_EXT_LPOWER_WIDTH 1 |
| 70 | #define PMA_PMD_EXT_ROBUST_LBN 14 | ||
| 71 | #define PMA_PMD_EXT_ROBUST_WIDTH 1 | ||
| 70 | #define PMA_PMD_EXT_SSR_LBN 15 | 72 | #define PMA_PMD_EXT_SSR_LBN 15 |
| 71 | #define PMA_PMD_EXT_SSR_WIDTH 1 | 73 | #define PMA_PMD_EXT_SSR_WIDTH 1 |
| 72 | 74 | ||
| @@ -177,35 +179,24 @@ | |||
| 177 | #define C22EXT_STATUS_LINK_LBN 2 | 179 | #define C22EXT_STATUS_LINK_LBN 2 |
| 178 | #define C22EXT_STATUS_LINK_WIDTH 1 | 180 | #define C22EXT_STATUS_LINK_WIDTH 1 |
| 179 | 181 | ||
| 180 | #define C22EXT_MSTSLV_REG 49162 | 182 | #define C22EXT_MSTSLV_CTRL 49161 |
| 181 | #define C22EXT_MSTSLV_1000_HD_LBN 10 | 183 | #define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8 |
| 182 | #define C22EXT_MSTSLV_1000_HD_WIDTH 1 | 184 | #define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9 |
| 183 | #define C22EXT_MSTSLV_1000_FD_LBN 11 | 185 | |
| 184 | #define C22EXT_MSTSLV_1000_FD_WIDTH 1 | 186 | #define C22EXT_MSTSLV_STATUS 49162 |
| 187 | #define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10 | ||
| 188 | #define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11 | ||
| 185 | 189 | ||
| 186 | /* Time to wait between powering down the LNPGA and turning off the power | 190 | /* Time to wait between powering down the LNPGA and turning off the power |
| 187 | * rails */ | 191 | * rails */ |
| 188 | #define LNPGA_PDOWN_WAIT (HZ / 5) | 192 | #define LNPGA_PDOWN_WAIT (HZ / 5) |
| 189 | 193 | ||
| 190 | static int crc_error_reset_threshold = 100; | ||
| 191 | module_param(crc_error_reset_threshold, int, 0644); | ||
| 192 | MODULE_PARM_DESC(crc_error_reset_threshold, | ||
| 193 | "Max number of CRC errors before XAUI reset"); | ||
| 194 | |||
| 195 | struct tenxpress_phy_data { | 194 | struct tenxpress_phy_data { |
| 196 | enum efx_loopback_mode loopback_mode; | 195 | enum efx_loopback_mode loopback_mode; |
| 197 | atomic_t bad_crc_count; | ||
| 198 | enum efx_phy_mode phy_mode; | 196 | enum efx_phy_mode phy_mode; |
| 199 | int bad_lp_tries; | 197 | int bad_lp_tries; |
| 200 | }; | 198 | }; |
| 201 | 199 | ||
| 202 | void tenxpress_crc_err(struct efx_nic *efx) | ||
| 203 | { | ||
| 204 | struct tenxpress_phy_data *phy_data = efx->phy_data; | ||
| 205 | if (phy_data != NULL) | ||
| 206 | atomic_inc(&phy_data->bad_crc_count); | ||
| 207 | } | ||
| 208 | |||
| 209 | static ssize_t show_phy_short_reach(struct device *dev, | 200 | static ssize_t show_phy_short_reach(struct device *dev, |
| 210 | struct device_attribute *attr, char *buf) | 201 | struct device_attribute *attr, char *buf) |
| 211 | { | 202 | { |
| @@ -284,7 +275,9 @@ static int tenxpress_init(struct efx_nic *efx) | |||
| 284 | PMA_PMD_XCONTROL_REG); | 275 | PMA_PMD_XCONTROL_REG); |
| 285 | reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | | 276 | reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | |
| 286 | (1 << PMA_PMD_EXT_CLK_OUT_LBN) | | 277 | (1 << PMA_PMD_EXT_CLK_OUT_LBN) | |
| 287 | (1 << PMA_PMD_EXT_CLK312_LBN)); | 278 | (1 << PMA_PMD_EXT_CLK312_LBN) | |
| 279 | (1 << PMA_PMD_EXT_ROBUST_LBN)); | ||
| 280 | |||
| 288 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | 281 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, |
| 289 | PMA_PMD_XCONTROL_REG, reg); | 282 | PMA_PMD_XCONTROL_REG, reg); |
| 290 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, | 283 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, |
| @@ -346,6 +339,7 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
| 346 | rc = tenxpress_init(efx); | 339 | rc = tenxpress_init(efx); |
| 347 | if (rc < 0) | 340 | if (rc < 0) |
| 348 | goto fail; | 341 | goto fail; |
| 342 | mdio_clause45_set_pause(efx); | ||
| 349 | 343 | ||
| 350 | if (efx->phy_type == PHY_TYPE_SFT9001B) { | 344 | if (efx->phy_type == PHY_TYPE_SFT9001B) { |
| 351 | rc = device_create_file(&efx->pci_dev->dev, | 345 | rc = device_create_file(&efx->pci_dev->dev, |
| @@ -376,8 +370,8 @@ static int tenxpress_special_reset(struct efx_nic *efx) | |||
| 376 | 370 | ||
| 377 | /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so | 371 | /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so |
| 378 | * a special software reset can glitch the XGMAC sufficiently for stats | 372 | * a special software reset can glitch the XGMAC sufficiently for stats |
| 379 | * requests to fail. Since we don't often special_reset, just lock. */ | 373 | * requests to fail. */ |
| 380 | spin_lock(&efx->stats_lock); | 374 | efx_stats_disable(efx); |
| 381 | 375 | ||
| 382 | /* Initiate reset */ | 376 | /* Initiate reset */ |
| 383 | reg = mdio_clause45_read(efx, efx->mii.phy_id, | 377 | reg = mdio_clause45_read(efx, efx->mii.phy_id, |
| @@ -392,17 +386,17 @@ static int tenxpress_special_reset(struct efx_nic *efx) | |||
| 392 | rc = mdio_clause45_wait_reset_mmds(efx, | 386 | rc = mdio_clause45_wait_reset_mmds(efx, |
| 393 | TENXPRESS_REQUIRED_DEVS); | 387 | TENXPRESS_REQUIRED_DEVS); |
| 394 | if (rc < 0) | 388 | if (rc < 0) |
| 395 | goto unlock; | 389 | goto out; |
| 396 | 390 | ||
| 397 | /* Try and reconfigure the device */ | 391 | /* Try and reconfigure the device */ |
| 398 | rc = tenxpress_init(efx); | 392 | rc = tenxpress_init(efx); |
| 399 | if (rc < 0) | 393 | if (rc < 0) |
| 400 | goto unlock; | 394 | goto out; |
| 401 | 395 | ||
| 402 | /* Wait for the XGXS state machine to churn */ | 396 | /* Wait for the XGXS state machine to churn */ |
| 403 | mdelay(10); | 397 | mdelay(10); |
| 404 | unlock: | 398 | out: |
| 405 | spin_unlock(&efx->stats_lock); | 399 | efx_stats_enable(efx); |
| 406 | return rc; | 400 | return rc; |
| 407 | } | 401 | } |
| 408 | 402 | ||
| @@ -520,7 +514,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) | |||
| 520 | { | 514 | { |
| 521 | struct tenxpress_phy_data *phy_data = efx->phy_data; | 515 | struct tenxpress_phy_data *phy_data = efx->phy_data; |
| 522 | struct ethtool_cmd ecmd; | 516 | struct ethtool_cmd ecmd; |
| 523 | bool phy_mode_change, loop_reset, loop_toggle, loopback; | 517 | bool phy_mode_change, loop_reset; |
| 524 | 518 | ||
| 525 | if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { | 519 | if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { |
| 526 | phy_data->phy_mode = efx->phy_mode; | 520 | phy_data->phy_mode = efx->phy_mode; |
| @@ -531,12 +525,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) | |||
| 531 | 525 | ||
| 532 | phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && | 526 | phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && |
| 533 | phy_data->phy_mode != PHY_MODE_NORMAL); | 527 | phy_data->phy_mode != PHY_MODE_NORMAL); |
| 534 | loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks; | ||
| 535 | loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks); | ||
| 536 | loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || | 528 | loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || |
| 537 | LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); | 529 | LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); |
| 538 | 530 | ||
| 539 | if (loop_reset || loop_toggle || loopback || phy_mode_change) { | 531 | if (loop_reset || phy_mode_change) { |
| 540 | int rc; | 532 | int rc; |
| 541 | 533 | ||
| 542 | efx->phy_op->get_settings(efx, &ecmd); | 534 | efx->phy_op->get_settings(efx, &ecmd); |
| @@ -551,20 +543,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) | |||
| 551 | falcon_reset_xaui(efx); | 543 | falcon_reset_xaui(efx); |
| 552 | } | 544 | } |
| 553 | 545 | ||
| 554 | if (efx->phy_type != PHY_TYPE_SFX7101) { | ||
| 555 | /* Only change autoneg once, on coming out or | ||
| 556 | * going into loopback */ | ||
| 557 | if (loop_toggle) | ||
| 558 | ecmd.autoneg = !loopback; | ||
| 559 | if (loopback) { | ||
| 560 | ecmd.duplex = DUPLEX_FULL; | ||
| 561 | if (efx->loopback_mode == LOOPBACK_GPHY) | ||
| 562 | ecmd.speed = SPEED_1000; | ||
| 563 | else | ||
| 564 | ecmd.speed = SPEED_10000; | ||
| 565 | } | ||
| 566 | } | ||
| 567 | |||
| 568 | rc = efx->phy_op->set_settings(efx, &ecmd); | 546 | rc = efx->phy_op->set_settings(efx, &ecmd); |
| 569 | WARN_ON(rc); | 547 | WARN_ON(rc); |
| 570 | } | 548 | } |
| @@ -623,13 +601,6 @@ static void tenxpress_phy_poll(struct efx_nic *efx) | |||
| 623 | 601 | ||
| 624 | if (phy_data->phy_mode != PHY_MODE_NORMAL) | 602 | if (phy_data->phy_mode != PHY_MODE_NORMAL) |
| 625 | return; | 603 | return; |
| 626 | |||
| 627 | if (EFX_WORKAROUND_10750(efx) && | ||
| 628 | atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { | ||
| 629 | EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); | ||
| 630 | falcon_reset_xaui(efx); | ||
| 631 | atomic_set(&phy_data->bad_crc_count, 0); | ||
| 632 | } | ||
| 633 | } | 604 | } |
| 634 | 605 | ||
| 635 | static void tenxpress_phy_fini(struct efx_nic *efx) | 606 | static void tenxpress_phy_fini(struct efx_nic *efx) |
| @@ -772,107 +743,76 @@ reset: | |||
| 772 | return rc; | 743 | return rc; |
| 773 | } | 744 | } |
| 774 | 745 | ||
| 775 | static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) | 746 | static void |
| 747 | tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | ||
| 776 | { | 748 | { |
| 777 | int phy = efx->mii.phy_id; | 749 | int phy_id = efx->mii.phy_id; |
| 778 | u32 lpa = 0; | 750 | u32 adv = 0, lpa = 0; |
| 779 | int reg; | 751 | int reg; |
| 780 | 752 | ||
| 781 | if (efx->phy_type != PHY_TYPE_SFX7101) { | 753 | if (efx->phy_type != PHY_TYPE_SFX7101) { |
| 782 | reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT, | 754 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, |
| 783 | C22EXT_MSTSLV_REG); | 755 | C22EXT_MSTSLV_CTRL); |
| 784 | if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN)) | 756 | if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN)) |
| 757 | adv |= ADVERTISED_1000baseT_Full; | ||
| 758 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, | ||
| 759 | C22EXT_MSTSLV_STATUS); | ||
| 760 | if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN)) | ||
| 785 | lpa |= ADVERTISED_1000baseT_Half; | 761 | lpa |= ADVERTISED_1000baseT_Half; |
| 786 | if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN)) | 762 | if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN)) |
| 787 | lpa |= ADVERTISED_1000baseT_Full; | 763 | lpa |= ADVERTISED_1000baseT_Full; |
| 788 | } | 764 | } |
| 789 | reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS); | 765 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, |
| 766 | MDIO_AN_10GBT_CTRL); | ||
| 767 | if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN)) | ||
| 768 | adv |= ADVERTISED_10000baseT_Full; | ||
| 769 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
| 770 | MDIO_AN_10GBT_STATUS); | ||
| 790 | if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) | 771 | if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) |
| 791 | lpa |= ADVERTISED_10000baseT_Full; | 772 | lpa |= ADVERTISED_10000baseT_Full; |
| 792 | return lpa; | ||
| 793 | } | ||
| 794 | 773 | ||
| 795 | static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 774 | mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa); |
| 796 | { | 775 | |
| 797 | mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full, | 776 | if (efx->phy_type != PHY_TYPE_SFX7101) |
| 798 | tenxpress_get_xnp_lpa(efx)); | 777 | ecmd->supported |= (SUPPORTED_100baseT_Full | |
| 799 | ecmd->supported |= SUPPORTED_10000baseT_Full; | 778 | SUPPORTED_1000baseT_Full); |
| 800 | ecmd->advertising |= ADVERTISED_10000baseT_Full; | 779 | |
| 780 | /* In loopback, the PHY automatically brings up the correct interface, | ||
| 781 | * but doesn't advertise the correct speed. So override it */ | ||
| 782 | if (efx->loopback_mode == LOOPBACK_GPHY) | ||
| 783 | ecmd->speed = SPEED_1000; | ||
| 784 | else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) | ||
| 785 | ecmd->speed = SPEED_10000; | ||
| 801 | } | 786 | } |
| 802 | 787 | ||
| 803 | static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 788 | static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) |
| 804 | { | 789 | { |
| 805 | int phy_id = efx->mii.phy_id; | 790 | if (!ecmd->autoneg) |
| 806 | u32 xnp_adv = 0; | 791 | return -EINVAL; |
| 807 | int reg; | ||
| 808 | |||
| 809 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
| 810 | PMA_PMD_SPEED_ENABLE_REG); | ||
| 811 | if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN))) | ||
| 812 | xnp_adv |= ADVERTISED_100baseT_Full; | ||
| 813 | if (reg & (1 << PMA_PMD_1000T_ADV_LBN)) | ||
| 814 | xnp_adv |= ADVERTISED_1000baseT_Full; | ||
| 815 | if (reg & (1 << PMA_PMD_10000T_ADV_LBN)) | ||
| 816 | xnp_adv |= ADVERTISED_10000baseT_Full; | ||
| 817 | |||
| 818 | mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv, | ||
| 819 | tenxpress_get_xnp_lpa(efx)); | ||
| 820 | |||
| 821 | ecmd->supported |= (SUPPORTED_100baseT_Half | | ||
| 822 | SUPPORTED_100baseT_Full | | ||
| 823 | SUPPORTED_1000baseT_Full); | ||
| 824 | 792 | ||
| 825 | /* Use the vendor defined C22ext register for duplex settings */ | 793 | return mdio_clause45_set_settings(efx, ecmd); |
| 826 | if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) { | ||
| 827 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, | ||
| 828 | GPHY_XCONTROL_REG); | ||
| 829 | ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ? | ||
| 830 | DUPLEX_FULL : DUPLEX_HALF); | ||
| 831 | } | ||
| 832 | } | 794 | } |
| 833 | 795 | ||
| 834 | static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 796 | static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) |
| 835 | { | 797 | { |
| 836 | int phy_id = efx->mii.phy_id; | 798 | mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN, |
| 837 | int rc; | 799 | MDIO_AN_10GBT_CTRL, |
| 838 | 800 | MDIO_AN_10GBT_CTRL_ADV_10G_LBN, | |
| 839 | rc = mdio_clause45_set_settings(efx, ecmd); | 801 | advertising & ADVERTISED_10000baseT_Full); |
| 840 | if (rc) | ||
| 841 | return rc; | ||
| 842 | |||
| 843 | if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) | ||
| 844 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, | ||
| 845 | GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN, | ||
| 846 | ecmd->duplex == DUPLEX_FULL); | ||
| 847 | |||
| 848 | return rc; | ||
| 849 | } | 802 | } |
| 850 | 803 | ||
| 851 | static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) | 804 | static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) |
| 852 | { | 805 | { |
| 853 | int phy = efx->mii.phy_id; | 806 | int phy_id = efx->mii.phy_id; |
| 854 | int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD, | 807 | |
| 855 | PMA_PMD_SPEED_ENABLE_REG); | 808 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, |
| 856 | bool enabled; | 809 | C22EXT_MSTSLV_CTRL, |
| 857 | 810 | C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, | |
| 858 | reg &= ~((1 << 2) | (1 << 3)); | 811 | advertising & ADVERTISED_1000baseT_Full); |
| 859 | if (EFX_WORKAROUND_13204(efx) && | 812 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, |
| 860 | (advertising & ADVERTISED_100baseT_Full)) | 813 | MDIO_AN_10GBT_CTRL, |
| 861 | reg |= 1 << PMA_PMD_100TX_ADV_LBN; | 814 | MDIO_AN_10GBT_CTRL_ADV_10G_LBN, |
| 862 | if (advertising & ADVERTISED_1000baseT_Full) | 815 | advertising & ADVERTISED_10000baseT_Full); |
| 863 | reg |= 1 << PMA_PMD_1000T_ADV_LBN; | ||
| 864 | if (advertising & ADVERTISED_10000baseT_Full) | ||
| 865 | reg |= 1 << PMA_PMD_10000T_ADV_LBN; | ||
| 866 | mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD, | ||
| 867 | PMA_PMD_SPEED_ENABLE_REG, reg); | ||
| 868 | |||
| 869 | enabled = (advertising & | ||
| 870 | (ADVERTISED_1000baseT_Half | | ||
| 871 | ADVERTISED_1000baseT_Full | | ||
| 872 | ADVERTISED_10000baseT_Full)); | ||
| 873 | if (EFX_WORKAROUND_13204(efx)) | ||
| 874 | enabled |= (advertising & ADVERTISED_100baseT_Full); | ||
| 875 | return enabled; | ||
| 876 | } | 816 | } |
| 877 | 817 | ||
| 878 | struct efx_phy_operations falcon_sfx7101_phy_ops = { | 818 | struct efx_phy_operations falcon_sfx7101_phy_ops = { |
| @@ -882,8 +822,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { | |||
| 882 | .poll = tenxpress_phy_poll, | 822 | .poll = tenxpress_phy_poll, |
| 883 | .fini = tenxpress_phy_fini, | 823 | .fini = tenxpress_phy_fini, |
| 884 | .clear_interrupt = efx_port_dummy_op_void, | 824 | .clear_interrupt = efx_port_dummy_op_void, |
| 885 | .get_settings = sfx7101_get_settings, | 825 | .get_settings = tenxpress_get_settings, |
| 886 | .set_settings = mdio_clause45_set_settings, | 826 | .set_settings = tenxpress_set_settings, |
| 827 | .set_npage_adv = sfx7101_set_npage_adv, | ||
| 887 | .num_tests = ARRAY_SIZE(sfx7101_test_names), | 828 | .num_tests = ARRAY_SIZE(sfx7101_test_names), |
| 888 | .test_names = sfx7101_test_names, | 829 | .test_names = sfx7101_test_names, |
| 889 | .run_tests = sfx7101_run_tests, | 830 | .run_tests = sfx7101_run_tests, |
| @@ -898,9 +839,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = { | |||
| 898 | .poll = tenxpress_phy_poll, | 839 | .poll = tenxpress_phy_poll, |
| 899 | .fini = tenxpress_phy_fini, | 840 | .fini = tenxpress_phy_fini, |
| 900 | .clear_interrupt = efx_port_dummy_op_void, | 841 | .clear_interrupt = efx_port_dummy_op_void, |
| 901 | .get_settings = sft9001_get_settings, | 842 | .get_settings = tenxpress_get_settings, |
| 902 | .set_settings = sft9001_set_settings, | 843 | .set_settings = tenxpress_set_settings, |
| 903 | .set_xnp_advertise = sft9001_set_xnp_advertise, | 844 | .set_npage_adv = sft9001_set_npage_adv, |
| 904 | .num_tests = ARRAY_SIZE(sft9001_test_names), | 845 | .num_tests = ARRAY_SIZE(sft9001_test_names), |
| 905 | .test_names = sft9001_test_names, | 846 | .test_names = sft9001_test_names, |
| 906 | .run_tests = sft9001_run_tests, | 847 | .run_tests = sft9001_run_tests, |
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index 82e03e1d7371..78de68f4a95b 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h | |||
| @@ -18,8 +18,8 @@ | |||
| 18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 | 18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 |
| 19 | #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) | 19 | #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) |
| 20 | #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) | 20 | #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) |
| 21 | #define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101) | 21 | #define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ |
| 22 | #define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) | 22 | (efx)->phy_type == PHY_TYPE_SFT9001B) |
| 23 | 23 | ||
| 24 | /* XAUI resets if link not detected */ | 24 | /* XAUI resets if link not detected */ |
| 25 | #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS | 25 | #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS |
| @@ -29,8 +29,6 @@ | |||
| 29 | #define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G | 29 | #define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G |
| 30 | /* TX pkt parser problem with <= 16 byte TXes */ | 30 | /* TX pkt parser problem with <= 16 byte TXes */ |
| 31 | #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS | 31 | #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS |
| 32 | /* Low rate CRC errors require XAUI reset */ | ||
| 33 | #define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101 | ||
| 34 | /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor | 32 | /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor |
| 35 | * or a PCIe error (bug 11028) */ | 33 | * or a PCIe error (bug 11028) */ |
| 36 | #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS | 34 | #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS |
| @@ -55,8 +53,8 @@ | |||
| 55 | #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A | 53 | #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A |
| 56 | 54 | ||
| 57 | /* Need to send XNP pages for 100BaseT */ | 55 | /* Need to send XNP pages for 100BaseT */ |
| 58 | #define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A | 56 | #define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 |
| 59 | /* Need to keep AN enabled */ | 57 | /* Don't restart AN in near-side loopback */ |
| 60 | #define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A | 58 | #define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 |
| 61 | 59 | ||
| 62 | #endif /* EFX_WORKAROUNDS_H */ | 60 | #endif /* EFX_WORKAROUNDS_H */ |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3668e81e474d..994703cc0db3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -1403,9 +1403,6 @@ static int sky2_up(struct net_device *dev) | |||
| 1403 | 1403 | ||
| 1404 | } | 1404 | } |
| 1405 | 1405 | ||
| 1406 | if (netif_msg_ifup(sky2)) | ||
| 1407 | printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); | ||
| 1408 | |||
| 1409 | netif_carrier_off(dev); | 1406 | netif_carrier_off(dev); |
| 1410 | 1407 | ||
| 1411 | /* must be power of 2 */ | 1408 | /* must be power of 2 */ |
| @@ -1484,6 +1481,9 @@ static int sky2_up(struct net_device *dev) | |||
| 1484 | sky2_write32(hw, B0_IMSK, imask); | 1481 | sky2_write32(hw, B0_IMSK, imask); |
| 1485 | 1482 | ||
| 1486 | sky2_set_multicast(dev); | 1483 | sky2_set_multicast(dev); |
| 1484 | |||
| 1485 | if (netif_msg_ifup(sky2)) | ||
| 1486 | printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); | ||
| 1487 | return 0; | 1487 | return 0; |
| 1488 | 1488 | ||
| 1489 | err_out: | 1489 | err_out: |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index d19a84b79503..228be551e9c1 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
| @@ -48,6 +48,7 @@ | |||
| 48 | #include <linux/pim.h> | 48 | #include <linux/pim.h> |
| 49 | #include <net/addrconf.h> | 49 | #include <net/addrconf.h> |
| 50 | #include <linux/netfilter_ipv6.h> | 50 | #include <linux/netfilter_ipv6.h> |
| 51 | #include <net/ip6_checksum.h> | ||
| 51 | 52 | ||
| 52 | /* Big lock, protecting vif table, mrt cache and mroute socket state. | 53 | /* Big lock, protecting vif table, mrt cache and mroute socket state. |
| 53 | Note that the changes are semaphored via rtnl_lock. | 54 | Note that the changes are semaphored via rtnl_lock. |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 5f94db2f3e9e..9454d4ae46df 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -77,6 +77,7 @@ | |||
| 77 | #include <linux/poll.h> | 77 | #include <linux/poll.h> |
| 78 | #include <linux/module.h> | 78 | #include <linux/module.h> |
| 79 | #include <linux/init.h> | 79 | #include <linux/init.h> |
| 80 | #include <linux/mutex.h> | ||
| 80 | 81 | ||
| 81 | #ifdef CONFIG_INET | 82 | #ifdef CONFIG_INET |
| 82 | #include <net/inet_common.h> | 83 | #include <net/inet_common.h> |
| @@ -175,6 +176,7 @@ struct packet_sock { | |||
| 175 | #endif | 176 | #endif |
| 176 | struct packet_type prot_hook; | 177 | struct packet_type prot_hook; |
| 177 | spinlock_t bind_lock; | 178 | spinlock_t bind_lock; |
| 179 | struct mutex pg_vec_lock; | ||
| 178 | unsigned int running:1, /* prot_hook is attached*/ | 180 | unsigned int running:1, /* prot_hook is attached*/ |
| 179 | auxdata:1, | 181 | auxdata:1, |
| 180 | origdev:1; | 182 | origdev:1; |
| @@ -1069,6 +1071,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol) | |||
| 1069 | */ | 1071 | */ |
| 1070 | 1072 | ||
| 1071 | spin_lock_init(&po->bind_lock); | 1073 | spin_lock_init(&po->bind_lock); |
| 1074 | mutex_init(&po->pg_vec_lock); | ||
| 1072 | po->prot_hook.func = packet_rcv; | 1075 | po->prot_hook.func = packet_rcv; |
| 1073 | 1076 | ||
| 1074 | if (sock->type == SOCK_PACKET) | 1077 | if (sock->type == SOCK_PACKET) |
| @@ -1865,6 +1868,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing | |||
| 1865 | synchronize_net(); | 1868 | synchronize_net(); |
| 1866 | 1869 | ||
| 1867 | err = -EBUSY; | 1870 | err = -EBUSY; |
| 1871 | mutex_lock(&po->pg_vec_lock); | ||
| 1868 | if (closing || atomic_read(&po->mapped) == 0) { | 1872 | if (closing || atomic_read(&po->mapped) == 0) { |
| 1869 | err = 0; | 1873 | err = 0; |
| 1870 | #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; }) | 1874 | #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; }) |
| @@ -1886,6 +1890,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing | |||
| 1886 | if (atomic_read(&po->mapped)) | 1890 | if (atomic_read(&po->mapped)) |
| 1887 | printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped)); | 1891 | printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped)); |
| 1888 | } | 1892 | } |
| 1893 | mutex_unlock(&po->pg_vec_lock); | ||
| 1889 | 1894 | ||
| 1890 | spin_lock(&po->bind_lock); | 1895 | spin_lock(&po->bind_lock); |
| 1891 | if (was_running && !po->running) { | 1896 | if (was_running && !po->running) { |
| @@ -1918,7 +1923,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st | |||
| 1918 | 1923 | ||
| 1919 | size = vma->vm_end - vma->vm_start; | 1924 | size = vma->vm_end - vma->vm_start; |
| 1920 | 1925 | ||
| 1921 | lock_sock(sk); | 1926 | mutex_lock(&po->pg_vec_lock); |
| 1922 | if (po->pg_vec == NULL) | 1927 | if (po->pg_vec == NULL) |
| 1923 | goto out; | 1928 | goto out; |
| 1924 | if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE) | 1929 | if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE) |
| @@ -1941,7 +1946,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st | |||
| 1941 | err = 0; | 1946 | err = 0; |
| 1942 | 1947 | ||
| 1943 | out: | 1948 | out: |
| 1944 | release_sock(sk); | 1949 | mutex_unlock(&po->pg_vec_lock); |
| 1945 | return err; | 1950 | return err; |
| 1946 | } | 1951 | } |
| 1947 | #endif | 1952 | #endif |
