aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c39
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.h1
2 files changed, 31 insertions, 9 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 7facda1328f8..99a838db032e 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1316,8 +1316,10 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start)
1316 RFLR); 1316 RFLR);
1317 1317
1318 sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); 1318 sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
1319 if (start) 1319 if (start) {
1320 mdp->irq_enabled = true;
1320 sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); 1321 sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
1322 }
1321 1323
1322 /* PAUSE Prohibition */ 1324 /* PAUSE Prohibition */
1323 val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | 1325 val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
@@ -1653,7 +1655,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
1653 if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) 1655 if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check))
1654 ret = IRQ_HANDLED; 1656 ret = IRQ_HANDLED;
1655 else 1657 else
1656 goto other_irq; 1658 goto out;
1659
1660 if (!likely(mdp->irq_enabled)) {
1661 sh_eth_write(ndev, 0, EESIPR);
1662 goto out;
1663 }
1657 1664
1658 if (intr_status & EESR_RX_CHECK) { 1665 if (intr_status & EESR_RX_CHECK) {
1659 if (napi_schedule_prep(&mdp->napi)) { 1666 if (napi_schedule_prep(&mdp->napi)) {
@@ -1684,7 +1691,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
1684 sh_eth_error(ndev, intr_status); 1691 sh_eth_error(ndev, intr_status);
1685 } 1692 }
1686 1693
1687other_irq: 1694out:
1688 spin_unlock(&mdp->lock); 1695 spin_unlock(&mdp->lock);
1689 1696
1690 return ret; 1697 return ret;
@@ -1712,7 +1719,8 @@ static int sh_eth_poll(struct napi_struct *napi, int budget)
1712 napi_complete(napi); 1719 napi_complete(napi);
1713 1720
1714 /* Reenable Rx interrupts */ 1721 /* Reenable Rx interrupts */
1715 sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); 1722 if (mdp->irq_enabled)
1723 sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
1716out: 1724out:
1717 return budget - quota; 1725 return budget - quota;
1718} 1726}
@@ -1970,12 +1978,20 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
1970 if (netif_running(ndev)) { 1978 if (netif_running(ndev)) {
1971 netif_device_detach(ndev); 1979 netif_device_detach(ndev);
1972 netif_tx_disable(ndev); 1980 netif_tx_disable(ndev);
1973 /* Disable interrupts by clearing the interrupt mask. */ 1981
1982 /* Serialise with the interrupt handler and NAPI, then
1983 * disable interrupts. We have to clear the
1984 * irq_enabled flag first to ensure that interrupts
1985 * won't be re-enabled.
1986 */
1987 mdp->irq_enabled = false;
1988 synchronize_irq(ndev->irq);
1989 napi_synchronize(&mdp->napi);
1974 sh_eth_write(ndev, 0x0000, EESIPR); 1990 sh_eth_write(ndev, 0x0000, EESIPR);
1991
1975 /* Stop the chip's Tx and Rx processes. */ 1992 /* Stop the chip's Tx and Rx processes. */
1976 sh_eth_write(ndev, 0, EDTRR); 1993 sh_eth_write(ndev, 0, EDTRR);
1977 sh_eth_write(ndev, 0, EDRRR); 1994 sh_eth_write(ndev, 0, EDRRR);
1978 synchronize_irq(ndev->irq);
1979 1995
1980 /* Free all the skbuffs in the Rx queue. */ 1996 /* Free all the skbuffs in the Rx queue. */
1981 sh_eth_ring_free(ndev); 1997 sh_eth_ring_free(ndev);
@@ -2001,6 +2017,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
2001 return ret; 2017 return ret;
2002 } 2018 }
2003 2019
2020 mdp->irq_enabled = true;
2004 sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); 2021 sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
2005 /* Setting the Rx mode will start the Rx process. */ 2022 /* Setting the Rx mode will start the Rx process. */
2006 sh_eth_write(ndev, EDRRR_R, EDRRR); 2023 sh_eth_write(ndev, EDRRR_R, EDRRR);
@@ -2184,7 +2201,13 @@ static int sh_eth_close(struct net_device *ndev)
2184 2201
2185 netif_stop_queue(ndev); 2202 netif_stop_queue(ndev);
2186 2203
2187 /* Disable interrupts by clearing the interrupt mask. */ 2204 /* Serialise with the interrupt handler and NAPI, then disable
2205 * interrupts. We have to clear the irq_enabled flag first to
2206 * ensure that interrupts won't be re-enabled.
2207 */
2208 mdp->irq_enabled = false;
2209 synchronize_irq(ndev->irq);
2210 napi_disable(&mdp->napi);
2188 sh_eth_write(ndev, 0x0000, EESIPR); 2211 sh_eth_write(ndev, 0x0000, EESIPR);
2189 2212
2190 /* Stop the chip's Tx and Rx processes. */ 2213 /* Stop the chip's Tx and Rx processes. */
@@ -2201,8 +2224,6 @@ static int sh_eth_close(struct net_device *ndev)
2201 2224
2202 free_irq(ndev->irq, ndev); 2225 free_irq(ndev->irq, ndev);
2203 2226
2204 napi_disable(&mdp->napi);
2205
2206 /* Free all the skbuffs in the Rx queue. */ 2227 /* Free all the skbuffs in the Rx queue. */
2207 sh_eth_ring_free(ndev); 2228 sh_eth_ring_free(ndev);
2208 2229
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 71f5de1171bd..332d3c16d483 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -513,6 +513,7 @@ struct sh_eth_private {
513 u32 rx_buf_sz; /* Based on MTU+slack. */ 513 u32 rx_buf_sz; /* Based on MTU+slack. */
514 int edmac_endian; 514 int edmac_endian;
515 struct napi_struct napi; 515 struct napi_struct napi;
516 bool irq_enabled;
516 /* MII transceiver section. */ 517 /* MII transceiver section. */
517 u32 phy_id; /* PHY ID */ 518 u32 phy_id; /* PHY ID */
518 struct mii_bus *mii_bus; /* MDIO bus control */ 519 struct mii_bus *mii_bus; /* MDIO bus control */