Message ID | 1515076573-6732-1-git-send-email-tmaimon77@gmail.com |
---|---|
State | Not Applicable, archived |
Headers | show |
Series | [linux,dev-4.13,v1] net: stmmac: bypass for lpi eee hang issue | expand |
On 5 Jan. 2018 01:36, "Tomer Maimon" <tmaimon77@gmail.com> wrote: Bypass for lpi eee hang issue in the STMicroelectronics 10/100/1000 Ethernet driver Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> Can you please submit this one upstream? If you need advice on how to do this then let me know. Cheers, Joel --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 27 +++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index a916e13624eb..c19bec963e28 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -136,6 +136,7 @@ struct stmmac_priv { int use_riwt; int irq_wake; spinlock_t ptp_lock; + spinlock_t lpi_lock; void __iomem *mmcaddr; void __iomem *ptpaddr; u32 mss; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 1763e48c84e2..4c8c7a463f40 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -333,9 +333,13 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv) */ void stmmac_disable_eee_mode(struct stmmac_priv *priv) { + unsigned long flags; + priv->hw->mac->reset_eee_mode(priv->hw); del_timer_sync(&priv->eee_ctrl_timer); + spin_lock_irqsave(&priv->lpi_lock, flags); priv->tx_path_in_lpi_mode = false; + spin_unlock_irqrestore(&priv->lpi_lock, flags); } /** @@ -1872,6 +1876,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue) netdev_tx_completed_queue(netdev_get_tx_queue(priv->dev, queue), pkts_compl, bytes_compl); + netif_tx_unlock(priv->dev); if (unlikely(netif_tx_queue_stopped(netdev_get_tx_queue(priv->dev, queue))) && @@ -1882,11 +1887,16 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue) netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue)); } - if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { - stmmac_enable_eee_mode(priv); - mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); + if (priv->eee_enabled) { + unsigned long flags; + + spin_lock_irqsave(&priv->lpi_lock, flags); + if (!priv->tx_path_in_lpi_mode) + mod_timer(&priv->eee_ctrl_timer, + STMMAC_LPI_T(eee_timer)); + + spin_unlock_irqrestore(&priv->lpi_lock, flags); } - netif_tx_unlock(priv->dev); } static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv, u32 chan) @@ -2968,6 +2978,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) unsigned int enh_desc; unsigned int des; + if (priv->tx_path_in_lpi_mode) + stmmac_disable_eee_mode(priv); + tx_q = &priv->tx_queue[queue]; /* Manage oversized TCP frames for GMAC4 device */ @@ -2988,9 +3001,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } - if (priv->tx_path_in_lpi_mode) - stmmac_disable_eee_mode(priv); - entry = tx_q->cur_tx; first_entry = entry; @@ -3638,11 +3648,13 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) &priv->xstats); if (unlikely(status)) { + spin_lock(&priv->lpi_lock); /* For LPI we need to save the tx status */ if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE) priv->tx_path_in_lpi_mode = true; if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE) priv->tx_path_in_lpi_mode = false; + spin_unlock(&priv->lpi_lock); } if (priv->synopsys_id >= DWMAC_CORE_4_00) { @@ -4196,6 +4208,7 @@ int stmmac_dvr_probe(struct device *device, } spin_lock_init(&priv->lock); + spin_lock_init(&priv->lpi_lock); /* If a specific clk_csr value is passed from the platform * this means that the CSR Clock Range selection cannot be -- 2.14.1 <div dir="auto"><div><br><div class="gmail_extra"><br><div class="gmail_quote">On 5 Jan. 2018 01:36, "Tomer Maimon" <<a href="mailto:tmaimon77@gmail.com">tmaimon77@gmail.com</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Bypass for lpi eee hang issue in the<br> STMicroelectronics 10/100/1000 Ethernet driver<br> <br> Signed-off-by: Tomer Maimon <<a href="mailto:tmaimon77@gmail.com">tmaimon77@gmail.com</a>><br></blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">Can you please submit this one upstream?</div><div dir="auto"><br></div><div dir="auto">If you need advice on how to do this then let me know.</div><div dir="auto"><br></div><div dir="auto">Cheers,</div><div dir="auto"><br></div><div dir="auto">Joel</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> ---<br> drivers/net/ethernet/stmicro/<wbr>stmmac/stmmac.h | 1 +<br> drivers/net/ethernet/stmicro/<wbr>stmmac/stmmac_main.c | 27 +++++++++++++++++------<br> 2 files changed, 21 insertions(+), 7 deletions(-)<br> <br> diff --git a/drivers/net/ethernet/<wbr>stmicro/stmmac/stmmac.h b/drivers/net/ethernet/<wbr>stmicro/stmmac/stmmac.h<br> index a916e13624eb..c19bec963e28 100644<br> --- a/drivers/net/ethernet/<wbr>stmicro/stmmac/stmmac.h<br> +++ b/drivers/net/ethernet/<wbr>stmicro/stmmac/stmmac.h<br> @@ -136,6 +136,7 @@ struct stmmac_priv {<br> int use_riwt;<br> int irq_wake;<br> spinlock_t ptp_lock;<br> + spinlock_t lpi_lock;<br> void __iomem *mmcaddr;<br> void __iomem *ptpaddr;<br> u32 mss;<br> diff --git a/drivers/net/ethernet/<wbr>stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/<wbr>stmicro/stmmac/stmmac_main.c<br> index 1763e48c84e2..4c8c7a463f40 100644<br> --- a/drivers/net/ethernet/<wbr>stmicro/stmmac/stmmac_main.c<br> +++ b/drivers/net/ethernet/<wbr>stmicro/stmmac/stmmac_main.c<br> @@ -333,9 +333,13 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv)<br> */<br> void stmmac_disable_eee_mode(struct stmmac_priv *priv)<br> {<br> + unsigned long flags;<br> +<br> priv->hw->mac->reset_eee_mode(<wbr>priv->hw);<br> del_timer_sync(&priv->eee_<wbr>ctrl_timer);<br> + spin_lock_irqsave(&priv->lpi_<wbr>lock, flags);<br> priv->tx_path_in_lpi_mode = false;<br> + spin_unlock_irqrestore(&priv-><wbr>lpi_lock, flags);<br> }<br> <br> /**<br> @@ -1872,6 +1876,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)<br> <br> netdev_tx_completed_queue(<wbr>netdev_get_tx_queue(priv->dev, queue),<br> pkts_compl, bytes_compl);<br> + netif_tx_unlock(priv->dev);<br> <br> if (unlikely(netif_tx_queue_<wbr>stopped(netdev_get_tx_queue(<wbr>priv->dev,<br> queue))) &&<br> @@ -1882,11 +1887,16 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)<br> netif_tx_wake_queue(netdev_<wbr>get_tx_queue(priv->dev, queue));<br> }<br> <br> - if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {<br> - stmmac_enable_eee_mode(priv);<br> - mod_timer(&priv->eee_ctrl_<wbr>timer, STMMAC_LPI_T(eee_timer));<br> + if (priv->eee_enabled) {<br> + unsigned long flags;<br> +<br> + spin_lock_irqsave(&priv->lpi_<wbr>lock, flags);<br> + if (!priv->tx_path_in_lpi_mode)<br> + mod_timer(&priv->eee_ctrl_<wbr>timer,<br> + STMMAC_LPI_T(eee_timer));<br> +<br> + spin_unlock_irqrestore(&priv-><wbr>lpi_lock, flags);<br> }<br> - netif_tx_unlock(priv->dev);<br> }<br> <br> static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv, u32 chan)<br> @@ -2968,6 +2978,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)<br> unsigned int enh_desc;<br> unsigned int des;<br> <br> + if (priv->tx_path_in_lpi_mode)<br> + stmmac_disable_eee_mode(priv);<br> +<br> tx_q = &priv->tx_queue[queue];<br> <br> /* Manage oversized TCP frames for GMAC4 device */<br> @@ -2988,9 +3001,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)<br> return NETDEV_TX_BUSY;<br> }<br> <br> - if (priv->tx_path_in_lpi_mode)<br> - stmmac_disable_eee_mode(priv);<br> -<br> entry = tx_q->cur_tx;<br> first_entry = entry;<br> <br> @@ -3638,11 +3648,13 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)<br> &priv->xstats);<br> <br> if (unlikely(status)) {<br> + spin_lock(&priv->lpi_lock);<br> /* For LPI we need to save the tx status */<br> if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE)<br> priv->tx_path_in_lpi_mode = true;<br> if (status & CORE_IRQ_TX_PATH_EXIT_LPI_<wbr>MODE)<br> priv->tx_path_in_lpi_mode = false;<br> + spin_unlock(&priv->lpi_lock);<br> }<br> <br> if (priv->synopsys_id >= DWMAC_CORE_4_00) {<br> @@ -4196,6 +4208,7 @@ int stmmac_dvr_probe(struct device *device,<br> }<br> <br> spin_lock_init(&priv->lock);<br> + spin_lock_init(&priv->lpi_<wbr>lock);<br> <br> /* If a specific clk_csr value is passed from the platform<br> * this means that the CSR Clock Range selection cannot be<br> <font color="#888888">--<br> 2.14.1<br> <br> </font></blockquote></div><br></div></div></div>
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index a916e13624eb..c19bec963e28 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -136,6 +136,7 @@ struct stmmac_priv { int use_riwt; int irq_wake; spinlock_t ptp_lock; + spinlock_t lpi_lock; void __iomem *mmcaddr; void __iomem *ptpaddr; u32 mss; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 1763e48c84e2..4c8c7a463f40 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -333,9 +333,13 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv) */ void stmmac_disable_eee_mode(struct stmmac_priv *priv) { + unsigned long flags; + priv->hw->mac->reset_eee_mode(priv->hw); del_timer_sync(&priv->eee_ctrl_timer); + spin_lock_irqsave(&priv->lpi_lock, flags); priv->tx_path_in_lpi_mode = false; + spin_unlock_irqrestore(&priv->lpi_lock, flags); } /** @@ -1872,6 +1876,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue) netdev_tx_completed_queue(netdev_get_tx_queue(priv->dev, queue), pkts_compl, bytes_compl); + netif_tx_unlock(priv->dev); if (unlikely(netif_tx_queue_stopped(netdev_get_tx_queue(priv->dev, queue))) && @@ -1882,11 +1887,16 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue) netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue)); } - if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { - stmmac_enable_eee_mode(priv); - mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); + if (priv->eee_enabled) { + unsigned long flags; + + spin_lock_irqsave(&priv->lpi_lock, flags); + if (!priv->tx_path_in_lpi_mode) + mod_timer(&priv->eee_ctrl_timer, + STMMAC_LPI_T(eee_timer)); + + spin_unlock_irqrestore(&priv->lpi_lock, flags); } - netif_tx_unlock(priv->dev); } static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv, u32 chan) @@ -2968,6 +2978,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) unsigned int enh_desc; unsigned int des; + if (priv->tx_path_in_lpi_mode) + stmmac_disable_eee_mode(priv); + tx_q = &priv->tx_queue[queue]; /* Manage oversized TCP frames for GMAC4 device */ @@ -2988,9 +3001,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } - if (priv->tx_path_in_lpi_mode) - stmmac_disable_eee_mode(priv); - entry = tx_q->cur_tx; first_entry = entry; @@ -3638,11 +3648,13 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) &priv->xstats); if (unlikely(status)) { + spin_lock(&priv->lpi_lock); /* For LPI we need to save the tx status */ if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE) priv->tx_path_in_lpi_mode = true; if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE) priv->tx_path_in_lpi_mode = false; + spin_unlock(&priv->lpi_lock); } if (priv->synopsys_id >= DWMAC_CORE_4_00) { @@ -4196,6 +4208,7 @@ int stmmac_dvr_probe(struct device *device, } spin_lock_init(&priv->lock); + spin_lock_init(&priv->lpi_lock); /* If a specific clk_csr value is passed from the platform * this means that the CSR Clock Range selection cannot be
Bypass for lpi eee hang issue in the STMicroelectronics 10/100/1000 Ethernet driver Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 27 +++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-)