ath25: eth: fix crash on skb DMA (un-)map

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>
This commit is contained in:
Sergey Ryazanov 2020-09-05 02:51:31 +03:00 committed by Adrian Schmutzler
parent 36e06497f4
commit ce3b135243
2 changed files with 11 additions and 9 deletions

View file

@ -33,7 +33,7 @@
+obj-$(CONFIG_NET_AR231X) += ar231x.o +obj-$(CONFIG_NET_AR231X) += ar231x.o
--- /dev/null --- /dev/null
+++ b/drivers/net/ethernet/atheros/ar231x/ar231x.c +++ 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. + * ar231x.c: Linux driver for the Atheros AR231x Ethernet device.
+ * + *
@ -225,6 +225,7 @@
+ +
+ sp = netdev_priv(dev); + sp = netdev_priv(dev);
+ sp->dev = dev; + sp->dev = dev;
+ sp->pdev = pdev;
+ sp->cfg = pdev->dev.platform_data; + sp->cfg = pdev->dev.platform_data;
+ +
+ sprintf(buf, "eth%d_membase", pdev->id); + sprintf(buf, "eth%d_membase", pdev->id);
@ -787,7 +788,7 @@
+ break; + break;
+ } + }
+ /* done with this descriptor */ + /* done with this descriptor */
+ dma_unmap_single(NULL, txdesc->addr, + dma_unmap_single(&sp->pdev->dev, txdesc->addr,
+ txdesc->devcs & DMA_TX1_BSIZE_MASK, + txdesc->devcs & DMA_TX1_BSIZE_MASK,
+ DMA_TO_DEVICE); + DMA_TO_DEVICE);
+ txdesc->status = 0; + txdesc->status = 0;
@ -1014,7 +1015,7 @@
+ /* Setup the transmit descriptor. */ + /* Setup the transmit descriptor. */
+ td->devcs = ((skb->len << DMA_TX1_BSIZE_SHIFT) | + td->devcs = ((skb->len << DMA_TX1_BSIZE_SHIFT) |
+ (DMA_TX1_LS | DMA_TX1_IC | DMA_TX1_CHAINED)); + (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; + td->status = DMA_TX_OWN;
+ +
+ /* kick transmitter last */ + /* kick transmitter last */
@ -1155,7 +1156,7 @@
+ +
--- /dev/null --- /dev/null
+++ b/drivers/net/ethernet/atheros/ar231x/ar231x.h +++ 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. + * ar231x.h: Linux driver for the Atheros AR231x Ethernet device.
+ * + *
@ -1379,6 +1380,7 @@
+ */ + */
+struct ar231x_private { +struct ar231x_private {
+ struct net_device *dev; + struct net_device *dev;
+ struct platform_device *pdev;
+ int version; + int version;
+ u32 mb[2]; + u32 mb[2];
+ +

View file

@ -41,7 +41,7 @@
static int ar231x_probe(struct platform_device *pdev) static int ar231x_probe(struct platform_device *pdev)
{ {
struct net_device *dev; 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); mdiobus_register(sp->mii_bus);
@ -66,7 +66,7 @@
if (ar231x_mdiobus_probe(dev) != 0) { if (ar231x_mdiobus_probe(dev) != 0) {
printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name); printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name);
rx_tasklet_cleanup(dev); 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); rx_tasklet_cleanup(dev);
ar231x_init_cleanup(dev); ar231x_init_cleanup(dev);
unregister_netdev(dev); unregister_netdev(dev);
@ -79,7 +79,7 @@
kfree(dev); kfree(dev);
return 0; 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; sp->eth_regs->mac_control |= MAC_CONTROL_RE;
@ -89,7 +89,7 @@
return 0; 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 #endif
@ -99,7 +99,7 @@
return 0; 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); struct ar231x_private *sp = netdev_priv(dev);