mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
net: stmmac: block PHY RXC clock-stop
The DesignWare core requires the receive clock to be running during certain operations. Ensure that we block PHY RXC clock-stop during these operations. This is a best-efforts change - not everywhere can be covered by this because of net's core locking, which means we can't access the MDIO bus to configure the PHY to disable RXC clock-stop in certain areas. These are marked with FIXME comments. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Link: https://patch.msgid.link/E1tvO6p-008Vjz-Qy@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
ddf4bd3f73
commit
dd557266cf
@@ -3484,9 +3484,18 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
|
||||
if (priv->hw->phylink_pcs)
|
||||
phylink_pcs_pre_init(priv->phylink, priv->hw->phylink_pcs);
|
||||
|
||||
/* Note that clk_rx_i must be running for reset to complete. This
|
||||
* clock may also be required when setting the MAC address.
|
||||
*
|
||||
* Block the receive clock stop for LPI mode at the PHY in case
|
||||
* the link is established with EEE mode active.
|
||||
*/
|
||||
phylink_rx_clk_stop_block(priv->phylink);
|
||||
|
||||
/* DMA initialization and SW reset */
|
||||
ret = stmmac_init_dma_engine(priv);
|
||||
if (ret < 0) {
|
||||
phylink_rx_clk_stop_unblock(priv->phylink);
|
||||
netdev_err(priv->dev, "%s: DMA engine initialization failed\n",
|
||||
__func__);
|
||||
return ret;
|
||||
@@ -3494,6 +3503,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
|
||||
|
||||
/* Copy the MAC addr into the HW */
|
||||
stmmac_set_umac_addr(priv, priv->hw, dev->dev_addr, 0);
|
||||
phylink_rx_clk_stop_unblock(priv->phylink);
|
||||
|
||||
/* PS and related bits will be programmed according to the speed */
|
||||
if (priv->hw->pcs) {
|
||||
@@ -3604,7 +3614,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
|
||||
/* Start the ball rolling... */
|
||||
stmmac_start_all_dma(priv);
|
||||
|
||||
phylink_rx_clk_stop_block(priv->phylink);
|
||||
stmmac_set_hw_vlan_mode(priv, priv->hw);
|
||||
phylink_rx_clk_stop_unblock(priv->phylink);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -5888,6 +5900,9 @@ static void stmmac_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
||||
* whenever multicast addresses must be enabled/disabled.
|
||||
* Return value:
|
||||
* void.
|
||||
*
|
||||
* FIXME: This may need RXC to be running, but it may be called with BH
|
||||
* disabled, which means we can't call phylink_rx_clk_stop*().
|
||||
*/
|
||||
static void stmmac_set_rx_mode(struct net_device *dev)
|
||||
{
|
||||
@@ -6020,7 +6035,9 @@ static int stmmac_set_features(struct net_device *netdev,
|
||||
else
|
||||
priv->hw->hw_vlan_en = false;
|
||||
|
||||
phylink_rx_clk_stop_block(priv->phylink);
|
||||
stmmac_set_hw_vlan_mode(priv, priv->hw);
|
||||
phylink_rx_clk_stop_unblock(priv->phylink);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -6304,7 +6321,9 @@ static int stmmac_set_mac_address(struct net_device *ndev, void *addr)
|
||||
if (ret)
|
||||
goto set_mac_error;
|
||||
|
||||
phylink_rx_clk_stop_block(priv->phylink);
|
||||
stmmac_set_umac_addr(priv, priv->hw, ndev->dev_addr, 0);
|
||||
phylink_rx_clk_stop_unblock(priv->phylink);
|
||||
|
||||
set_mac_error:
|
||||
pm_runtime_put(priv->device);
|
||||
@@ -6660,6 +6679,9 @@ static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_double)
|
||||
return stmmac_update_vlan_hash(priv, priv->hw, hash, pmatch, is_double);
|
||||
}
|
||||
|
||||
/* FIXME: This may need RXC to be running, but it may be called with BH
|
||||
* disabled, which means we can't call phylink_rx_clk_stop*().
|
||||
*/
|
||||
static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
@@ -6691,6 +6713,9 @@ err_pm_put:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* FIXME: This may need RXC to be running, but it may be called with BH
|
||||
* disabled, which means we can't call phylink_rx_clk_stop*().
|
||||
*/
|
||||
static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
@@ -7951,9 +7976,11 @@ int stmmac_resume(struct device *dev)
|
||||
|
||||
stmmac_hw_setup(ndev, false);
|
||||
stmmac_init_coalesce(priv);
|
||||
phylink_rx_clk_stop_block(priv->phylink);
|
||||
stmmac_set_rx_mode(ndev);
|
||||
|
||||
stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw);
|
||||
phylink_rx_clk_stop_unblock(priv->phylink);
|
||||
|
||||
stmmac_enable_all_queues(priv);
|
||||
stmmac_enable_all_dma_irq(priv);
|
||||
|
||||
Reference in New Issue
Block a user