bmips: check for DMA error when refilling Rx
authorSieng-Piaw Liew <liew.s.piaw@gmail.com>
Tue, 19 Jul 2022 00:20:45 +0000 (08:20 +0800)
committerÁlvaro Fernández Rojas <noltari@gmail.com>
Sat, 4 Mar 2023 18:28:16 +0000 (19:28 +0100)
dma_mapping_error() should be called as dma_map_single() could fail and
return error.

Signed-off-by: Sieng-Piaw Liew <liew.s.piaw@gmail.com>
target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c

index c655ae8d27753106298d0bae151c98444bbab337..64736ebf61e181b3cfbcc973407cef5a852d6044 100644 (file)
@@ -270,6 +270,7 @@ static int bcm6368_enetsw_refill_rx(struct net_device *dev, bool napi_mode)
 
                if (!priv->rx_buf[desc_idx]) {
                        unsigned char *buf;
+                       dma_addr_t p;
 
                        if (likely(napi_mode))
                                buf = napi_alloc_frag(priv->rx_frag_size);
@@ -279,11 +280,15 @@ static int bcm6368_enetsw_refill_rx(struct net_device *dev, bool napi_mode)
                        if (unlikely(!buf))
                                break;
 
+                       p = dma_map_single(&priv->pdev->dev, buf + NET_SKB_PAD,
+                                          priv->rx_buf_size, DMA_FROM_DEVICE);
+                       if (unlikely(dma_mapping_error(&priv->pdev->dev, p))) {
+                               skb_free_frag(buf);
+                               break;
+                       }
+
                        priv->rx_buf[desc_idx] = buf;
-                       desc->address = dma_map_single(&priv->pdev->dev,
-                                                      buf + NET_SKB_PAD,
-                                                      priv->rx_buf_size,
-                                                      DMA_FROM_DEVICE);
+                       desc->address = p;
                }
 
                len_stat = priv->rx_buf_size << DMADESC_LENGTH_SHIFT;
@@ -563,6 +568,7 @@ bcm6368_enetsw_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct bcm6368_enetsw_desc *desc;
        u32 len_stat;
        netdev_tx_t ret;
+       dma_addr_t p;
 
        /* lock against tx reclaim */
        spin_lock(&priv->tx_lock);
@@ -597,13 +603,19 @@ bcm6368_enetsw_start_xmit(struct sk_buff *skb, struct net_device *dev)
                data = skb_put_zero(skb, needed);
        }
 
+       /* fill descriptor */
+       p = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
+                          DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(&priv->pdev->dev, p))) {
+               dev_kfree_skb(skb);
+               ret = NETDEV_TX_OK;
+               goto out_unlock;
+       }
+
        /* point to the next available desc */
        desc = &priv->tx_desc_cpu[priv->tx_curr_desc];
        priv->tx_skb[priv->tx_curr_desc] = skb;
-
-       /* fill descriptor */
-       desc->address = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
-                                      DMA_TO_DEVICE);
+       desc->address = p;
 
        len_stat = (skb->len << DMADESC_LENGTH_SHIFT) & DMADESC_LENGTH_MASK;
        len_stat |= DMADESC_ESOP_MASK | DMADESC_APPEND_CRC |