aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
authorMichal Schmidt <mschmidt@redhat.com>2014-01-09 08:36:27 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-06 14:08:16 -0500
commit4369fa25d4499e63368b39523698d936b75f65fd (patch)
treed092916b097bcbdff0d8ca1a5ce12982f291dacc /drivers/net/ethernet/broadcom
parent759ebfb44b87339bb43c2674b7ab9816ffc37b7a (diff)
bnx2x: fix DMA unmapping of TSO split BDs
[ Upstream commit 95e92fd40c967c363ad66b2fd1ce4dcd68132e54 ] bnx2x triggers warnings with CONFIG_DMA_API_DEBUG=y: WARNING: CPU: 0 PID: 2253 at lib/dma-debug.c:887 check_unmap+0xf8/0x920() bnx2x 0000:28:00.0: DMA-API: device driver frees DMA memory with different size [device address=0x00000000da2b389e] [map size=1490 bytes] [unmap size=66 bytes] The reason is that bnx2x splits a TSO BD into two BDs (headers + data) using one DMA mapping for both, but it uses only the length of the first BD when unmapping. This patch fixes the bug by unmapping the whole length of the two BDs. Signed-off-by: Michal Schmidt <mschmidt@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Acked-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 8c4babc0efbd..70be100feeb4 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -153,6 +153,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
153 struct sk_buff *skb = tx_buf->skb; 153 struct sk_buff *skb = tx_buf->skb;
154 u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons; 154 u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
155 int nbd; 155 int nbd;
156 u16 split_bd_len = 0;
156 157
157 /* prefetch skb end pointer to speedup dev_kfree_skb() */ 158 /* prefetch skb end pointer to speedup dev_kfree_skb() */
158 prefetch(&skb->end); 159 prefetch(&skb->end);
@@ -160,10 +161,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
160 DP(NETIF_MSG_TX_DONE, "fp[%d]: pkt_idx %d buff @(%p)->skb %p\n", 161 DP(NETIF_MSG_TX_DONE, "fp[%d]: pkt_idx %d buff @(%p)->skb %p\n",
161 txdata->txq_index, idx, tx_buf, skb); 162 txdata->txq_index, idx, tx_buf, skb);
162 163
163 /* unmap first bd */
164 tx_start_bd = &txdata->tx_desc_ring[bd_idx].start_bd; 164 tx_start_bd = &txdata->tx_desc_ring[bd_idx].start_bd;
165 dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
166 BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE);
167 165
168 166
169 nbd = le16_to_cpu(tx_start_bd->nbd) - 1; 167 nbd = le16_to_cpu(tx_start_bd->nbd) - 1;
@@ -182,12 +180,19 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
182 --nbd; 180 --nbd;
183 bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); 181 bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
184 182
185 /* ...and the TSO split header bd since they have no mapping */ 183 /* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */
186 if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) { 184 if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
185 tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
186 split_bd_len = BD_UNMAP_LEN(tx_data_bd);
187 --nbd; 187 --nbd;
188 bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); 188 bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
189 } 189 }
190 190
191 /* unmap first bd */
192 dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
193 BD_UNMAP_LEN(tx_start_bd) + split_bd_len,
194 DMA_TO_DEVICE);
195
191 /* now free frags */ 196 /* now free frags */
192 while (nbd > 0) { 197 while (nbd > 0) {
193 198