diff options
author | David S. Miller <davem@davemloft.net> | 2021-11-07 19:05:52 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-11-07 19:05:52 +0000 |
commit | f05fb508ec3bb2d4b6006682d76d380d50a6fc42 (patch) | |
tree | 8d65c4ca75dd91f704853d8eb6ba1dc42a5d7904 | |
parent | 70bf363d7adb3a428773bc905011d0ff923ba747 (diff) | |
parent | 69c55f6e7669d46bb40e41f6e2b218428178368a (diff) |
Merge tag 'linux-can-fixes-for-5.16-20211106' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
linux-can-fixes-for-5.16-20211106
Marc Kleine-Budde says:
====================
pull-request: can 2021-11-06
this is a pull request of 8 patches for net/master.
The first 3 patches are by Zhang Changzhong and fix 3 standard
conformance problems in the j1939 CAN stack.
The next patch is by Vincent Mailhol and fixes a memory leak in the
leak error path of the etas_es58x CAN driver.
Stephane Grosjean contributes 2 patches for the peak_usb driver to fix
the bus error handling and update the order of printed information
regarding firmware version and available updates.
The last 2 patches are by me and fixes a packet starvation problem in
the bus off case and the error handling in the mcp251xfd_chip_start()
function.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 6 | ||||
-rw-r--r-- | drivers/net/can/usb/etas_es58x/es58x_core.c | 6 | ||||
-rw-r--r-- | drivers/net/can/usb/peak_usb/pcan_usb.c | 27 | ||||
-rw-r--r-- | net/can/j1939/main.c | 7 | ||||
-rw-r--r-- | net/can/j1939/transport.c | 11 |
5 files changed, 37 insertions, 20 deletions
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 673861ab665a..e16dc482f327 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1092,7 +1092,7 @@ static int mcp251xfd_chip_start(struct mcp251xfd_priv *priv) err = mcp251xfd_chip_rx_int_enable(priv); if (err) - return err; + goto out_chip_stop; err = mcp251xfd_chip_ecc_init(priv); if (err) @@ -2290,8 +2290,10 @@ static irqreturn_t mcp251xfd_irq(int irq, void *dev_id) * check will fail, too. So leave IRQ handler * directly. */ - if (priv->can.state == CAN_STATE_BUS_OFF) + if (priv->can.state == CAN_STATE_BUS_OFF) { + can_rx_offload_threaded_irq_finish(&priv->offload); return IRQ_HANDLED; + } } handled = IRQ_HANDLED; diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index 96a13c770e4a..24627ab14626 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -664,7 +664,7 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error, struct can_device_stats *can_stats = &can->can_stats; struct can_frame *cf = NULL; struct sk_buff *skb; - int ret; + int ret = 0; if (!netif_running(netdev)) { if (net_ratelimit()) @@ -823,8 +823,6 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error, can->state = CAN_STATE_BUS_OFF; can_bus_off(netdev); ret = can->do_set_mode(netdev, CAN_MODE_STOP); - if (ret) - return ret; } break; @@ -881,7 +879,7 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error, ES58X_EVENT_BUSOFF, timestamp); } - return 0; + return ret; } /** diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index 837b3fecd71e..876218752766 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -841,14 +841,14 @@ static int pcan_usb_start(struct peak_usb_device *dev) pdev->bec.rxerr = 0; pdev->bec.txerr = 0; - /* be notified on error counter changes (if requested by user) */ - if (dev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) { - err = pcan_usb_set_err_frame(dev, PCAN_USB_BERR_MASK); - if (err) - netdev_warn(dev->netdev, - "Asking for BERR reporting error %u\n", - err); - } + /* always ask the device for BERR reporting, to be able to switch from + * WARNING to PASSIVE state + */ + err = pcan_usb_set_err_frame(dev, PCAN_USB_BERR_MASK); + if (err) + netdev_warn(dev->netdev, + "Asking for BERR reporting error %u\n", + err); /* if revision greater than 3, can put silent mode on/off */ if (dev->device_rev > 3) { @@ -883,6 +883,11 @@ static int pcan_usb_init(struct peak_usb_device *dev) return err; } + dev_info(dev->netdev->dev.parent, + "PEAK-System %s adapter hwrev %u serial %08X (%u channel)\n", + pcan_usb.name, dev->device_rev, serial_number, + pcan_usb.ctrl_count); + /* Since rev 4.1, PCAN-USB is able to make single-shot as well as * looped back frames. */ @@ -896,11 +901,6 @@ static int pcan_usb_init(struct peak_usb_device *dev) "Firmware update available. Please contact support@peak-system.com\n"); } - dev_info(dev->netdev->dev.parent, - "PEAK-System %s adapter hwrev %u serial %08X (%u channel)\n", - pcan_usb.name, dev->device_rev, serial_number, - pcan_usb.ctrl_count); - return 0; } @@ -986,7 +986,6 @@ const struct peak_usb_adapter pcan_usb = { .device_id = PCAN_USB_PRODUCT_ID, .ctrl_count = 1, .ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY | - CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_CC_LEN8_DLC, .clock = { .freq = PCAN_USB_CRYSTAL_HZ / 2, diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c index 9bc55ecb37f9..8452b0fbb78c 100644 --- a/net/can/j1939/main.c +++ b/net/can/j1939/main.c @@ -75,6 +75,13 @@ static void j1939_can_recv(struct sk_buff *iskb, void *data) skcb->addr.pgn = (cf->can_id >> 8) & J1939_PGN_MAX; /* set default message type */ skcb->addr.type = J1939_TP; + + if (!j1939_address_is_valid(skcb->addr.sa)) { + netdev_err_once(priv->ndev, "%s: sa is broadcast address, ignoring!\n", + __func__); + goto done; + } + if (j1939_pgn_is_pdu1(skcb->addr.pgn)) { /* Type 1: with destination address */ skcb->addr.da = skcb->addr.pgn; diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c index 6c0a0ebdd024..a271688780a2 100644 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -2023,6 +2023,11 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb) extd = J1939_ETP; fallthrough; case J1939_TP_CMD_BAM: + if (cmd == J1939_TP_CMD_BAM && !j1939_cb_is_broadcast(skcb)) { + netdev_err_once(priv->ndev, "%s: BAM to unicast (%02x), ignoring!\n", + __func__, skcb->addr.sa); + return; + } fallthrough; case J1939_TP_CMD_RTS: if (skcb->addr.type != extd) @@ -2085,6 +2090,12 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb) break; case J1939_ETP_CMD_ABORT: /* && J1939_TP_CMD_ABORT */ + if (j1939_cb_is_broadcast(skcb)) { + netdev_err_once(priv->ndev, "%s: abort to broadcast (%02x), ignoring!\n", + __func__, skcb->addr.sa); + return; + } + if (j1939_tp_im_transmitter(skcb)) j1939_xtp_rx_abort(priv, skb, true); |