diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/Kconfig | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c | 3 | ||||
-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 | 131 |
6 files changed, 96 insertions, 58 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index ac6f190743d..22745d7bf53 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig | |||
@@ -29,15 +29,6 @@ config STMMAC_DA | |||
29 | By default, the DMA arbitration scheme is based on Round-robin | 29 | By default, the DMA arbitration scheme is based on Round-robin |
30 | (rx:tx priority is 1:1). | 30 | (rx:tx priority is 1:1). |
31 | 31 | ||
32 | config STMMAC_DUAL_MAC | ||
33 | bool "STMMAC: dual mac support (EXPERIMENTAL)" | ||
34 | default n | ||
35 | depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER | ||
36 | ---help--- | ||
37 | Some ST SoCs (for example the stx7141 and stx7200c2) have two | ||
38 | Ethernet Controllers. This option turns on the second Ethernet | ||
39 | device on this kind of platforms. | ||
40 | |||
41 | config STMMAC_TIMER | 32 | config STMMAC_TIMER |
42 | bool "STMMAC Timer optimisation" | 33 | bool "STMMAC Timer optimisation" |
43 | default n | 34 | default n |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index da66ac511c4..4d5402a1d26 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | |||
@@ -39,10 +39,11 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, | |||
39 | /* DMA SW reset */ | 39 | /* DMA SW reset */ |
40 | value |= DMA_BUS_MODE_SFT_RESET; | 40 | value |= DMA_BUS_MODE_SFT_RESET; |
41 | writel(value, ioaddr + DMA_BUS_MODE); | 41 | writel(value, ioaddr + DMA_BUS_MODE); |
42 | limit = 15000; | 42 | limit = 10; |
43 | while (limit--) { | 43 | while (limit--) { |
44 | if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) | 44 | if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) |
45 | break; | 45 | break; |
46 | mdelay(10); | ||
46 | } | 47 | } |
47 | if (limit < 0) | 48 | if (limit < 0) |
48 | return -EBUSY; | 49 | return -EBUSY; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index 627f656b0f3..bc17fd08b55 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c | |||
@@ -41,10 +41,11 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, | |||
41 | /* DMA SW reset */ | 41 | /* DMA SW reset */ |
42 | value |= DMA_BUS_MODE_SFT_RESET; | 42 | value |= DMA_BUS_MODE_SFT_RESET; |
43 | writel(value, ioaddr + DMA_BUS_MODE); | 43 | writel(value, ioaddr + DMA_BUS_MODE); |
44 | limit = 15000; | 44 | limit = 10; |
45 | while (limit--) { | 45 | while (limit--) { |
46 | if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) | 46 | if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) |
47 | break; | 47 | break; |
48 | mdelay(10); | ||
48 | } | 49 | } |
49 | if (limit < 0) | 50 | if (limit < 0) |
50 | return -EBUSY; | 51 | return -EBUSY; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 9bafa6cf9e8..a140a8fbf05 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 e8eff09bbbd..0395f9eba80 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 20546bbbb8d..72cd190b9c1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -321,12 +321,10 @@ static int stmmac_init_phy(struct net_device *dev) | |||
321 | } | 321 | } |
322 | 322 | ||
323 | /* Stop Advertising 1000BASE Capability if interface is not GMII */ | 323 | /* Stop Advertising 1000BASE Capability if interface is not GMII */ |
324 | if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) || | 324 | if ((interface == PHY_INTERFACE_MODE_MII) || |
325 | (interface == PHY_INTERFACE_MODE_RMII))) { | 325 | (interface == PHY_INTERFACE_MODE_RMII)) |
326 | phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | | 326 | phydev->advertising &= ~(SUPPORTED_1000baseT_Half | |
327 | SUPPORTED_Asym_Pause); | 327 | SUPPORTED_1000baseT_Full); |
328 | phydev->advertising = phydev->supported; | ||
329 | } | ||
330 | 328 | ||
331 | /* | 329 | /* |
332 | * Broken HW is sometimes missing the pull-up resistor on the | 330 | * Broken HW is sometimes missing the pull-up resistor on the |
@@ -783,10 +781,15 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv) | |||
783 | unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | | 781 | unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | |
784 | MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; | 782 | MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; |
785 | 783 | ||
786 | /* Do not manage MMC IRQ (FIXME) */ | 784 | /* Mask MMC irq, counters are managed in SW and registers |
785 | * are cleared on each READ eventually. */ | ||
787 | dwmac_mmc_intr_all_mask(priv->ioaddr); | 786 | dwmac_mmc_intr_all_mask(priv->ioaddr); |
788 | dwmac_mmc_ctrl(priv->ioaddr, mode); | 787 | |
789 | memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); | 788 | if (priv->dma_cap.rmon) { |
789 | dwmac_mmc_ctrl(priv->ioaddr, mode); | ||
790 | memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); | ||
791 | } else | ||
792 | pr_info(" No MAC Management Counters available"); | ||
790 | } | 793 | } |
791 | 794 | ||
792 | static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) | 795 | static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) |
@@ -807,8 +810,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) | |||
807 | return 0; | 810 | return 0; |
808 | } | 811 | } |
809 | 812 | ||
810 | /* New GMAC chips support a new register to indicate the | 813 | /** |
811 | * presence of the optional feature/functions. | 814 | * stmmac_selec_desc_mode |
815 | * @dev : device pointer | ||
816 | * Description: select the Enhanced/Alternate or Normal descriptors */ | ||
817 | static void stmmac_selec_desc_mode(struct stmmac_priv *priv) | ||
818 | { | ||
819 | if (priv->plat->enh_desc) { | ||
820 | pr_info(" Enhanced/Alternate descriptors\n"); | ||
821 | priv->hw->desc = &enh_desc_ops; | ||
822 | } else { | ||
823 | pr_info(" Normal descriptors\n"); | ||
824 | priv->hw->desc = &ndesc_ops; | ||
825 | } | ||
826 | } | ||
827 | |||
828 | /** | ||
829 | * stmmac_get_hw_features | ||
830 | * @priv : private device pointer | ||
831 | * Description: | ||
832 | * new GMAC chip generations have a new register to indicate the | ||
833 | * presence of the optional feature/functions. | ||
834 | * This can be also used to override the value passed through the | ||
835 | * platform and necessary for old MAC10/100 and GMAC chips. | ||
812 | */ | 836 | */ |
813 | static int stmmac_get_hw_features(struct stmmac_priv *priv) | 837 | static int stmmac_get_hw_features(struct stmmac_priv *priv) |
814 | { | 838 | { |
@@ -829,7 +853,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv) | |||
829 | (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; | 853 | (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; |
830 | priv->dma_cap.pmt_magic_frame = | 854 | priv->dma_cap.pmt_magic_frame = |
831 | (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; | 855 | (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; |
832 | /*MMC*/ | 856 | /* MMC */ |
833 | priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; | 857 | priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; |
834 | /* IEEE 1588-2002*/ | 858 | /* IEEE 1588-2002*/ |
835 | priv->dma_cap.time_stamp = | 859 | priv->dma_cap.time_stamp = |
@@ -857,8 +881,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv) | |||
857 | priv->dma_cap.enh_desc = | 881 | priv->dma_cap.enh_desc = |
858 | (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; | 882 | (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; |
859 | 883 | ||
860 | } else | 884 | } |
861 | pr_debug("\tNo HW DMA feature register supported"); | ||
862 | 885 | ||
863 | return hw_cap; | 886 | return hw_cap; |
864 | } | 887 | } |
@@ -913,6 +936,44 @@ static int stmmac_open(struct net_device *dev) | |||
913 | goto open_error; | 936 | goto open_error; |
914 | } | 937 | } |
915 | 938 | ||
939 | stmmac_get_synopsys_id(priv); | ||
940 | |||
941 | priv->hw_cap_support = stmmac_get_hw_features(priv); | ||
942 | |||
943 | if (priv->hw_cap_support) { | ||
944 | pr_info(" Support DMA HW capability register"); | ||
945 | |||
946 | /* We can override some gmac/dma configuration fields: e.g. | ||
947 | * enh_desc, tx_coe (e.g. that are passed through the | ||
948 | * platform) with the values from the HW capability | ||
949 | * register (if supported). | ||
950 | */ | ||
951 | priv->plat->enh_desc = priv->dma_cap.enh_desc; | ||
952 | priv->plat->tx_coe = priv->dma_cap.tx_coe; | ||
953 | priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; | ||
954 | |||
955 | /* By default disable wol on magic frame if not supported */ | ||
956 | if (!priv->dma_cap.pmt_magic_frame) | ||
957 | priv->wolopts &= ~WAKE_MAGIC; | ||
958 | |||
959 | } else | ||
960 | pr_info(" No HW DMA feature register supported"); | ||
961 | |||
962 | /* Select the enhnaced/normal descriptor structures */ | ||
963 | stmmac_selec_desc_mode(priv); | ||
964 | |||
965 | /* PMT module is not integrated in all the MAC devices. */ | ||
966 | if (priv->plat->pmt) { | ||
967 | pr_info(" Remote wake-up capable\n"); | ||
968 | device_set_wakeup_capable(priv->device, 1); | ||
969 | } | ||
970 | |||
971 | priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); | ||
972 | if (priv->rx_coe) | ||
973 | pr_info(" Checksum Offload Engine supported\n"); | ||
974 | if (priv->plat->tx_coe) | ||
975 | pr_info(" Checksum insertion supported\n"); | ||
976 | |||
916 | /* Create and initialize the TX/RX descriptors chains. */ | 977 | /* Create and initialize the TX/RX descriptors chains. */ |
917 | priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); | 978 | priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); |
918 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); | 979 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); |
@@ -935,15 +996,6 @@ static int stmmac_open(struct net_device *dev) | |||
935 | /* Initialize the MAC Core */ | 996 | /* Initialize the MAC Core */ |
936 | priv->hw->mac->core_init(priv->ioaddr); | 997 | priv->hw->mac->core_init(priv->ioaddr); |
937 | 998 | ||
938 | stmmac_get_synopsys_id(priv); | ||
939 | |||
940 | stmmac_get_hw_features(priv); | ||
941 | |||
942 | priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); | ||
943 | if (priv->rx_coe) | ||
944 | pr_info("stmmac: Rx Checksum Offload Engine supported\n"); | ||
945 | if (priv->plat->tx_coe) | ||
946 | pr_info("\tTX Checksum insertion supported\n"); | ||
947 | netdev_update_features(dev); | 999 | netdev_update_features(dev); |
948 | 1000 | ||
949 | /* Request the IRQ lines */ | 1001 | /* Request the IRQ lines */ |
@@ -965,8 +1017,7 @@ static int stmmac_open(struct net_device *dev) | |||
965 | memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); | 1017 | memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); |
966 | priv->xstats.threshold = tc; | 1018 | priv->xstats.threshold = tc; |
967 | 1019 | ||
968 | if (priv->dma_cap.rmon) | 1020 | stmmac_mmc_setup(priv); |
969 | stmmac_mmc_setup(priv); | ||
970 | 1021 | ||
971 | /* Start the ball rolling... */ | 1022 | /* Start the ball rolling... */ |
972 | DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); | 1023 | DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); |
@@ -1489,9 +1540,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
1489 | if (!priv->phydev) | 1540 | if (!priv->phydev) |
1490 | return -EINVAL; | 1541 | return -EINVAL; |
1491 | 1542 | ||
1492 | spin_lock(&priv->lock); | ||
1493 | ret = phy_mii_ioctl(priv->phydev, rq, cmd); | 1543 | ret = phy_mii_ioctl(priv->phydev, rq, cmd); |
1494 | spin_unlock(&priv->lock); | ||
1495 | 1544 | ||
1496 | return ret; | 1545 | return ret; |
1497 | } | 1546 | } |
@@ -1558,7 +1607,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) | |||
1558 | struct net_device *dev = seq->private; | 1607 | struct net_device *dev = seq->private; |
1559 | struct stmmac_priv *priv = netdev_priv(dev); | 1608 | struct stmmac_priv *priv = netdev_priv(dev); |
1560 | 1609 | ||
1561 | if (!stmmac_get_hw_features(priv)) { | 1610 | if (!priv->hw_cap_support) { |
1562 | seq_printf(seq, "DMA HW features not supported\n"); | 1611 | seq_printf(seq, "DMA HW features not supported\n"); |
1563 | return 0; | 1612 | return 0; |
1564 | } | 1613 | } |
@@ -1766,12 +1815,6 @@ static int stmmac_mac_device_setup(struct net_device *dev) | |||
1766 | if (!device) | 1815 | if (!device) |
1767 | return -ENOMEM; | 1816 | return -ENOMEM; |
1768 | 1817 | ||
1769 | if (priv->plat->enh_desc) { | ||
1770 | device->desc = &enh_desc_ops; | ||
1771 | pr_info("\tEnhanced descriptor structure\n"); | ||
1772 | } else | ||
1773 | device->desc = &ndesc_ops; | ||
1774 | |||
1775 | priv->hw = device; | 1818 | priv->hw = device; |
1776 | priv->hw->ring = &ring_mode_ops; | 1819 | priv->hw->ring = &ring_mode_ops; |
1777 | 1820 | ||
@@ -1845,11 +1888,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
1845 | 1888 | ||
1846 | priv->ioaddr = addr; | 1889 | priv->ioaddr = addr; |
1847 | 1890 | ||
1848 | /* PMT module is not integrated in all the MAC devices. */ | ||
1849 | if (plat_dat->pmt) { | ||
1850 | pr_info("\tPMT module supported\n"); | ||
1851 | device_set_wakeup_capable(&pdev->dev, 1); | ||
1852 | } | ||
1853 | /* | 1891 | /* |
1854 | * On some platforms e.g. SPEAr the wake up irq differs from the mac irq | 1892 | * On some platforms e.g. SPEAr the wake up irq differs from the mac irq |
1855 | * The external wake up irq can be passed through the platform code | 1893 | * The external wake up irq can be passed through the platform code |
@@ -1862,7 +1900,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
1862 | if (priv->wol_irq == -ENXIO) | 1900 | if (priv->wol_irq == -ENXIO) |
1863 | priv->wol_irq = ndev->irq; | 1901 | priv->wol_irq = ndev->irq; |
1864 | 1902 | ||
1865 | |||
1866 | platform_set_drvdata(pdev, ndev); | 1903 | platform_set_drvdata(pdev, ndev); |
1867 | 1904 | ||
1868 | /* Set the I/O base addr */ | 1905 | /* Set the I/O base addr */ |
@@ -1875,7 +1912,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
1875 | goto out_free_ndev; | 1912 | goto out_free_ndev; |
1876 | } | 1913 | } |
1877 | 1914 | ||
1878 | /* MAC HW revice detection */ | 1915 | /* MAC HW device detection */ |
1879 | ret = stmmac_mac_device_setup(ndev); | 1916 | ret = stmmac_mac_device_setup(ndev); |
1880 | if (ret < 0) | 1917 | if (ret < 0) |
1881 | goto out_plat_exit; | 1918 | goto out_plat_exit; |
@@ -1978,12 +2015,13 @@ static int stmmac_suspend(struct device *dev) | |||
1978 | if (!ndev || !netif_running(ndev)) | 2015 | if (!ndev || !netif_running(ndev)) |
1979 | return 0; | 2016 | return 0; |
1980 | 2017 | ||
2018 | if (priv->phydev) | ||
2019 | phy_stop(priv->phydev); | ||
2020 | |||
1981 | spin_lock(&priv->lock); | 2021 | spin_lock(&priv->lock); |
1982 | 2022 | ||
1983 | netif_device_detach(ndev); | 2023 | netif_device_detach(ndev); |
1984 | netif_stop_queue(ndev); | 2024 | netif_stop_queue(ndev); |
1985 | if (priv->phydev) | ||
1986 | phy_stop(priv->phydev); | ||
1987 | 2025 | ||
1988 | #ifdef CONFIG_STMMAC_TIMER | 2026 | #ifdef CONFIG_STMMAC_TIMER |
1989 | priv->tm->timer_stop(); | 2027 | priv->tm->timer_stop(); |
@@ -2041,12 +2079,13 @@ static int stmmac_resume(struct device *dev) | |||
2041 | #endif | 2079 | #endif |
2042 | napi_enable(&priv->napi); | 2080 | napi_enable(&priv->napi); |
2043 | 2081 | ||
2044 | if (priv->phydev) | ||
2045 | phy_start(priv->phydev); | ||
2046 | |||
2047 | netif_start_queue(ndev); | 2082 | netif_start_queue(ndev); |
2048 | 2083 | ||
2049 | spin_unlock(&priv->lock); | 2084 | spin_unlock(&priv->lock); |
2085 | |||
2086 | if (priv->phydev) | ||
2087 | phy_start(priv->phydev); | ||
2088 | |||
2050 | return 0; | 2089 | return 0; |
2051 | } | 2090 | } |
2052 | 2091 | ||