Commit e18b7faae15dbd47e5811ed748bd5b500dcfaa2d

Authored by David S. Miller

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>

Showing 1 changed file Side-by-side Diff

drivers/net/ethernet/broadcom/genet/bcmgenet.c
... ... @@ -875,6 +875,7 @@
875 875 int last_tx_cn, last_c_index, num_tx_bds;
876 876 struct enet_cb *tx_cb_ptr;
877 877 struct netdev_queue *txq;
  878 + unsigned int bds_compl;
878 879 unsigned int c_index;
879 880  
880 881 /* Compute how many buffers are transmitted since last xmit call */
881 882  
... ... @@ -899,7 +900,9 @@
899 900 /* Reclaim transmitted buffers */
900 901 while (last_tx_cn-- > 0) {
901 902 tx_cb_ptr = ring->cbs + last_c_index;
  903 + bds_compl = 0;
902 904 if (tx_cb_ptr->skb) {
  905 + bds_compl = skb_shinfo(tx_cb_ptr->skb)->nr_frags + 1;
903 906 dev->stats.tx_bytes += tx_cb_ptr->skb->len;
904 907 dma_unmap_single(&dev->dev,
905 908 dma_unmap_addr(tx_cb_ptr, dma_addr),
... ... @@ -916,7 +919,7 @@
916 919 dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0);
917 920 }
918 921 dev->stats.tx_packets++;
919   - ring->free_bds += 1;
  922 + ring->free_bds += bds_compl;
920 923  
921 924 last_c_index++;
922 925 last_c_index &= (num_tx_bds - 1);
923 926  
... ... @@ -1741,13 +1744,63 @@
1741 1744 bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
1742 1745 }
1743 1746  
  1747 +static 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 +
1744 1798 static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
1745 1799 {
1746 1800 int i;
1747 1801  
1748 1802 /* disable DMA */
1749   - bcmgenet_rdma_writel(priv, 0, DMA_CTRL);
1750   - bcmgenet_tdma_writel(priv, 0, DMA_CTRL);
  1803 + bcmgenet_dma_teardown(priv);
1751 1804  
1752 1805 for (i = 0; i < priv->num_tx_bds; i++) {
1753 1806 if (priv->tx_cbs[i].skb != NULL) {
... ... @@ -2103,57 +2156,6 @@
2103 2156 err_clk_disable:
2104 2157 if (!IS_ERR(priv->clk))
2105 2158 clk_disable_unprepare(priv->clk);
2106   - return ret;
2107   -}
2108   -
2109   -static 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 2159 return ret;
2158 2160 }
2159 2161