aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2014-09-22 14:54:43 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-22 18:38:40 -0400
commit4a0c081eff43a11c65dee3ad6c457f7f58bcebe0 (patch)
tree055ff5d64bf6a601eb5165c0820fcb18db998121
parent478a010c9235ca92e66cc5058b42e30e33275ad4 (diff)
net: bcmgenet: call bcmgenet_dma_teardown in bcmgenet_fini_dma
We should not be manipulaging the DMA_CTRL registers directly by writing 0 to them to disable DMA. This is an operation that needs to be timed to make sure the DMA engines have been properly stopped since their state machine stops on a packet boundary, not immediately. Make sure that tha bcmgenet_fini_dma() calls bcmgenet_dma_teardown() to ensure a proper DMA engine state. As a result, we need to reorder the function bodies to resolve the use dependency. Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c105
1 files changed, 52 insertions, 53 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 11a96437862d..5cc9cae21ed5 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1744,13 +1744,63 @@ static void bcmgenet_init_multiq(struct net_device *dev)
1744 bcmgenet_tdma_writel(priv, reg, DMA_CTRL); 1744 bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
1745} 1745}
1746 1746
1747static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
1748{
1749 int ret = 0;
1750 int timeout = 0;
1751 u32 reg;
1752
1753 /* Disable TDMA to stop add more frames in TX DMA */
1754 reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
1755 reg &= ~DMA_EN;
1756 bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
1757
1758 /* Check TDMA status register to confirm TDMA is disabled */
1759 while (timeout++ < DMA_TIMEOUT_VAL) {
1760 reg = bcmgenet_tdma_readl(priv, DMA_STATUS);
1761 if (reg & DMA_DISABLED)
1762 break;
1763
1764 udelay(1);
1765 }
1766
1767 if (timeout == DMA_TIMEOUT_VAL) {
1768 netdev_warn(priv->dev, "Timed out while disabling TX DMA\n");
1769 ret = -ETIMEDOUT;
1770 }
1771
1772 /* Wait 10ms for packet drain in both tx and rx dma */
1773 usleep_range(10000, 20000);
1774
1775 /* Disable RDMA */
1776 reg = bcmgenet_rdma_readl(priv, DMA_CTRL);
1777 reg &= ~DMA_EN;
1778 bcmgenet_rdma_writel(priv, reg, DMA_CTRL);
1779
1780 timeout = 0;
1781 /* Check RDMA status register to confirm RDMA is disabled */
1782 while (timeout++ < DMA_TIMEOUT_VAL) {
1783 reg = bcmgenet_rdma_readl(priv, DMA_STATUS);
1784 if (reg & DMA_DISABLED)
1785 break;
1786
1787 udelay(1);
1788 }
1789
1790 if (timeout == DMA_TIMEOUT_VAL) {
1791 netdev_warn(priv->dev, "Timed out while disabling RX DMA\n");
1792 ret = -ETIMEDOUT;
1793 }
1794
1795 return ret;
1796}
1797
1747static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) 1798static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
1748{ 1799{
1749 int i; 1800 int i;
1750 1801
1751 /* disable DMA */ 1802 /* disable DMA */
1752 bcmgenet_rdma_writel(priv, 0, DMA_CTRL); 1803 bcmgenet_dma_teardown(priv);
1753 bcmgenet_tdma_writel(priv, 0, DMA_CTRL);
1754 1804
1755 for (i = 0; i < priv->num_tx_bds; i++) { 1805 for (i = 0; i < priv->num_tx_bds; i++) {
1756 if (priv->tx_cbs[i].skb != NULL) { 1806 if (priv->tx_cbs[i].skb != NULL) {
@@ -2109,57 +2159,6 @@ err_clk_disable:
2109 return ret; 2159 return ret;
2110} 2160}
2111 2161
2112static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
2113{
2114 int ret = 0;
2115 int timeout = 0;
2116 u32 reg;
2117
2118 /* Disable TDMA to stop add more frames in TX DMA */
2119 reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
2120 reg &= ~DMA_EN;
2121 bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
2122
2123 /* Check TDMA status register to confirm TDMA is disabled */
2124 while (timeout++ < DMA_TIMEOUT_VAL) {
2125 reg = bcmgenet_tdma_readl(priv, DMA_STATUS);
2126 if (reg & DMA_DISABLED)
2127 break;
2128
2129 udelay(1);
2130 }
2131
2132 if (timeout == DMA_TIMEOUT_VAL) {
2133 netdev_warn(priv->dev, "Timed out while disabling TX DMA\n");
2134 ret = -ETIMEDOUT;
2135 }
2136
2137 /* Wait 10ms for packet drain in both tx and rx dma */
2138 usleep_range(10000, 20000);
2139
2140 /* Disable RDMA */
2141 reg = bcmgenet_rdma_readl(priv, DMA_CTRL);
2142 reg &= ~DMA_EN;
2143 bcmgenet_rdma_writel(priv, reg, DMA_CTRL);
2144
2145 timeout = 0;
2146 /* Check RDMA status register to confirm RDMA is disabled */
2147 while (timeout++ < DMA_TIMEOUT_VAL) {
2148 reg = bcmgenet_rdma_readl(priv, DMA_STATUS);
2149 if (reg & DMA_DISABLED)
2150 break;
2151
2152 udelay(1);
2153 }
2154
2155 if (timeout == DMA_TIMEOUT_VAL) {
2156 netdev_warn(priv->dev, "Timed out while disabling RX DMA\n");
2157 ret = -ETIMEDOUT;
2158 }
2159
2160 return ret;
2161}
2162
2163static void bcmgenet_netif_stop(struct net_device *dev) 2162static void bcmgenet_netif_stop(struct net_device *dev)
2164{ 2163{
2165 struct bcmgenet_priv *priv = netdev_priv(dev); 2164 struct bcmgenet_priv *priv = netdev_priv(dev);