| From 20e09b61cd6104c54e51ae9658afbb8494a632c8 Mon Sep 17 00:00:00 2001 |
| From: Esben Haabendal <esben@geanix.com> |
| Date: Fri, 21 Feb 2020 07:47:33 +0100 |
| Subject: [PATCH] net: ll_temac: Add more error handling of dma_map_single() |
| calls |
| |
| commit d07c849cd2b97d6809430dfb7e738ad31088037a upstream. |
| |
| This adds error handling to the remaining dma_map_single() calls, so that |
| behavior is well defined if/when we run out of DMA memory. |
| |
| Fixes: 92744989533c ("net: add Xilinx ll_temac device driver") |
| Signed-off-by: Esben Haabendal <esben@geanix.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c |
| index 2053001fc36e..cb738a73c064 100644 |
| --- a/drivers/net/ethernet/xilinx/ll_temac_main.c |
| +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c |
| @@ -300,6 +300,8 @@ static int temac_dma_bd_init(struct net_device *ndev) |
| skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, |
| XTE_MAX_JUMBO_FRAME_SIZE, |
| DMA_FROM_DEVICE); |
| + if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) |
| + goto out; |
| lp->rx_bd_v[i].phys = cpu_to_be32(skb_dma_addr); |
| lp->rx_bd_v[i].len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); |
| lp->rx_bd_v[i].app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); |
| @@ -779,12 +781,13 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
| skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, |
| skb_headlen(skb), DMA_TO_DEVICE); |
| cur_p->len = cpu_to_be32(skb_headlen(skb)); |
| + if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, skb_dma_addr))) |
| + return NETDEV_TX_BUSY; |
| cur_p->phys = cpu_to_be32(skb_dma_addr); |
| ptr_to_txbd((void *)skb, cur_p); |
| |
| for (ii = 0; ii < num_frag; ii++) { |
| - lp->tx_bd_tail++; |
| - if (lp->tx_bd_tail >= TX_BD_NUM) |
| + if (++lp->tx_bd_tail >= TX_BD_NUM) |
| lp->tx_bd_tail = 0; |
| |
| cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
| @@ -792,6 +795,25 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
| skb_frag_address(frag), |
| skb_frag_size(frag), |
| DMA_TO_DEVICE); |
| + if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) { |
| + if (--lp->tx_bd_tail < 0) |
| + lp->tx_bd_tail = TX_BD_NUM - 1; |
| + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
| + while (--ii >= 0) { |
| + --frag; |
| + dma_unmap_single(ndev->dev.parent, |
| + be32_to_cpu(cur_p->phys), |
| + skb_frag_size(frag), |
| + DMA_TO_DEVICE); |
| + if (--lp->tx_bd_tail < 0) |
| + lp->tx_bd_tail = TX_BD_NUM - 1; |
| + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
| + } |
| + dma_unmap_single(ndev->dev.parent, |
| + be32_to_cpu(cur_p->phys), |
| + skb_headlen(skb), DMA_TO_DEVICE); |
| + return NETDEV_TX_BUSY; |
| + } |
| cur_p->phys = cpu_to_be32(skb_dma_addr); |
| cur_p->len = cpu_to_be32(skb_frag_size(frag)); |
| cur_p->app0 = 0; |
| -- |
| 2.7.4 |
| |