diff options
author | David S. Miller <davem@davemloft.net> | 2014-11-01 22:14:07 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-01 22:14:07 +0300 |
commit | 1868855798b1a1b413bf823f21fa798f176195b7 (patch) | |
tree | d5ffafa66836552fa4cc7c64163a31b4ad615590 | |
parent | 437374735c0055433f8300ba59f8cf7214c58ad3 (diff) | |
parent | 914adb55afbc7e449512f609de19e548d1054480 (diff) | |
download | linux-1868855798b1a1b413bf823f21fa798f176195b7.tar.xz |
Merge branch 'systemport-net'
Florian Fainelli says:
====================
net: systemport: TX dma fixes
This patch series contains two fixes for our transmit path, first one
is a pretty nasty one since we were not allocating a large enough
dma coherent pool for our transmit descriptors, which would work most of the
time, since allocations are contiguous and we could have.
Second patch fixes a less frequent, though highly likley crash when using
CMA allocations.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bcmsysport.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 3a6778a667f4..531bb7c57531 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1110,7 +1110,8 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, /* We just need one DMA descriptor which is DMA-able, since writing to * the port will allocate a new descriptor in its internal linked-list */ - p = dma_zalloc_coherent(kdev, 1, &ring->desc_dma, GFP_KERNEL); + p = dma_zalloc_coherent(kdev, sizeof(struct dma_desc), &ring->desc_dma, + GFP_KERNEL); if (!p) { netif_err(priv, hw, priv->netdev, "DMA alloc failed\n"); return -ENOMEM; @@ -1174,6 +1175,13 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv, if (!(reg & TDMA_DISABLED)) netdev_warn(priv->netdev, "TDMA not stopped!\n"); + /* ring->cbs is the last part in bcm_sysport_init_tx_ring which could + * fail, so by checking this pointer we know whether the TX ring was + * fully initialized or not. + */ + if (!ring->cbs) + return; + napi_disable(&ring->napi); netif_napi_del(&ring->napi); @@ -1183,7 +1191,8 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv, ring->cbs = NULL; if (ring->desc_dma) { - dma_free_coherent(kdev, 1, ring->desc_cpu, ring->desc_dma); + dma_free_coherent(kdev, sizeof(struct dma_desc), + ring->desc_cpu, ring->desc_dma); ring->desc_dma = 0; } ring->size = 0; |