提交 1299653a 编写于 作者: S Sergei Shtylyov 提交者: David S. Miller

sh_eth: fix descriptor access endianness

The driver never  calls cpu_to_edmac() when writing the descriptor address
and edmac_to_cpu() when reading it, although it should -- fix this.

Note that the frame/buffer length descriptor field accesses also need fixing
but since they are both 16-bit we can't  use {cpu|edmac}_to_{edmac|cpu}()...
Signed-off-by: NSergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 3e230993
...@@ -1196,7 +1196,7 @@ static void sh_eth_ring_format(struct net_device *ndev) ...@@ -1196,7 +1196,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
break; break;
} }
mdp->rx_skbuff[i] = skb; mdp->rx_skbuff[i] = skb;
rxdesc->addr = dma_addr; rxdesc->addr = cpu_to_edmac(mdp, dma_addr);
rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
/* Rx descriptor address set */ /* Rx descriptor address set */
...@@ -1427,7 +1427,8 @@ static int sh_eth_txfree(struct net_device *ndev) ...@@ -1427,7 +1427,8 @@ static int sh_eth_txfree(struct net_device *ndev)
entry, edmac_to_cpu(mdp, txdesc->status)); entry, edmac_to_cpu(mdp, txdesc->status));
/* Free the original skb. */ /* Free the original skb. */
if (mdp->tx_skbuff[entry]) { if (mdp->tx_skbuff[entry]) {
dma_unmap_single(&ndev->dev, txdesc->addr, dma_unmap_single(&ndev->dev,
edmac_to_cpu(mdp, txdesc->addr),
txdesc->buffer_length, DMA_TO_DEVICE); txdesc->buffer_length, DMA_TO_DEVICE);
dev_kfree_skb_irq(mdp->tx_skbuff[entry]); dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
mdp->tx_skbuff[entry] = NULL; mdp->tx_skbuff[entry] = NULL;
...@@ -1503,14 +1504,15 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) ...@@ -1503,14 +1504,15 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
if (desc_status & RD_RFS10) if (desc_status & RD_RFS10)
ndev->stats.rx_over_errors++; ndev->stats.rx_over_errors++;
} else if (skb) { } else if (skb) {
dma_addr = edmac_to_cpu(mdp, rxdesc->addr);
if (!mdp->cd->hw_swap) if (!mdp->cd->hw_swap)
sh_eth_soft_swap( sh_eth_soft_swap(
phys_to_virt(ALIGN(rxdesc->addr, 4)), phys_to_virt(ALIGN(dma_addr, 4)),
pkt_len + 2); pkt_len + 2);
mdp->rx_skbuff[entry] = NULL; mdp->rx_skbuff[entry] = NULL;
if (mdp->cd->rpadir) if (mdp->cd->rpadir)
skb_reserve(skb, NET_IP_ALIGN); skb_reserve(skb, NET_IP_ALIGN);
dma_unmap_single(&ndev->dev, rxdesc->addr, dma_unmap_single(&ndev->dev, dma_addr,
ALIGN(mdp->rx_buf_sz, 32), ALIGN(mdp->rx_buf_sz, 32),
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
skb_put(skb, pkt_len); skb_put(skb, pkt_len);
...@@ -1547,7 +1549,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) ...@@ -1547,7 +1549,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
mdp->rx_skbuff[entry] = skb; mdp->rx_skbuff[entry] = skb;
skb_checksum_none_assert(skb); skb_checksum_none_assert(skb);
rxdesc->addr = dma_addr; rxdesc->addr = cpu_to_edmac(mdp, dma_addr);
} }
dma_wmb(); /* RACT bit must be set after all the above writes */ dma_wmb(); /* RACT bit must be set after all the above writes */
if (entry >= mdp->num_rx_ring - 1) if (entry >= mdp->num_rx_ring - 1)
...@@ -2355,8 +2357,8 @@ static void sh_eth_tx_timeout(struct net_device *ndev) ...@@ -2355,8 +2357,8 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
/* Free all the skbuffs in the Rx queue. */ /* Free all the skbuffs in the Rx queue. */
for (i = 0; i < mdp->num_rx_ring; i++) { for (i = 0; i < mdp->num_rx_ring; i++) {
rxdesc = &mdp->rx_ring[i]; rxdesc = &mdp->rx_ring[i];
rxdesc->status = 0; rxdesc->status = cpu_to_edmac(mdp, 0);
rxdesc->addr = 0xBADF00D0; rxdesc->addr = cpu_to_edmac(mdp, 0xBADF00D0);
dev_kfree_skb(mdp->rx_skbuff[i]); dev_kfree_skb(mdp->rx_skbuff[i]);
mdp->rx_skbuff[i] = NULL; mdp->rx_skbuff[i] = NULL;
} }
...@@ -2374,6 +2376,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -2374,6 +2376,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{ {
struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_txdesc *txdesc; struct sh_eth_txdesc *txdesc;
dma_addr_t dma_addr;
u32 entry; u32 entry;
unsigned long flags; unsigned long flags;
...@@ -2397,12 +2400,13 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -2397,12 +2400,13 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
/* soft swap. */ /* soft swap. */
if (!mdp->cd->hw_swap) if (!mdp->cd->hw_swap)
sh_eth_soft_swap(PTR_ALIGN(skb->data, 4), skb->len + 2); sh_eth_soft_swap(PTR_ALIGN(skb->data, 4), skb->len + 2);
txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, dma_addr = dma_map_single(&ndev->dev, skb->data, skb->len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (dma_mapping_error(&ndev->dev, txdesc->addr)) { if (dma_mapping_error(&ndev->dev, dma_addr)) {
kfree_skb(skb); kfree_skb(skb);
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
txdesc->addr = cpu_to_edmac(mdp, dma_addr);
txdesc->buffer_length = skb->len; txdesc->buffer_length = skb->len;
dma_wmb(); /* TACT bit must be set after all the above writes */ dma_wmb(); /* TACT bit must be set after all the above writes */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册