Commit 9d08da9630cc7a7e97fe163fc2837c6bf1c86a56
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge branch 'sh_eth'
Ben Hutchings says: ==================== Fixes for sh_eth #2 I'm continuing review and testing of Ethernet support on the R-Car H2 chip. This series fixes more of the issues I've found, but it won't be the last set. These are not tested on any of the other supported chips. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 2 changed files Side-by-side Diff
drivers/net/ethernet/renesas/sh_eth.c
... | ... | @@ -1316,8 +1316,10 @@ |
1316 | 1316 | RFLR); |
1317 | 1317 | |
1318 | 1318 | sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); |
1319 | - if (start) | |
1319 | + if (start) { | |
1320 | + mdp->irq_enabled = true; | |
1320 | 1321 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); |
1322 | + } | |
1321 | 1323 | |
1322 | 1324 | /* PAUSE Prohibition */ |
1323 | 1325 | val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | |
1324 | 1326 | |
... | ... | @@ -1653,8 +1655,13 @@ |
1653 | 1655 | if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) |
1654 | 1656 | ret = IRQ_HANDLED; |
1655 | 1657 | else |
1656 | - goto other_irq; | |
1658 | + goto out; | |
1657 | 1659 | |
1660 | + if (!likely(mdp->irq_enabled)) { | |
1661 | + sh_eth_write(ndev, 0, EESIPR); | |
1662 | + goto out; | |
1663 | + } | |
1664 | + | |
1658 | 1665 | if (intr_status & EESR_RX_CHECK) { |
1659 | 1666 | if (napi_schedule_prep(&mdp->napi)) { |
1660 | 1667 | /* Mask Rx interrupts */ |
... | ... | @@ -1684,7 +1691,7 @@ |
1684 | 1691 | sh_eth_error(ndev, intr_status); |
1685 | 1692 | } |
1686 | 1693 | |
1687 | -other_irq: | |
1694 | +out: | |
1688 | 1695 | spin_unlock(&mdp->lock); |
1689 | 1696 | |
1690 | 1697 | return ret; |
... | ... | @@ -1712,7 +1719,8 @@ |
1712 | 1719 | napi_complete(napi); |
1713 | 1720 | |
1714 | 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); | |
1716 | 1724 | out: |
1717 | 1725 | return budget - quota; |
1718 | 1726 | } |
1719 | 1727 | |
1720 | 1728 | |
1721 | 1729 | |
1722 | 1730 | |
1723 | 1731 | |
1724 | 1732 | |
1725 | 1733 | |
... | ... | @@ -1968,40 +1976,52 @@ |
1968 | 1976 | return -EINVAL; |
1969 | 1977 | |
1970 | 1978 | if (netif_running(ndev)) { |
1979 | + netif_device_detach(ndev); | |
1971 | 1980 | netif_tx_disable(ndev); |
1972 | - /* 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); | |
1973 | 1990 | sh_eth_write(ndev, 0x0000, EESIPR); |
1991 | + | |
1974 | 1992 | /* Stop the chip's Tx and Rx processes. */ |
1975 | 1993 | sh_eth_write(ndev, 0, EDTRR); |
1976 | 1994 | sh_eth_write(ndev, 0, EDRRR); |
1977 | - synchronize_irq(ndev->irq); | |
1995 | + | |
1996 | + /* Free all the skbuffs in the Rx queue. */ | |
1997 | + sh_eth_ring_free(ndev); | |
1998 | + /* Free DMA buffer */ | |
1999 | + sh_eth_free_dma_buffer(mdp); | |
1978 | 2000 | } |
1979 | 2001 | |
1980 | - /* Free all the skbuffs in the Rx queue. */ | |
1981 | - sh_eth_ring_free(ndev); | |
1982 | - /* Free DMA buffer */ | |
1983 | - sh_eth_free_dma_buffer(mdp); | |
1984 | - | |
1985 | 2002 | /* Set new parameters */ |
1986 | 2003 | mdp->num_rx_ring = ring->rx_pending; |
1987 | 2004 | mdp->num_tx_ring = ring->tx_pending; |
1988 | 2005 | |
1989 | - ret = sh_eth_ring_init(ndev); | |
1990 | - if (ret < 0) { | |
1991 | - netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", __func__); | |
1992 | - return ret; | |
1993 | - } | |
1994 | - ret = sh_eth_dev_init(ndev, false); | |
1995 | - if (ret < 0) { | |
1996 | - netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", __func__); | |
1997 | - return ret; | |
1998 | - } | |
1999 | - | |
2000 | 2006 | if (netif_running(ndev)) { |
2007 | + ret = sh_eth_ring_init(ndev); | |
2008 | + if (ret < 0) { | |
2009 | + netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", | |
2010 | + __func__); | |
2011 | + return ret; | |
2012 | + } | |
2013 | + ret = sh_eth_dev_init(ndev, false); | |
2014 | + if (ret < 0) { | |
2015 | + netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", | |
2016 | + __func__); | |
2017 | + return ret; | |
2018 | + } | |
2019 | + | |
2020 | + mdp->irq_enabled = true; | |
2001 | 2021 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); |
2002 | 2022 | /* Setting the Rx mode will start the Rx process. */ |
2003 | 2023 | sh_eth_write(ndev, EDRRR_R, EDRRR); |
2004 | - netif_wake_queue(ndev); | |
2024 | + netif_device_attach(ndev); | |
2005 | 2025 | } |
2006 | 2026 | |
2007 | 2027 | return 0; |
... | ... | @@ -2117,6 +2137,9 @@ |
2117 | 2137 | } |
2118 | 2138 | spin_unlock_irqrestore(&mdp->lock, flags); |
2119 | 2139 | |
2140 | + if (skb_padto(skb, ETH_ZLEN)) | |
2141 | + return NETDEV_TX_OK; | |
2142 | + | |
2120 | 2143 | entry = mdp->cur_tx % mdp->num_tx_ring; |
2121 | 2144 | mdp->tx_skbuff[entry] = skb; |
2122 | 2145 | txdesc = &mdp->tx_ring[entry]; |
... | ... | @@ -2126,10 +2149,7 @@ |
2126 | 2149 | skb->len + 2); |
2127 | 2150 | txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, |
2128 | 2151 | DMA_TO_DEVICE); |
2129 | - if (skb->len < ETH_ZLEN) | |
2130 | - txdesc->buffer_length = ETH_ZLEN; | |
2131 | - else | |
2132 | - txdesc->buffer_length = skb->len; | |
2152 | + txdesc->buffer_length = skb->len; | |
2133 | 2153 | |
2134 | 2154 | if (entry >= mdp->num_tx_ring - 1) |
2135 | 2155 | txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); |
... | ... | @@ -2181,7 +2201,13 @@ |
2181 | 2201 | |
2182 | 2202 | netif_stop_queue(ndev); |
2183 | 2203 | |
2184 | - /* 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); | |
2185 | 2211 | sh_eth_write(ndev, 0x0000, EESIPR); |
2186 | 2212 | |
2187 | 2213 | /* Stop the chip's Tx and Rx processes. */ |
... | ... | @@ -2197,8 +2223,6 @@ |
2197 | 2223 | } |
2198 | 2224 | |
2199 | 2225 | free_irq(ndev->irq, ndev); |
2200 | - | |
2201 | - napi_disable(&mdp->napi); | |
2202 | 2226 | |
2203 | 2227 | /* Free all the skbuffs in the Rx queue. */ |
2204 | 2228 | sh_eth_ring_free(ndev); |
drivers/net/ethernet/renesas/sh_eth.h