Hi Florian

I was looking at drivers/net/ethernet/broadcom/genet/bcmgenet.c
and found TX completion (__bcmgenet_tx_reclaim()) was freeing skb before
frags were actually dma unmapped.


Are you sure this is OK ? bnx2 and bnx2x actually do the reverse (unmap
all frags before freeing skb)

A second problem is the dma_unmap_single() uses tx_cb_ptr->skb->len for
the length, while it really should be the same thing that was used in
bcmgenet_xmit_single()

skb_len = skb_headlen(skb) < ETH_ZLEN ? ETH_ZLEN : skb_headlen(skb);

So maybe something like :

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c 
b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index d7e01a7..9211b9c7 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1197,7 +1197,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct 
net_device *dev,
                        dev->stats.tx_bytes += tx_cb_ptr->skb->len;
                        dma_unmap_single(&dev->dev,
                                         dma_unmap_addr(tx_cb_ptr, dma_addr),
-                                        tx_cb_ptr->skb->len,
+                                        dma_unmap_len(tx_cb_ptr, dma_len),
                                         DMA_TO_DEVICE);
                        bcmgenet_free_cb(tx_cb_ptr);
                } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
@@ -1308,7 +1308,7 @@ static int bcmgenet_xmit_single(struct net_device *dev,
        }
 
        dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
-       dma_unmap_len_set(tx_cb_ptr, dma_len, skb->len);
+       dma_unmap_len_set(tx_cb_ptr, dma_len, skb_len);
        length_status = (skb_len << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
                        (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT) |
                        DMA_TX_APPEND_CRC;


Reply via email to