aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEsben Haabendal <esben@geanix.com>2019-04-30 03:17:50 -0400
committerDavid S. Miller <davem@davemloft.net>2019-05-01 14:33:30 -0400
commitd84aec42151b489c4ca6e342ff5233c4789f5b90 (patch)
tree963be7d72aed6fd13dee5f9811ff61c811ea886d
parent8425c41d1ef762cc15d9501d7117f009a79f3fe9 (diff)
net: ll_temac: Fix support for 64-bit platforms
The use of buffer descriptor APP4 field (32-bit) for storing skb pointer obviously does not work on 64-bit platforms. As APP3 is also unused, we can use that to store the other half of 64-bit pointer values. Contrary to what is hinted at in commit message of commit 15bfe05c8d63 ("net: ethernet: xilinx: Mark XILINX_LL_TEMAC broken on 64-bit") there are no other pointers stored in cdmac_bd. Signed-off-by: Esben Haabendal <esben@geanix.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/xilinx/Kconfig1
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac_main.c35
2 files changed, 32 insertions, 4 deletions
diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig
index da4ec575ccf9..6d68c8a8f4f2 100644
--- a/drivers/net/ethernet/xilinx/Kconfig
+++ b/drivers/net/ethernet/xilinx/Kconfig
@@ -34,7 +34,6 @@ config XILINX_AXI_EMAC
34config XILINX_LL_TEMAC 34config XILINX_LL_TEMAC
35 tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" 35 tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
36 depends on (PPC || MICROBLAZE) 36 depends on (PPC || MICROBLAZE)
37 depends on !64BIT || BROKEN
38 select PHYLIB 37 select PHYLIB
39 ---help--- 38 ---help---
40 This driver supports the Xilinx 10/100/1000 LocalLink TEMAC 39 This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index fddd1b3ac194..bcafb8925f75 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -619,11 +619,39 @@ static void temac_adjust_link(struct net_device *ndev)
619 mutex_unlock(&lp->indirect_mutex); 619 mutex_unlock(&lp->indirect_mutex);
620} 620}
621 621
622#ifdef CONFIG_64BIT
623
624void ptr_to_txbd(void *p, struct cdmac_bd *bd)
625{
626 bd->app3 = (u32)(((u64)p) >> 32);
627 bd->app4 = (u32)((u64)p & 0xFFFFFFFF);
628}
629
630void *ptr_from_txbd(struct cdmac_bd *bd)
631{
632 return (void *)(((u64)(bd->app3) << 32) | bd->app4);
633}
634
635#else
636
637void ptr_to_txbd(void *p, struct cmdac_bd *bd)
638{
639 bd->app4 = (u32)p;
640}
641
642void *ptr_from_txbd(struct cdmac_bd *bd)
643{
644 return (void *)(bd->app4);
645}
646
647#endif
648
622static void temac_start_xmit_done(struct net_device *ndev) 649static void temac_start_xmit_done(struct net_device *ndev)
623{ 650{
624 struct temac_local *lp = netdev_priv(ndev); 651 struct temac_local *lp = netdev_priv(ndev);
625 struct cdmac_bd *cur_p; 652 struct cdmac_bd *cur_p;
626 unsigned int stat = 0; 653 unsigned int stat = 0;
654 struct sk_buff *skb;
627 655
628 cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; 656 cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
629 stat = cur_p->app0; 657 stat = cur_p->app0;
@@ -631,8 +659,9 @@ static void temac_start_xmit_done(struct net_device *ndev)
631 while (stat & STS_CTRL_APP0_CMPLT) { 659 while (stat & STS_CTRL_APP0_CMPLT) {
632 dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len, 660 dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len,
633 DMA_TO_DEVICE); 661 DMA_TO_DEVICE);
634 if (cur_p->app4) 662 skb = (struct sk_buff *)ptr_from_txbd(cur_p);
635 dev_consume_skb_irq((struct sk_buff *)cur_p->app4); 663 if (skb)
664 dev_consume_skb_irq(skb);
636 cur_p->app0 = 0; 665 cur_p->app0 = 0;
637 cur_p->app1 = 0; 666 cur_p->app1 = 0;
638 cur_p->app2 = 0; 667 cur_p->app2 = 0;
@@ -711,7 +740,7 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
711 cur_p->len = skb_headlen(skb); 740 cur_p->len = skb_headlen(skb);
712 cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, 741 cur_p->phys = dma_map_single(ndev->dev.parent, skb->data,
713 skb_headlen(skb), DMA_TO_DEVICE); 742 skb_headlen(skb), DMA_TO_DEVICE);
714 cur_p->app4 = (unsigned long)skb; 743 ptr_to_txbd((void *)skb, cur_p);
715 744
716 for (ii = 0; ii < num_frag; ii++) { 745 for (ii = 0; ii < num_frag; ii++) {
717 lp->tx_bd_tail++; 746 lp->tx_bd_tail++;