ath25: eth: fix crash on skb DMA (un-)map
authorSergey Ryazanov <ryazanov.s.a@gmail.com>
Fri, 4 Sep 2020 23:51:31 +0000 (02:51 +0300)
committerAdrian Schmutzler <freifunk@adrianschmutzler.de>
Sun, 6 Sep 2020 17:49:43 +0000 (19:49 +0200)
AR2315 Ethernet driver pass NULL instead of a real device pointer to DMA
(un-)map calls. With kernel version 5.4 such behaviour causes a kernel
panic. Fix this issue by preserving device pointer during the probe
procedure and pass it to each skb data DMA (un-)map call.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
target/linux/ath25/patches-5.4/110-ar2313_ethernet.patch
target/linux/ath25/patches-5.4/220-enet_micrel_workaround.patch

index e4f5fa8d2efd34391c173df439e44f55cbab3096..57c18abf69b4062154e92e69cb0446a93d6cbaa4 100644 (file)
@@ -33,7 +33,7 @@
 +obj-$(CONFIG_NET_AR231X) += ar231x.o
 --- /dev/null
 +++ b/drivers/net/ethernet/atheros/ar231x/ar231x.c
-@@ -0,0 +1,1119 @@
+@@ -0,0 +1,1120 @@
 +/*
 + * ar231x.c: Linux driver for the Atheros AR231x Ethernet device.
 + *
 +
 +      sp = netdev_priv(dev);
 +      sp->dev = dev;
++      sp->pdev = pdev;
 +      sp->cfg = pdev->dev.platform_data;
 +
 +      sprintf(buf, "eth%d_membase", pdev->id);
 +                      break;
 +              }
 +              /* done with this descriptor */
-+              dma_unmap_single(NULL, txdesc->addr,
++              dma_unmap_single(&sp->pdev->dev, txdesc->addr,
 +                               txdesc->devcs & DMA_TX1_BSIZE_MASK,
 +                               DMA_TO_DEVICE);
 +              txdesc->status = 0;
 +      /* Setup the transmit descriptor. */
 +      td->devcs = ((skb->len << DMA_TX1_BSIZE_SHIFT) |
 +                               (DMA_TX1_LS | DMA_TX1_IC | DMA_TX1_CHAINED));
-+      td->addr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
++      td->addr = dma_map_single(&sp->pdev->dev, skb->data, skb->len, DMA_TO_DEVICE);
 +      td->status = DMA_TX_OWN;
 +
 +      /* kick transmitter last */
 +
 --- /dev/null
 +++ b/drivers/net/ethernet/atheros/ar231x/ar231x.h
-@@ -0,0 +1,281 @@
+@@ -0,0 +1,282 @@
 +/*
 + * ar231x.h: Linux driver for the Atheros AR231x Ethernet device.
 + *
 + */
 +struct ar231x_private {
 +      struct net_device *dev;
++      struct platform_device *pdev;
 +      int version;
 +      u32 mb[2];
 +
index 91b97925155f8fbeecd3b7d153c8b09c6a795ca8..9051e1b466af58fbbe4dff6575616fa5be2718e7 100644 (file)
@@ -41,7 +41,7 @@
  static int ar231x_probe(struct platform_device *pdev)
  {
        struct net_device *dev;
-@@ -273,6 +300,24 @@ static int ar231x_probe(struct platform_
+@@ -274,6 +301,24 @@ static int ar231x_probe(struct platform_
  
        mdiobus_register(sp->mii_bus);
  
@@ -66,7 +66,7 @@
        if (ar231x_mdiobus_probe(dev) != 0) {
                printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name);
                rx_tasklet_cleanup(dev);
-@@ -326,8 +371,10 @@ static int ar231x_remove(struct platform
+@@ -327,8 +372,10 @@ static int ar231x_remove(struct platform
        rx_tasklet_cleanup(dev);
        ar231x_init_cleanup(dev);
        unregister_netdev(dev);
@@ -79,7 +79,7 @@
        kfree(dev);
        return 0;
  }
-@@ -870,7 +917,8 @@ static int ar231x_open(struct net_device
+@@ -871,7 +918,8 @@ static int ar231x_open(struct net_device
  
        sp->eth_regs->mac_control |= MAC_CONTROL_RE;
  
@@ -89,7 +89,7 @@
  
        return 0;
  }
-@@ -951,7 +999,8 @@ static int ar231x_close(struct net_devic
+@@ -952,7 +1000,8 @@ static int ar231x_close(struct net_devic
  
  #endif
  
@@ -99,7 +99,7 @@
  
        return 0;
  }
-@@ -995,6 +1044,9 @@ static int ar231x_ioctl(struct net_devic
+@@ -996,6 +1045,9 @@ static int ar231x_ioctl(struct net_devic
  {
        struct ar231x_private *sp = netdev_priv(dev);