diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index ec6bccb13710..151f08e5e85d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -392,7 +392,6 @@ int stmmac_pcs_setup(struct net_device *ndev); void stmmac_pcs_clean(struct net_device *ndev); void stmmac_set_ethtool_ops(struct net_device *netdev); -int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags); void stmmac_ptp_register(struct stmmac_priv *priv); void stmmac_ptp_unregister(struct stmmac_priv *priv); int stmmac_xdp_open(struct net_device *dev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 419cb49ee5a2..8c8ca5999bd8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -726,16 +726,14 @@ static int stmmac_hwtstamp_get(struct net_device *dev, * Will be rerun after resuming from suspend, case in which the timestamping * flags updated by stmmac_hwtstamp_set() also need to be restored. */ -int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags) +static int stmmac_init_tstamp_counter(struct stmmac_priv *priv, + u32 systime_flags) { bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; struct timespec64 now; u32 sec_inc = 0; u64 temp = 0; - if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) - return -EOPNOTSUPP; - if (!priv->plat->clk_ptp_rate) { netdev_err(priv->dev, "Invalid PTP clock rate"); return -EINVAL; @@ -770,16 +768,15 @@ int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags) return 0; } -EXPORT_SYMBOL_GPL(stmmac_init_tstamp_counter); /** - * stmmac_init_ptp - init PTP + * stmmac_init_timestamping - initialise timestamping * @priv: driver private structure * Description: this is to verify if the HW supports the PTPv1 or PTPv2. * This is done by looking at the HW cap. register. * This function also registers the ptp driver. */ -static int stmmac_init_ptp(struct stmmac_priv *priv) +static int stmmac_init_timestamping(struct stmmac_priv *priv) { bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; int ret; @@ -787,9 +784,16 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) if (priv->plat->ptp_clk_freq_config) priv->plat->ptp_clk_freq_config(priv); + if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) { + netdev_info(priv->dev, "PTP not supported by HW\n"); + return -EOPNOTSUPP; + } + ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE); - if (ret) + if (ret) { + netdev_warn(priv->dev, "PTP init failed\n"); return ret; + } priv->adv_ts = 0; /* Check if adv_ts can be enabled for dwmac 4.x / xgmac core */ @@ -815,10 +819,24 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) return 0; } +static void stmmac_setup_ptp(struct stmmac_priv *priv) +{ + int ret; + + ret = clk_prepare_enable(priv->plat->clk_ptp_ref); + if (ret < 0) + netdev_warn(priv->dev, + "failed to enable PTP reference clock: %pe\n", + ERR_PTR(ret)); + + if (stmmac_init_timestamping(priv) == 0) + stmmac_ptp_register(priv); +} + static void stmmac_release_ptp(struct stmmac_priv *priv) { - clk_disable_unprepare(priv->plat->clk_ptp_ref); stmmac_ptp_unregister(priv); + clk_disable_unprepare(priv->plat->clk_ptp_ref); } /** @@ -3418,7 +3436,7 @@ static void stmmac_safety_feat_configuration(struct stmmac_priv *priv) * 0 on success and an appropriate (-)ve integer as defined in errno.h * file on failure. */ -static int stmmac_hw_setup(struct net_device *dev, bool ptp_register) +static int stmmac_hw_setup(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); u32 rx_cnt = priv->plat->rx_queues_to_use; @@ -3489,22 +3507,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register) stmmac_mmc_setup(priv); - if (ptp_register) { - ret = clk_prepare_enable(priv->plat->clk_ptp_ref); - if (ret < 0) - netdev_warn(priv->dev, - "failed to enable PTP reference clock: %pe\n", - ERR_PTR(ret)); - } - - ret = stmmac_init_ptp(priv); - if (ret == -EOPNOTSUPP) - netdev_info(priv->dev, "PTP not supported by HW\n"); - else if (ret) - netdev_warn(priv->dev, "PTP init failed\n"); - else if (ptp_register) - stmmac_ptp_register(priv); - if (priv->use_riwt) { u32 queue; @@ -3568,13 +3570,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register) return 0; } -static void stmmac_hw_teardown(struct net_device *dev) -{ - struct stmmac_priv *priv = netdev_priv(dev); - - clk_disable_unprepare(priv->plat->clk_ptp_ref); -} - static void stmmac_free_irq(struct net_device *dev, enum request_irq_err irq_err, int irq_idx) { @@ -3972,10 +3967,6 @@ static int __stmmac_open(struct net_device *dev, if (!priv->tx_lpi_timer) priv->tx_lpi_timer = eee_timer * 1000; - ret = pm_runtime_resume_and_get(priv->device); - if (ret < 0) - return ret; - if ((!priv->hw->xpcs || xpcs_get_an_mode(priv->hw->xpcs, mode) != DW_AN_C73)) { ret = stmmac_init_phy(dev); @@ -3983,7 +3974,7 @@ static int __stmmac_open(struct net_device *dev, netdev_err(priv->dev, "%s: Cannot attach to PHY (error: %d)\n", __func__, ret); - goto init_phy_error; + return ret; } } @@ -4004,12 +3995,14 @@ static int __stmmac_open(struct net_device *dev, } } - ret = stmmac_hw_setup(dev, true); + ret = stmmac_hw_setup(dev); if (ret < 0) { netdev_err(priv->dev, "%s: Hw setup failed\n", __func__); goto init_error; } + stmmac_setup_ptp(priv); + stmmac_init_coalesce(priv); phylink_start(priv->phylink); @@ -4032,11 +4025,9 @@ static int __stmmac_open(struct net_device *dev, for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); - stmmac_hw_teardown(dev); + stmmac_release_ptp(priv); init_error: phylink_disconnect_phy(priv->phylink); -init_phy_error: - pm_runtime_put(priv->device); return ret; } @@ -4050,21 +4041,23 @@ static int stmmac_open(struct net_device *dev) if (IS_ERR(dma_conf)) return PTR_ERR(dma_conf); + ret = pm_runtime_resume_and_get(priv->device); + if (ret < 0) + goto err; + ret = __stmmac_open(dev, dma_conf); - if (ret) + if (ret) { + pm_runtime_put(priv->device); +err: free_dma_desc_resources(priv, dma_conf); + } kfree(dma_conf); + return ret; } -/** - * stmmac_release - close entry point of the driver - * @dev : device pointer. - * Description: - * This is the stop entry point of the driver. - */ -static int stmmac_release(struct net_device *dev) +static void __stmmac_release(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); u32 chan; @@ -4104,6 +4097,19 @@ static int stmmac_release(struct net_device *dev) if (stmmac_fpe_supported(priv)) ethtool_mmsv_stop(&priv->fpe_cfg.mmsv); +} + +/** + * stmmac_release - close entry point of the driver + * @dev : device pointer. + * Description: + * This is the stop entry point of the driver. + */ +static int stmmac_release(struct net_device *dev) +{ + struct stmmac_priv *priv = netdev_priv(dev); + + __stmmac_release(dev); pm_runtime_put(priv->device); @@ -5902,7 +5908,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) return PTR_ERR(dma_conf); } - stmmac_release(dev); + __stmmac_release(dev); ret = __stmmac_open(dev, dma_conf); if (ret) { @@ -6992,7 +6998,6 @@ int stmmac_xdp_open(struct net_device *dev) for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); - stmmac_hw_teardown(dev); init_error: free_dma_desc_resources(priv, &priv->dma_conf); dma_desc_error: @@ -7909,7 +7914,7 @@ int stmmac_resume(struct device *dev) stmmac_free_tx_skbufs(priv); stmmac_clear_descriptors(priv, &priv->dma_conf); - ret = stmmac_hw_setup(ndev, false); + ret = stmmac_hw_setup(ndev); if (ret < 0) { netdev_err(priv->dev, "%s: Hw setup failed\n", __func__); mutex_unlock(&priv->lock); @@ -7917,6 +7922,8 @@ int stmmac_resume(struct device *dev) return ret; } + stmmac_init_timestamping(priv); + stmmac_init_coalesce(priv); phylink_rx_clk_stop_block(priv->phylink); stmmac_set_rx_mode(ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c index 69bd8ace139c..993ff4e87e55 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c @@ -370,8 +370,12 @@ void stmmac_ptp_register(struct stmmac_priv *priv) if (IS_ERR(priv->ptp_clock)) { netdev_err(priv->dev, "ptp_clock_register failed\n"); priv->ptp_clock = NULL; - } else if (priv->ptp_clock) + } + + if (priv->ptp_clock) netdev_info(priv->dev, "registered PTP clock\n"); + else + mutex_destroy(&priv->aux_ts_lock); } /** @@ -387,7 +391,7 @@ void stmmac_ptp_unregister(struct stmmac_priv *priv) priv->ptp_clock = NULL; pr_debug("Removed PTP HW clock successfully on %s\n", priv->dev->name); - } - mutex_destroy(&priv->aux_ts_lock); + mutex_destroy(&priv->aux_ts_lock); + } }