Skip to content

Commit e18b7fa

Browse files
committed
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>
2 parents a35165c + 4a0c081 commit e18b7fa

File tree

1 file changed

+56
-54
lines changed

1 file changed

+56
-54
lines changed

drivers/net/ethernet/broadcom/genet/bcmgenet.c

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
875875
int last_tx_cn, last_c_index, num_tx_bds;
876876
struct enet_cb *tx_cb_ptr;
877877
struct netdev_queue *txq;
878+
unsigned int bds_compl;
878879
unsigned int c_index;
879880

880881
/* Compute how many buffers are transmitted since last xmit call */
@@ -899,7 +900,9 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
899900
/* Reclaim transmitted buffers */
900901
while (last_tx_cn-- > 0) {
901902
tx_cb_ptr = ring->cbs + last_c_index;
903+
bds_compl = 0;
902904
if (tx_cb_ptr->skb) {
905+
bds_compl = skb_shinfo(tx_cb_ptr->skb)->nr_frags + 1;
903906
dev->stats.tx_bytes += tx_cb_ptr->skb->len;
904907
dma_unmap_single(&dev->dev,
905908
dma_unmap_addr(tx_cb_ptr, dma_addr),
@@ -916,7 +919,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
916919
dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0);
917920
}
918921
dev->stats.tx_packets++;
919-
ring->free_bds += 1;
922+
ring->free_bds += bds_compl;
920923

921924
last_c_index++;
922925
last_c_index &= (num_tx_bds - 1);
@@ -1741,13 +1744,63 @@ static void bcmgenet_init_multiq(struct net_device *dev)
17411744
bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
17421745
}
17431746

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+
17441798
static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
17451799
{
17461800
int i;
17471801

17481802
/* disable DMA */
1749-
bcmgenet_rdma_writel(priv, 0, DMA_CTRL);
1750-
bcmgenet_tdma_writel(priv, 0, DMA_CTRL);
1803+
bcmgenet_dma_teardown(priv);
17511804

17521805
for (i = 0; i < priv->num_tx_bds; i++) {
17531806
if (priv->tx_cbs[i].skb != NULL) {
@@ -2106,57 +2159,6 @@ static int bcmgenet_open(struct net_device *dev)
21062159
return ret;
21072160
}
21082161

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-
return ret;
2158-
}
2159-
21602162
static void bcmgenet_netif_stop(struct net_device *dev)
21612163
{
21622164
struct bcmgenet_priv *priv = netdev_priv(dev);

0 commit comments

Comments
 (0)