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: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3e2309937f
commit
1299653aff
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
/* 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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user