diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
-rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 1aabe4bcc8ea..ecaa7a90b7c8 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -2310,14 +2310,24 @@ static const struct fec_stat { | |||
2310 | { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK }, | 2310 | { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK }, |
2311 | }; | 2311 | }; |
2312 | 2312 | ||
2313 | static void fec_enet_get_ethtool_stats(struct net_device *dev, | 2313 | static void fec_enet_update_ethtool_stats(struct net_device *dev) |
2314 | struct ethtool_stats *stats, u64 *data) | ||
2315 | { | 2314 | { |
2316 | struct fec_enet_private *fep = netdev_priv(dev); | 2315 | struct fec_enet_private *fep = netdev_priv(dev); |
2317 | int i; | 2316 | int i; |
2318 | 2317 | ||
2319 | for (i = 0; i < ARRAY_SIZE(fec_stats); i++) | 2318 | for (i = 0; i < ARRAY_SIZE(fec_stats); i++) |
2320 | data[i] = readl(fep->hwp + fec_stats[i].offset); | 2319 | fep->ethtool_stats[i] = readl(fep->hwp + fec_stats[i].offset); |
2320 | } | ||
2321 | |||
2322 | static void fec_enet_get_ethtool_stats(struct net_device *dev, | ||
2323 | struct ethtool_stats *stats, u64 *data) | ||
2324 | { | ||
2325 | struct fec_enet_private *fep = netdev_priv(dev); | ||
2326 | |||
2327 | if (netif_running(dev)) | ||
2328 | fec_enet_update_ethtool_stats(dev); | ||
2329 | |||
2330 | memcpy(data, fep->ethtool_stats, ARRAY_SIZE(fec_stats) * sizeof(u64)); | ||
2321 | } | 2331 | } |
2322 | 2332 | ||
2323 | static void fec_enet_get_strings(struct net_device *netdev, | 2333 | static void fec_enet_get_strings(struct net_device *netdev, |
@@ -2861,6 +2871,8 @@ fec_enet_close(struct net_device *ndev) | |||
2861 | if (fep->quirks & FEC_QUIRK_ERR006687) | 2871 | if (fep->quirks & FEC_QUIRK_ERR006687) |
2862 | imx6q_cpuidle_fec_irqs_unused(); | 2872 | imx6q_cpuidle_fec_irqs_unused(); |
2863 | 2873 | ||
2874 | fec_enet_update_ethtool_stats(ndev); | ||
2875 | |||
2864 | fec_enet_clk_enable(ndev, false); | 2876 | fec_enet_clk_enable(ndev, false); |
2865 | pinctrl_pm_select_sleep_state(&fep->pdev->dev); | 2877 | pinctrl_pm_select_sleep_state(&fep->pdev->dev); |
2866 | pm_runtime_mark_last_busy(&fep->pdev->dev); | 2878 | pm_runtime_mark_last_busy(&fep->pdev->dev); |
@@ -3166,6 +3178,8 @@ static int fec_enet_init(struct net_device *ndev) | |||
3166 | 3178 | ||
3167 | fec_restart(ndev); | 3179 | fec_restart(ndev); |
3168 | 3180 | ||
3181 | fec_enet_update_ethtool_stats(ndev); | ||
3182 | |||
3169 | return 0; | 3183 | return 0; |
3170 | } | 3184 | } |
3171 | 3185 | ||
@@ -3264,7 +3278,8 @@ fec_probe(struct platform_device *pdev) | |||
3264 | fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs); | 3278 | fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs); |
3265 | 3279 | ||
3266 | /* Init network device */ | 3280 | /* Init network device */ |
3267 | ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private), | 3281 | ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private) + |
3282 | ARRAY_SIZE(fec_stats) * sizeof(u64), | ||
3268 | num_tx_qs, num_rx_qs); | 3283 | num_tx_qs, num_rx_qs); |
3269 | if (!ndev) | 3284 | if (!ndev) |
3270 | return -ENOMEM; | 3285 | return -ENOMEM; |
@@ -3461,6 +3476,8 @@ failed_regulator: | |||
3461 | failed_clk_ipg: | 3476 | failed_clk_ipg: |
3462 | fec_enet_clk_enable(ndev, false); | 3477 | fec_enet_clk_enable(ndev, false); |
3463 | failed_clk: | 3478 | failed_clk: |
3479 | if (of_phy_is_fixed_link(np)) | ||
3480 | of_phy_deregister_fixed_link(np); | ||
3464 | failed_phy: | 3481 | failed_phy: |
3465 | of_node_put(phy_node); | 3482 | of_node_put(phy_node); |
3466 | failed_ioremap: | 3483 | failed_ioremap: |
@@ -3474,6 +3491,7 @@ fec_drv_remove(struct platform_device *pdev) | |||
3474 | { | 3491 | { |
3475 | struct net_device *ndev = platform_get_drvdata(pdev); | 3492 | struct net_device *ndev = platform_get_drvdata(pdev); |
3476 | struct fec_enet_private *fep = netdev_priv(ndev); | 3493 | struct fec_enet_private *fep = netdev_priv(ndev); |
3494 | struct device_node *np = pdev->dev.of_node; | ||
3477 | 3495 | ||
3478 | cancel_work_sync(&fep->tx_timeout_work); | 3496 | cancel_work_sync(&fep->tx_timeout_work); |
3479 | fec_ptp_stop(pdev); | 3497 | fec_ptp_stop(pdev); |
@@ -3481,6 +3499,8 @@ fec_drv_remove(struct platform_device *pdev) | |||
3481 | fec_enet_mii_remove(fep); | 3499 | fec_enet_mii_remove(fep); |
3482 | if (fep->reg_phy) | 3500 | if (fep->reg_phy) |
3483 | regulator_disable(fep->reg_phy); | 3501 | regulator_disable(fep->reg_phy); |
3502 | if (of_phy_is_fixed_link(np)) | ||
3503 | of_phy_deregister_fixed_link(np); | ||
3484 | of_node_put(fep->phy_node); | 3504 | of_node_put(fep->phy_node); |
3485 | free_netdev(ndev); | 3505 | free_netdev(ndev); |
3486 | 3506 | ||