diff options
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 6 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 93 |
3 files changed, 72 insertions, 29 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 9bafa6cf9e8b..a140a8fbf051 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h | |||
| @@ -72,7 +72,6 @@ struct stmmac_priv { | |||
| 72 | spinlock_t lock; | 72 | spinlock_t lock; |
| 73 | spinlock_t tx_lock; | 73 | spinlock_t tx_lock; |
| 74 | int wolopts; | 74 | int wolopts; |
| 75 | int wolenabled; | ||
| 76 | int wol_irq; | 75 | int wol_irq; |
| 77 | #ifdef CONFIG_STMMAC_TIMER | 76 | #ifdef CONFIG_STMMAC_TIMER |
| 78 | struct stmmac_timer *tm; | 77 | struct stmmac_timer *tm; |
| @@ -80,6 +79,7 @@ struct stmmac_priv { | |||
| 80 | struct plat_stmmacenet_data *plat; | 79 | struct plat_stmmacenet_data *plat; |
| 81 | struct stmmac_counters mmc; | 80 | struct stmmac_counters mmc; |
| 82 | struct dma_features dma_cap; | 81 | struct dma_features dma_cap; |
| 82 | int hw_cap_support; | ||
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | extern int stmmac_mdio_unregister(struct net_device *ndev); | 85 | extern int stmmac_mdio_unregister(struct net_device *ndev); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index e8eff09bbbd7..0395f9eba801 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | |||
| @@ -430,6 +430,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
| 430 | struct stmmac_priv *priv = netdev_priv(dev); | 430 | struct stmmac_priv *priv = netdev_priv(dev); |
| 431 | u32 support = WAKE_MAGIC | WAKE_UCAST; | 431 | u32 support = WAKE_MAGIC | WAKE_UCAST; |
| 432 | 432 | ||
| 433 | /* By default almost all GMAC devices support the WoL via | ||
| 434 | * magic frame but we can disable it if the HW capability | ||
| 435 | * register shows no support for pmt_magic_frame. */ | ||
| 436 | if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame)) | ||
| 437 | wol->wolopts &= ~WAKE_MAGIC; | ||
| 438 | |||
| 433 | if (!device_can_wakeup(priv->device)) | 439 | if (!device_can_wakeup(priv->device)) |
| 434 | return -EINVAL; | 440 | return -EINVAL; |
| 435 | 441 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index e079762a796e..7f3ffd3742d8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -805,8 +805,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) | |||
| 805 | return 0; | 805 | return 0; |
| 806 | } | 806 | } |
| 807 | 807 | ||
| 808 | /* New GMAC chips support a new register to indicate the | 808 | /** |
| 809 | * presence of the optional feature/functions. | 809 | * stmmac_selec_desc_mode |
| 810 | * @dev : device pointer | ||
| 811 | * Description: select the Enhanced/Alternate or Normal descriptors */ | ||
| 812 | static void stmmac_selec_desc_mode(struct stmmac_priv *priv) | ||
| 813 | { | ||
| 814 | if (priv->plat->enh_desc) { | ||
| 815 | pr_info(" Enhanced/Alternate descriptors\n"); | ||
| 816 | priv->hw->desc = &enh_desc_ops; | ||
| 817 | } else { | ||
| 818 | pr_info(" Normal descriptors\n"); | ||
| 819 | priv->hw->desc = &ndesc_ops; | ||
| 820 | } | ||
| 821 | } | ||
| 822 | |||
| 823 | /** | ||
| 824 | * stmmac_get_hw_features | ||
| 825 | * @priv : private device pointer | ||
| 826 | * Description: | ||
| 827 | * new GMAC chip generations have a new register to indicate the | ||
| 828 | * presence of the optional feature/functions. | ||
| 829 | * This can be also used to override the value passed through the | ||
| 830 | * platform and necessary for old MAC10/100 and GMAC chips. | ||
| 810 | */ | 831 | */ |
| 811 | static int stmmac_get_hw_features(struct stmmac_priv *priv) | 832 | static int stmmac_get_hw_features(struct stmmac_priv *priv) |
| 812 | { | 833 | { |
| @@ -827,7 +848,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv) | |||
| 827 | (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; | 848 | (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; |
| 828 | priv->dma_cap.pmt_magic_frame = | 849 | priv->dma_cap.pmt_magic_frame = |
| 829 | (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; | 850 | (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; |
| 830 | /*MMC*/ | 851 | /* MMC */ |
| 831 | priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; | 852 | priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; |
| 832 | /* IEEE 1588-2002*/ | 853 | /* IEEE 1588-2002*/ |
| 833 | priv->dma_cap.time_stamp = | 854 | priv->dma_cap.time_stamp = |
| @@ -855,8 +876,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv) | |||
| 855 | priv->dma_cap.enh_desc = | 876 | priv->dma_cap.enh_desc = |
| 856 | (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; | 877 | (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; |
| 857 | 878 | ||
| 858 | } else | 879 | } |
| 859 | pr_debug("\tNo HW DMA feature register supported"); | ||
| 860 | 880 | ||
| 861 | return hw_cap; | 881 | return hw_cap; |
| 862 | } | 882 | } |
| @@ -911,6 +931,44 @@ static int stmmac_open(struct net_device *dev) | |||
| 911 | goto open_error; | 931 | goto open_error; |
| 912 | } | 932 | } |
| 913 | 933 | ||
| 934 | stmmac_get_synopsys_id(priv); | ||
| 935 | |||
| 936 | priv->hw_cap_support = stmmac_get_hw_features(priv); | ||
| 937 | |||
| 938 | if (priv->hw_cap_support) { | ||
| 939 | pr_info(" Support DMA HW capability register"); | ||
| 940 | |||
| 941 | /* We can override some gmac/dma configuration fields: e.g. | ||
| 942 | * enh_desc, tx_coe (e.g. that are passed through the | ||
| 943 | * platform) with the values from the HW capability | ||
| 944 | * register (if supported). | ||
| 945 | */ | ||
| 946 | priv->plat->enh_desc = priv->dma_cap.enh_desc; | ||
| 947 | priv->plat->tx_coe = priv->dma_cap.tx_coe; | ||
| 948 | priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; | ||
| 949 | |||
| 950 | /* By default disable wol on magic frame if not supported */ | ||
| 951 | if (!priv->dma_cap.pmt_magic_frame) | ||
| 952 | priv->wolopts &= ~WAKE_MAGIC; | ||
| 953 | |||
| 954 | } else | ||
| 955 | pr_info(" No HW DMA feature register supported"); | ||
| 956 | |||
| 957 | /* Select the enhnaced/normal descriptor structures */ | ||
| 958 | stmmac_selec_desc_mode(priv); | ||
| 959 | |||
| 960 | /* PMT module is not integrated in all the MAC devices. */ | ||
| 961 | if (priv->plat->pmt) { | ||
| 962 | pr_info(" Remote wake-up capable\n"); | ||
| 963 | device_set_wakeup_capable(priv->device, 1); | ||
| 964 | } | ||
| 965 | |||
| 966 | priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); | ||
| 967 | if (priv->rx_coe) | ||
| 968 | pr_info(" Checksum Offload Engine supported\n"); | ||
| 969 | if (priv->plat->tx_coe) | ||
| 970 | pr_info(" Checksum insertion supported\n"); | ||
| 971 | |||
| 914 | /* Create and initialize the TX/RX descriptors chains. */ | 972 | /* Create and initialize the TX/RX descriptors chains. */ |
| 915 | priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); | 973 | priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); |
| 916 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); | 974 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); |
| @@ -933,15 +991,6 @@ static int stmmac_open(struct net_device *dev) | |||
| 933 | /* Initialize the MAC Core */ | 991 | /* Initialize the MAC Core */ |
| 934 | priv->hw->mac->core_init(priv->ioaddr); | 992 | priv->hw->mac->core_init(priv->ioaddr); |
| 935 | 993 | ||
| 936 | stmmac_get_synopsys_id(priv); | ||
| 937 | |||
| 938 | stmmac_get_hw_features(priv); | ||
| 939 | |||
| 940 | priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); | ||
| 941 | if (priv->rx_coe) | ||
| 942 | pr_info("stmmac: Rx Checksum Offload Engine supported\n"); | ||
| 943 | if (priv->plat->tx_coe) | ||
| 944 | pr_info("\tTX Checksum insertion supported\n"); | ||
| 945 | netdev_update_features(dev); | 994 | netdev_update_features(dev); |
| 946 | 995 | ||
| 947 | /* Request the IRQ lines */ | 996 | /* Request the IRQ lines */ |
| @@ -1556,7 +1605,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) | |||
| 1556 | struct net_device *dev = seq->private; | 1605 | struct net_device *dev = seq->private; |
| 1557 | struct stmmac_priv *priv = netdev_priv(dev); | 1606 | struct stmmac_priv *priv = netdev_priv(dev); |
| 1558 | 1607 | ||
| 1559 | if (!stmmac_get_hw_features(priv)) { | 1608 | if (!priv->hw_cap_support) { |
| 1560 | seq_printf(seq, "DMA HW features not supported\n"); | 1609 | seq_printf(seq, "DMA HW features not supported\n"); |
| 1561 | return 0; | 1610 | return 0; |
| 1562 | } | 1611 | } |
| @@ -1764,12 +1813,6 @@ static int stmmac_mac_device_setup(struct net_device *dev) | |||
| 1764 | if (!device) | 1813 | if (!device) |
| 1765 | return -ENOMEM; | 1814 | return -ENOMEM; |
| 1766 | 1815 | ||
| 1767 | if (priv->plat->enh_desc) { | ||
| 1768 | device->desc = &enh_desc_ops; | ||
| 1769 | pr_info("\tEnhanced descriptor structure\n"); | ||
| 1770 | } else | ||
| 1771 | device->desc = &ndesc_ops; | ||
| 1772 | |||
| 1773 | priv->hw = device; | 1816 | priv->hw = device; |
| 1774 | priv->hw->ring = &ring_mode_ops; | 1817 | priv->hw->ring = &ring_mode_ops; |
| 1775 | 1818 | ||
| @@ -1843,11 +1886,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
| 1843 | 1886 | ||
| 1844 | priv->ioaddr = addr; | 1887 | priv->ioaddr = addr; |
| 1845 | 1888 | ||
| 1846 | /* PMT module is not integrated in all the MAC devices. */ | ||
| 1847 | if (plat_dat->pmt) { | ||
| 1848 | pr_info("\tPMT module supported\n"); | ||
| 1849 | device_set_wakeup_capable(&pdev->dev, 1); | ||
| 1850 | } | ||
| 1851 | /* | 1889 | /* |
| 1852 | * On some platforms e.g. SPEAr the wake up irq differs from the mac irq | 1890 | * On some platforms e.g. SPEAr the wake up irq differs from the mac irq |
| 1853 | * The external wake up irq can be passed through the platform code | 1891 | * The external wake up irq can be passed through the platform code |
| @@ -1860,7 +1898,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
| 1860 | if (priv->wol_irq == -ENXIO) | 1898 | if (priv->wol_irq == -ENXIO) |
| 1861 | priv->wol_irq = ndev->irq; | 1899 | priv->wol_irq = ndev->irq; |
| 1862 | 1900 | ||
| 1863 | |||
| 1864 | platform_set_drvdata(pdev, ndev); | 1901 | platform_set_drvdata(pdev, ndev); |
| 1865 | 1902 | ||
| 1866 | /* Set the I/O base addr */ | 1903 | /* Set the I/O base addr */ |
| @@ -1873,7 +1910,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
| 1873 | goto out_free_ndev; | 1910 | goto out_free_ndev; |
| 1874 | } | 1911 | } |
| 1875 | 1912 | ||
| 1876 | /* MAC HW revice detection */ | 1913 | /* MAC HW device detection */ |
| 1877 | ret = stmmac_mac_device_setup(ndev); | 1914 | ret = stmmac_mac_device_setup(ndev); |
| 1878 | if (ret < 0) | 1915 | if (ret < 0) |
| 1879 | goto out_plat_exit; | 1916 | goto out_plat_exit; |
