aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-09-22 18:38:53 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-22 18:38:53 -0400
commite18b7faae15dbd47e5811ed748bd5b500dcfaa2d (patch)
tree055ff5d64bf6a601eb5165c0820fcb18db998121
parenta35165ca101695aa2cc5a6300ef69ae60be39a49 (diff)
parent4a0c081eff43a11c65dee3ad6c457f7f58bcebe0 (diff)
Merge branch 'bcmgenet'
Florian Fainelli says: ==================== net: bcmgenet: TX reclaim and DMA fixes This patch set contains one fix for an accounting problem while reclaiming transmitted buffers having fragments, and the second fix is to make sure that the DMA shutdown is properly controlled. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c110
1 files changed, 56 insertions, 54 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index cdef86a03862..5cc9cae21ed5 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -875,6 +875,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
875 int last_tx_cn, last_c_index, num_tx_bds; 875 int last_tx_cn, last_c_index, num_tx_bds;
876 struct enet_cb *tx_cb_ptr; 876 struct enet_cb *tx_cb_ptr;
877 struct netdev_queue *txq; 877 struct netdev_queue *txq;
878 unsigned int bds_compl;
878 unsigned int c_index; 879 unsigned int c_index;
879 880
880 /* Compute how many buffers are transmitted since last xmit call */ 881 /* Compute how many buffers are transmitted since last xmit call */
@@ -899,7 +900,9 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
899 /* Reclaim transmitted buffers */ 900 /* Reclaim transmitted buffers */
900 while (last_tx_cn-- > 0) { 901 while (last_tx_cn-- > 0) {
901 tx_cb_ptr = ring->cbs + last_c_index; 902 tx_cb_ptr = ring->cbs + last_c_index;
903 bds_compl = 0;
902 if (tx_cb_ptr->skb) { 904 if (tx_cb_ptr->skb) {
905 bds_compl = skb_shinfo(tx_cb_ptr->skb)->nr_frags + 1;
903 dev->stats.tx_bytes += tx_cb_ptr->skb->len; 906 dev->stats.tx_bytes += tx_cb_ptr->skb->len;
904 dma_unmap_single(&dev->dev, 907 dma_unmap_single(&dev->dev,
905 dma_unmap_addr(tx_cb_ptr, dma_addr), 908 dma_unmap_addr(tx_cb_ptr, dma_addr),
@@ -916,7 +919,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
916 dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0); 919 dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0);
917 } 920 }
918 dev->stats.tx_packets++; 921 dev->stats.tx_packets++;
919 ring->free_bds += 1; 922 ring->free_bds += bds_compl;
920 923
921 last_c_index++; 924 last_c_index++;
922 last_c_index &= (num_tx_bds - 1); 925 last_c_index &= (num_tx_bds - 1);
@@ -1741,13 +1744,63 @@ static void bcmgenet_init_multiq(struct net_device *dev)
1741 bcmgenet_tdma_writel(priv, reg, DMA_CTRL); 1744 bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
1742} 1745}
1743 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
1744static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) 1798static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
1745{ 1799{
1746 int i; 1800 int i;
1747 1801
1748 /* disable DMA */ 1802 /* disable DMA */
1749 bcmgenet_rdma_writel(priv, 0, DMA_CTRL); 1803 bcmgenet_dma_teardown(priv);
1750 bcmgenet_tdma_writel(priv, 0, DMA_CTRL);
1751 1804
1752 for (i = 0; i < priv->num_tx_bds; i++) { 1805 for (i = 0; i < priv->num_tx_bds; i++) {
1753 if (priv->tx_cbs[i].skb != NULL) { 1806 if (priv->tx_cbs[i].skb != NULL) {
@@ -2106,57 +2159,6 @@ err_clk_disable:
2106 return ret; 2159 return ret;
2107} 2160}
2108 2161
2109static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
2110{
2111 int ret = 0;
2112 int timeout = 0;
2113 u32 reg;
2114
2115 /* Disable TDMA to stop add more frames in TX DMA */
2116 reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
2117 reg &= ~DMA_EN;
2118 bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
2119
2120 /* Check TDMA status register to confirm TDMA is disabled */
2121 while (timeout++ < DMA_TIMEOUT_VAL) {
2122 reg = bcmgenet_tdma_readl(priv, DMA_STATUS);
2123 if (reg & DMA_DISABLED)
2124 break;
2125
2126 udelay(1);
2127 }
2128
2129 if (timeout == DMA_TIMEOUT_VAL) {
2130 netdev_warn(priv->dev, "Timed out while disabling TX DMA\n");
2131 ret = -ETIMEDOUT;
2132 }
2133
2134 /* Wait 10ms for packet drain in both tx and rx dma */
2135 usleep_range(10000, 20000);
2136
2137 /* Disable RDMA */
2138 reg = bcmgenet_rdma_readl(priv, DMA_CTRL);
2139 reg &= ~DMA_EN;
2140 bcmgenet_rdma_writel(priv, reg, DMA_CTRL);
2141
2142 timeout = 0;
2143 /* Check RDMA status register to confirm RDMA is disabled */
2144 while (timeout++ < DMA_TIMEOUT_VAL) {
2145 reg = bcmgenet_rdma_readl(priv, DMA_STATUS);
2146 if (reg & DMA_DISABLED)
2147 break;
2148
2149 udelay(1);
2150 }
2151
2152 if (timeout == DMA_TIMEOUT_VAL) {
2153 netdev_warn(priv->dev, "Timed out while disabling RX DMA\n");
2154 ret = -ETIMEDOUT;
2155 }
2156
2157 return ret;
2158}
2159
2160static void bcmgenet_netif_stop(struct net_device *dev) 2162static void bcmgenet_netif_stop(struct net_device *dev)
2161{ 2163{
2162 struct bcmgenet_priv *priv = netdev_priv(dev); 2164 struct bcmgenet_priv *priv = netdev_priv(dev);