mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
Merge branch 'net-stmmac-timestamping-ptp-cleanups'
Russell King says: ==================== net: stmmac: timestamping/ptp cleanups This series cleans up the hardware timestamping / PTP initialisation and cleanup code in the stmmac driver. Several key points in no particular order: 1. Golden rule: unregister first, then release resources. stmmac_release_ptp didn't do this. 2. Avoid leaking resources - __stmmac_open() failure leaves the timestamping support initialised, but stops its clock. Also violates (1). 3. Avoid double-release of resources - stmmac_open() followed by stmmac_xdp_open() failing results in the PTP clock prepare and enable counts being released, and if the interface is then brought down, they are incorrectly released again. As XDP doesn't gain any additional prepare/enables on the PTP clock, remove this incorrect cleanup. 4. Changing the MTU of the interface is disruptive to PTP, and remains so as long as. This is not fixed by this series (too invasive at the moment.) 5. Avoid exporting functions that aren't used... 6. Avoid unnecessary runtime PM state manipulations (no point manipulating this when MTU changes). 7. Make the PTP/timestamping initialisation more readable - no point calling functions in the same file from one callsite that return error codes from one location in the called function, to only have the sole callee print messages depending on that return code. Also simplifying the mess in stmmac_hw_setup(). Also placing support checks in a better location. Also getting rid of the "ptp_register" boolean through this restructuring. v1 was tested by Gatien CHEVALLIER - thanks. ==================== Link: https://patch.msgid.link/aMKtV6O0WqlmJFN4@shell.armlinux.org.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
e0706474b1
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user