Commit 375a6833 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'linux-can-fixes-for-6.0-20220921' of...

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

Marc Kleine-Budde says:

====================
pull-request: can 2022-09-21

The 1st patch is by me, targets the flexcan driver and fixes a
potential system hang on single core systems under high CAN packet
rate.

The next 2 patches are also by me and target the gs_usb driver. A
potential race condition during the ndo_open callback as well as the
return value if the ethtool identify feature is not supported are
fixed.

* tag 'linux-can-fixes-for-6.0-20220921' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: gs_usb: gs_usb_set_phys_id(): return with error if identify is not supported
  can: gs_usb: gs_can_open(): fix race dev->can.state condition
  can: flexcan: flexcan_mailbox_read() fix return value for drop = true
====================

Link: https://lore.kernel.org/r/20220921083609.419768-1-mkl@pengutronix.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 65e5d27d 0f2211f1
...@@ -941,11 +941,6 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, ...@@ -941,11 +941,6 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
u32 reg_ctrl, reg_id, reg_iflag1; u32 reg_ctrl, reg_id, reg_iflag1;
int i; int i;
if (unlikely(drop)) {
skb = ERR_PTR(-ENOBUFS);
goto mark_as_read;
}
mb = flexcan_get_mb(priv, n); mb = flexcan_get_mb(priv, n);
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) { if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) {
...@@ -974,6 +969,11 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, ...@@ -974,6 +969,11 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
reg_ctrl = priv->read(&mb->can_ctrl); reg_ctrl = priv->read(&mb->can_ctrl);
} }
if (unlikely(drop)) {
skb = ERR_PTR(-ENOBUFS);
goto mark_as_read;
}
if (reg_ctrl & FLEXCAN_MB_CNT_EDL) if (reg_ctrl & FLEXCAN_MB_CNT_EDL)
skb = alloc_canfd_skb(offload->dev, &cfd); skb = alloc_canfd_skb(offload->dev, &cfd);
else else
......
...@@ -824,6 +824,7 @@ static int gs_can_open(struct net_device *netdev) ...@@ -824,6 +824,7 @@ static int gs_can_open(struct net_device *netdev)
flags |= GS_CAN_MODE_TRIPLE_SAMPLE; flags |= GS_CAN_MODE_TRIPLE_SAMPLE;
/* finally start device */ /* finally start device */
dev->can.state = CAN_STATE_ERROR_ACTIVE;
dm->mode = cpu_to_le32(GS_CAN_MODE_START); dm->mode = cpu_to_le32(GS_CAN_MODE_START);
dm->flags = cpu_to_le32(flags); dm->flags = cpu_to_le32(flags);
rc = usb_control_msg(interface_to_usbdev(dev->iface), rc = usb_control_msg(interface_to_usbdev(dev->iface),
...@@ -835,13 +836,12 @@ static int gs_can_open(struct net_device *netdev) ...@@ -835,13 +836,12 @@ static int gs_can_open(struct net_device *netdev)
if (rc < 0) { if (rc < 0) {
netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
kfree(dm); kfree(dm);
dev->can.state = CAN_STATE_STOPPED;
return rc; return rc;
} }
kfree(dm); kfree(dm);
dev->can.state = CAN_STATE_ERROR_ACTIVE;
parent->active_channels++; parent->active_channels++;
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
netif_start_queue(netdev); netif_start_queue(netdev);
...@@ -925,17 +925,21 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify) ...@@ -925,17 +925,21 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
} }
/* blink LED's for finding the this interface */ /* blink LED's for finding the this interface */
static int gs_usb_set_phys_id(struct net_device *dev, static int gs_usb_set_phys_id(struct net_device *netdev,
enum ethtool_phys_id_state state) enum ethtool_phys_id_state state)
{ {
const struct gs_can *dev = netdev_priv(netdev);
int rc = 0; int rc = 0;
if (!(dev->feature & GS_CAN_FEATURE_IDENTIFY))
return -EOPNOTSUPP;
switch (state) { switch (state) {
case ETHTOOL_ID_ACTIVE: case ETHTOOL_ID_ACTIVE:
rc = gs_usb_set_identify(dev, GS_CAN_IDENTIFY_ON); rc = gs_usb_set_identify(netdev, GS_CAN_IDENTIFY_ON);
break; break;
case ETHTOOL_ID_INACTIVE: case ETHTOOL_ID_INACTIVE:
rc = gs_usb_set_identify(dev, GS_CAN_IDENTIFY_OFF); rc = gs_usb_set_identify(netdev, GS_CAN_IDENTIFY_OFF);
break; break;
default: default:
break; break;
...@@ -1072,9 +1076,10 @@ static struct gs_can *gs_make_candev(unsigned int channel, ...@@ -1072,9 +1076,10 @@ static struct gs_can *gs_make_candev(unsigned int channel,
dev->feature |= GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX | dev->feature |= GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX |
GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO; GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO;
if (le32_to_cpu(dconf->sw_version) > 1) /* GS_CAN_FEATURE_IDENTIFY is only supported for sw_version > 1 */
if (feature & GS_CAN_FEATURE_IDENTIFY) if (!(le32_to_cpu(dconf->sw_version) > 1 &&
netdev->ethtool_ops = &gs_usb_ethtool_ops; feature & GS_CAN_FEATURE_IDENTIFY))
dev->feature &= ~GS_CAN_FEATURE_IDENTIFY;
kfree(bt_const); kfree(bt_const);
......
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