浏览代码

sh_eth: advance 'rxdesc' later in sh_eth_ring_format()

Iff dma_map_single() fails, 'rxdesc'  should point  to the last filled RX
descriptor, so  that it can be marked as the last one, however the driver
would have  already  advanced it by that time. In order to fix that, only
fill  an RX descriptor  once all the data for it is ready.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Sergei Shtylyov 9 年之前
父节点
当前提交
d0ba913488
共有 1 个文件被更改,包括 4 次插入3 次删除
  1. 4 3
      drivers/net/ethernet/renesas/sh_eth.c

+ 4 - 3
drivers/net/ethernet/renesas/sh_eth.c

@@ -1127,11 +1127,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
 			break;
 			break;
 		sh_eth_set_receive_align(skb);
 		sh_eth_set_receive_align(skb);
 
 
-		/* RX descriptor */
-		rxdesc = &mdp->rx_ring[i];
 		/* The size of the buffer is a multiple of 32 bytes. */
 		/* The size of the buffer is a multiple of 32 bytes. */
 		buf_len = ALIGN(mdp->rx_buf_sz, 32);
 		buf_len = ALIGN(mdp->rx_buf_sz, 32);
-		rxdesc->len = cpu_to_le32(buf_len << 16);
 		dma_addr = dma_map_single(&ndev->dev, skb->data, buf_len,
 		dma_addr = dma_map_single(&ndev->dev, skb->data, buf_len,
 					  DMA_FROM_DEVICE);
 					  DMA_FROM_DEVICE);
 		if (dma_mapping_error(&ndev->dev, dma_addr)) {
 		if (dma_mapping_error(&ndev->dev, dma_addr)) {
@@ -1139,6 +1136,10 @@ static void sh_eth_ring_format(struct net_device *ndev)
 			break;
 			break;
 		}
 		}
 		mdp->rx_skbuff[i] = skb;
 		mdp->rx_skbuff[i] = skb;
+
+		/* RX descriptor */
+		rxdesc = &mdp->rx_ring[i];
+		rxdesc->len = cpu_to_le32(buf_len << 16);
 		rxdesc->addr = cpu_to_le32(dma_addr);
 		rxdesc->addr = cpu_to_le32(dma_addr);
 		rxdesc->status = cpu_to_le32(RD_RACT | RD_RFP);
 		rxdesc->status = cpu_to_le32(RD_RACT | RD_RFP);