Commit 4f159a7c authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'linux-can-fixes-for-5.18-20220429' of...

Merge tag 'linux-can-fixes-for-5.18-20220429' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2022-04-29

The first patch is by Oliver Hartkopp and removes the ability to
re-binding bounds sockets from the ISOTP. It turned out to be not
needed and brings unnecessary complexity.

The last 4 patches all target the grcan driver. Duoming Zhou's patch
fixes a potential dead lock in the grcan_close() function. Daniel
Hellstrom's patch fixes the dma_alloc_coherent() to use the correct
device. Andreas Larsson's 1st patch fixes a broken system id check,
the 2nd patch fixes the NAPI poll budget usage.

* tag 'linux-can-fixes-for-5.18-20220429' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: grcan: only use the NAPI poll budget for RX
  can: grcan: grcan_probe(): fix broken system id check for errata workaround needs
  can: grcan: use ofdev->dev when allocating DMA memory
  can: grcan: grcan_close(): fix deadlock
  can: isotp: remove re-binding of bound socket
====================

Link: https://lore.kernel.org/r/20220429125612.1792561-1-mkl@pengutronix.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 249aca0d 2873d4d5
......@@ -241,13 +241,14 @@ struct grcan_device_config {
.rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \
}
#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100
#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 4100
#define GRLIB_VERSION_MASK 0xffff
/* GRCAN private data structure */
struct grcan_priv {
struct can_priv can; /* must be the first member */
struct net_device *dev;
struct device *ofdev_dev;
struct napi_struct napi;
struct grcan_registers __iomem *regs; /* ioremap'ed registers */
......@@ -921,7 +922,7 @@ static void grcan_free_dma_buffers(struct net_device *dev)
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_dma *dma = &priv->dma;
dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
dma_free_coherent(priv->ofdev_dev, dma->base_size, dma->base_buf,
dma->base_handle);
memset(dma, 0, sizeof(*dma));
}
......@@ -946,7 +947,7 @@ static int grcan_allocate_dma_buffers(struct net_device *dev,
/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
dma->base_buf = dma_alloc_coherent(&dev->dev,
dma->base_buf = dma_alloc_coherent(priv->ofdev_dev,
dma->base_size,
&dma->base_handle,
GFP_KERNEL);
......@@ -1102,8 +1103,10 @@ static int grcan_close(struct net_device *dev)
priv->closing = true;
if (priv->need_txbug_workaround) {
spin_unlock_irqrestore(&priv->lock, flags);
del_timer_sync(&priv->hang_timer);
del_timer_sync(&priv->rr_timer);
spin_lock_irqsave(&priv->lock, flags);
}
netif_stop_queue(dev);
grcan_stop_hardware(dev);
......@@ -1122,7 +1125,7 @@ static int grcan_close(struct net_device *dev)
return 0;
}
static int grcan_transmit_catch_up(struct net_device *dev, int budget)
static void grcan_transmit_catch_up(struct net_device *dev)
{
struct grcan_priv *priv = netdev_priv(dev);
unsigned long flags;
......@@ -1130,7 +1133,7 @@ static int grcan_transmit_catch_up(struct net_device *dev, int budget)
spin_lock_irqsave(&priv->lock, flags);
work_done = catch_up_echo_skb(dev, budget, true);
work_done = catch_up_echo_skb(dev, -1, true);
if (work_done) {
if (!priv->resetting && !priv->closing &&
!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
......@@ -1144,8 +1147,6 @@ static int grcan_transmit_catch_up(struct net_device *dev, int budget)
}
spin_unlock_irqrestore(&priv->lock, flags);
return work_done;
}
static int grcan_receive(struct net_device *dev, int budget)
......@@ -1227,19 +1228,13 @@ static int grcan_poll(struct napi_struct *napi, int budget)
struct net_device *dev = priv->dev;
struct grcan_registers __iomem *regs = priv->regs;
unsigned long flags;
int tx_work_done, rx_work_done;
int rx_budget = budget / 2;
int tx_budget = budget - rx_budget;
int work_done;
/* Half of the budget for receiving messages */
rx_work_done = grcan_receive(dev, rx_budget);
work_done = grcan_receive(dev, budget);
/* Half of the budget for transmitting messages as that can trigger echo
* frames being received
*/
tx_work_done = grcan_transmit_catch_up(dev, tx_budget);
grcan_transmit_catch_up(dev);
if (rx_work_done < rx_budget && tx_work_done < tx_budget) {
if (work_done < budget) {
napi_complete(napi);
/* Guarantee no interference with a running reset that otherwise
......@@ -1256,7 +1251,7 @@ static int grcan_poll(struct napi_struct *napi, int budget)
spin_unlock_irqrestore(&priv->lock, flags);
}
return rx_work_done + tx_work_done;
return work_done;
}
/* Work tx bug by waiting while for the risky situation to clear. If that fails,
......@@ -1587,6 +1582,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev,
memcpy(&priv->config, &grcan_module_config,
sizeof(struct grcan_device_config));
priv->dev = dev;
priv->ofdev_dev = &ofdev->dev;
priv->regs = base;
priv->can.bittiming_const = &grcan_bittiming_const;
priv->can.do_set_bittiming = grcan_set_bittiming;
......@@ -1639,6 +1635,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev,
static int grcan_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct device_node *sysid_parent;
u32 sysid, ambafreq;
int irq, err;
void __iomem *base;
......@@ -1647,10 +1644,15 @@ static int grcan_probe(struct platform_device *ofdev)
/* Compare GRLIB version number with the first that does not
* have the tx bug (see start_xmit)
*/
err = of_property_read_u32(np, "systemid", &sysid);
if (!err && ((sysid & GRLIB_VERSION_MASK)
>= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
txbug = false;
sysid_parent = of_find_node_by_path("/ambapp0");
if (sysid_parent) {
of_node_get(sysid_parent);
err = of_property_read_u32(sysid_parent, "systemid", &sysid);
if (!err && ((sysid & GRLIB_VERSION_MASK) >=
GRCAN_TXBUG_SAFE_GRLIB_VERSION))
txbug = false;
of_node_put(sysid_parent);
}
err = of_property_read_u32(np, "freq", &ambafreq);
if (err) {
......
......@@ -1189,6 +1189,11 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
lock_sock(sk);
if (so->bound) {
err = -EINVAL;
goto out;
}
/* do not register frame reception for functional addressing */
if (so->opt.flags & CAN_ISOTP_SF_BROADCAST)
do_rx_reg = 0;
......@@ -1199,10 +1204,6 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
goto out;
}
if (so->bound && addr->can_ifindex == so->ifindex &&
rx_id == so->rxid && tx_id == so->txid)
goto out;
dev = dev_get_by_index(net, addr->can_ifindex);
if (!dev) {
err = -ENODEV;
......@@ -1237,22 +1238,6 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
dev_put(dev);
if (so->bound && do_rx_reg) {
/* unregister old filter */
if (so->ifindex) {
dev = dev_get_by_index(net, so->ifindex);
if (dev) {
can_rx_unregister(net, dev, so->rxid,
SINGLE_MASK(so->rxid),
isotp_rcv, sk);
can_rx_unregister(net, dev, so->txid,
SINGLE_MASK(so->txid),
isotp_rcv_echo, sk);
dev_put(dev);
}
}
}
/* switch to new settings */
so->ifindex = ifindex;
so->rxid = rx_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment