Commit 7e8c182c authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'linux-can-fixes-for-5.19-20220704' of...

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

Marc Kleine-Budde says:

====================
can 2022-07-04

The 1st patch is by Oliver Hartkopp, targets the BCM CAN protocol and
converts a costly synchronize_rcu() to call_rcu() to fix a performance
regression.

Srinivas Neeli's patch for the xilinx_can driver drops the brp limit
down to 1, as only the pre-production silicon have an issue with a brp
of 1.

The next patch is by Duy Nguyen and fixes the data transmission on
R-Car V3U SoCs in the rcar_canfd driver.

Rhett Aultman's patch fixes a DMA memory leak in the gs_usb driver.

Liang He's patch removes an extra of_node_get() in the grcan driver.

The next 2 patches are by me, target the m_can driver and fix the
timestamp handling used for peripheral devices like the tcan4x5x.

Jimmy Assarsson contributes 3 patches for the kvaser_usb driver and
fixes CAN clock and bit timing related issues.

The remaining 5 patches target the mcp251xfd driver. Thomas Kopp
contributes 2 patches to improve the workaround for broken CRC when
reading the TBC register. 3 patches by me add a missing
hrtimer_cancel() during the ndo_stop() callback, and fix the reading
of the Device ID register.

* tag 'linux-can-fixes-for-5.19-20220704' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix endianness conversion
  can: mcp251xfd: mcp251xfd_register_get_dev_id(): use correct length to read dev_id
  can: mcp251xfd: mcp251xfd_stop(): add missing hrtimer_cancel()
  can: mcp251xfd: mcp251xfd_regmap_crc_read(): update workaround broken CRC on TBC register
  can: mcp251xfd: mcp251xfd_regmap_crc_read(): improve workaround handling for mcp2517fd
  can: kvaser_usb: kvaser_usb_leaf: fix bittiming limits
  can: kvaser_usb: kvaser_usb_leaf: fix CAN clock frequency regression
  can: kvaser_usb: replace run-time checks with struct kvaser_usb_driver_info
  can: m_can: m_can_{read_fifo,echo_tx_event}(): shift timestamp to full 32 bits
  can: m_can: m_can_chip_config(): actually enable internal timestamping
  can: grcan: grcan_probe(): remove extra of_node_get()
  can: gs_usb: gs_usb_open/close(): fix memory leak
  can: rcar_canfd: Fix data transmission failed on R-Car V3U
  Revert "can: xilinx_can: Limit CANFD brp to 2"
  can: bcm: use call_rcu() instead of costly synchronize_rcu()
====================

Link: https://lore.kernel.org/r/20220704122613.1551119-1-mkl@pengutronix.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1b18f09d 1c0e78a2
...@@ -1646,7 +1646,6 @@ static int grcan_probe(struct platform_device *ofdev) ...@@ -1646,7 +1646,6 @@ static int grcan_probe(struct platform_device *ofdev)
*/ */
sysid_parent = of_find_node_by_path("/ambapp0"); sysid_parent = of_find_node_by_path("/ambapp0");
if (sysid_parent) { if (sysid_parent) {
of_node_get(sysid_parent);
err = of_property_read_u32(sysid_parent, "systemid", &sysid); err = of_property_read_u32(sysid_parent, "systemid", &sysid);
if (!err && ((sysid & GRLIB_VERSION_MASK) >= if (!err && ((sysid & GRLIB_VERSION_MASK) >=
GRCAN_TXBUG_SAFE_GRLIB_VERSION)) GRCAN_TXBUG_SAFE_GRLIB_VERSION))
......
...@@ -529,7 +529,7 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs) ...@@ -529,7 +529,7 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs)
/* acknowledge rx fifo 0 */ /* acknowledge rx fifo 0 */
m_can_write(cdev, M_CAN_RXF0A, fgi); m_can_write(cdev, M_CAN_RXF0A, fgi);
timestamp = FIELD_GET(RX_BUF_RXTS_MASK, fifo_header.dlc); timestamp = FIELD_GET(RX_BUF_RXTS_MASK, fifo_header.dlc) << 16;
m_can_receive_skb(cdev, skb, timestamp); m_can_receive_skb(cdev, skb, timestamp);
...@@ -1030,7 +1030,7 @@ static int m_can_echo_tx_event(struct net_device *dev) ...@@ -1030,7 +1030,7 @@ static int m_can_echo_tx_event(struct net_device *dev)
} }
msg_mark = FIELD_GET(TX_EVENT_MM_MASK, txe); msg_mark = FIELD_GET(TX_EVENT_MM_MASK, txe);
timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe); timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe) << 16;
/* ack txe element */ /* ack txe element */
m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK, m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK,
...@@ -1351,7 +1351,9 @@ static void m_can_chip_config(struct net_device *dev) ...@@ -1351,7 +1351,9 @@ static void m_can_chip_config(struct net_device *dev)
/* enable internal timestamp generation, with a prescalar of 16. The /* enable internal timestamp generation, with a prescalar of 16. The
* prescalar is applied to the nominal bit timing * prescalar is applied to the nominal bit timing
*/ */
m_can_write(cdev, M_CAN_TSCC, FIELD_PREP(TSCC_TCP_MASK, 0xf)); m_can_write(cdev, M_CAN_TSCC,
FIELD_PREP(TSCC_TCP_MASK, 0xf) |
FIELD_PREP(TSCC_TSS_MASK, TSCC_TSS_INTERNAL));
m_can_config_endisable(cdev, false); m_can_config_endisable(cdev, false);
......
...@@ -1332,7 +1332,10 @@ static void rcar_canfd_set_bittiming(struct net_device *dev) ...@@ -1332,7 +1332,10 @@ static void rcar_canfd_set_bittiming(struct net_device *dev)
cfg = (RCANFD_DCFG_DTSEG1(gpriv, tseg1) | RCANFD_DCFG_DBRP(brp) | cfg = (RCANFD_DCFG_DTSEG1(gpriv, tseg1) | RCANFD_DCFG_DBRP(brp) |
RCANFD_DCFG_DSJW(sjw) | RCANFD_DCFG_DTSEG2(gpriv, tseg2)); RCANFD_DCFG_DSJW(sjw) | RCANFD_DCFG_DTSEG2(gpriv, tseg2));
rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg); if (is_v3u(gpriv))
rcar_canfd_write(priv->base, RCANFD_V3U_DCFG(ch), cfg);
else
rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg);
netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n",
brp, sjw, tseg1, tseg2); brp, sjw, tseg1, tseg2);
} else { } else {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
// Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
// //
#include <asm/unaligned.h>
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -1650,6 +1651,7 @@ static int mcp251xfd_stop(struct net_device *ndev) ...@@ -1650,6 +1651,7 @@ static int mcp251xfd_stop(struct net_device *ndev)
netif_stop_queue(ndev); netif_stop_queue(ndev);
set_bit(MCP251XFD_FLAGS_DOWN, priv->flags); set_bit(MCP251XFD_FLAGS_DOWN, priv->flags);
hrtimer_cancel(&priv->rx_irq_timer); hrtimer_cancel(&priv->rx_irq_timer);
hrtimer_cancel(&priv->tx_irq_timer);
mcp251xfd_chip_interrupts_disable(priv); mcp251xfd_chip_interrupts_disable(priv);
free_irq(ndev->irq, priv); free_irq(ndev->irq, priv);
can_rx_offload_disable(&priv->offload); can_rx_offload_disable(&priv->offload);
...@@ -1777,7 +1779,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id, ...@@ -1777,7 +1779,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
xfer[0].len = sizeof(buf_tx->cmd); xfer[0].len = sizeof(buf_tx->cmd);
xfer[0].speed_hz = priv->spi_max_speed_hz_slow; xfer[0].speed_hz = priv->spi_max_speed_hz_slow;
xfer[1].rx_buf = buf_rx->data; xfer[1].rx_buf = buf_rx->data;
xfer[1].len = sizeof(dev_id); xfer[1].len = sizeof(*dev_id);
xfer[1].speed_hz = priv->spi_max_speed_hz_fast; xfer[1].speed_hz = priv->spi_max_speed_hz_fast;
mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, MCP251XFD_REG_DEVID); mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, MCP251XFD_REG_DEVID);
...@@ -1786,7 +1788,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id, ...@@ -1786,7 +1788,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
if (err) if (err)
goto out_kfree_buf_tx; goto out_kfree_buf_tx;
*dev_id = be32_to_cpup((__be32 *)buf_rx->data); *dev_id = get_unaligned_le32(buf_rx->data);
*effective_speed_hz_slow = xfer[0].effective_speed_hz; *effective_speed_hz_slow = xfer[0].effective_speed_hz;
*effective_speed_hz_fast = xfer[1].effective_speed_hz; *effective_speed_hz_fast = xfer[1].effective_speed_hz;
......
...@@ -334,19 +334,21 @@ mcp251xfd_regmap_crc_read(void *context, ...@@ -334,19 +334,21 @@ mcp251xfd_regmap_crc_read(void *context,
* register. It increments once per SYS clock tick, * register. It increments once per SYS clock tick,
* which is 20 or 40 MHz. * which is 20 or 40 MHz.
* *
* Observation shows that if the lowest byte (which is * Observation on the mcp2518fd shows that if the
* transferred first on the SPI bus) of that register * lowest byte (which is transferred first on the SPI
* is 0x00 or 0x80 the calculated CRC doesn't always * bus) of that register is 0x00 or 0x80 the
* match the transferred one. * calculated CRC doesn't always match the transferred
* one. On the mcp2517fd this problem is not limited
* to the first byte being 0x00 or 0x80.
* *
* If the highest bit in the lowest byte is flipped * If the highest bit in the lowest byte is flipped
* the transferred CRC matches the calculated one. We * the transferred CRC matches the calculated one. We
* assume for now the CRC calculation in the chip * assume for now the CRC operates on the correct
* works on wrong data and the transferred data is * data.
* correct.
*/ */
if (reg == MCP251XFD_REG_TBC && if (reg == MCP251XFD_REG_TBC &&
(buf_rx->data[0] == 0x0 || buf_rx->data[0] == 0x80)) { ((buf_rx->data[0] & 0xf8) == 0x0 ||
(buf_rx->data[0] & 0xf8) == 0x80)) {
/* Flip highest bit in lowest byte of le32 */ /* Flip highest bit in lowest byte of le32 */
buf_rx->data[0] ^= 0x80; buf_rx->data[0] ^= 0x80;
...@@ -356,10 +358,8 @@ mcp251xfd_regmap_crc_read(void *context, ...@@ -356,10 +358,8 @@ mcp251xfd_regmap_crc_read(void *context,
val_len); val_len);
if (!err) { if (!err) {
/* If CRC is now correct, assume /* If CRC is now correct, assume
* transferred data was OK, flip bit * flipped data is OK.
* back to original value.
*/ */
buf_rx->data[0] ^= 0x80;
goto out; goto out;
} }
} }
......
...@@ -268,6 +268,8 @@ struct gs_can { ...@@ -268,6 +268,8 @@ struct gs_can {
struct usb_anchor tx_submitted; struct usb_anchor tx_submitted;
atomic_t active_tx_urbs; atomic_t active_tx_urbs;
void *rxbuf[GS_MAX_RX_URBS];
dma_addr_t rxbuf_dma[GS_MAX_RX_URBS];
}; };
/* usb interface struct */ /* usb interface struct */
...@@ -742,6 +744,7 @@ static int gs_can_open(struct net_device *netdev) ...@@ -742,6 +744,7 @@ static int gs_can_open(struct net_device *netdev)
for (i = 0; i < GS_MAX_RX_URBS; i++) { for (i = 0; i < GS_MAX_RX_URBS; i++) {
struct urb *urb; struct urb *urb;
u8 *buf; u8 *buf;
dma_addr_t buf_dma;
/* alloc rx urb */ /* alloc rx urb */
urb = usb_alloc_urb(0, GFP_KERNEL); urb = usb_alloc_urb(0, GFP_KERNEL);
...@@ -752,7 +755,7 @@ static int gs_can_open(struct net_device *netdev) ...@@ -752,7 +755,7 @@ static int gs_can_open(struct net_device *netdev)
buf = usb_alloc_coherent(dev->udev, buf = usb_alloc_coherent(dev->udev,
dev->parent->hf_size_rx, dev->parent->hf_size_rx,
GFP_KERNEL, GFP_KERNEL,
&urb->transfer_dma); &buf_dma);
if (!buf) { if (!buf) {
netdev_err(netdev, netdev_err(netdev,
"No memory left for USB buffer\n"); "No memory left for USB buffer\n");
...@@ -760,6 +763,8 @@ static int gs_can_open(struct net_device *netdev) ...@@ -760,6 +763,8 @@ static int gs_can_open(struct net_device *netdev)
return -ENOMEM; return -ENOMEM;
} }
urb->transfer_dma = buf_dma;
/* fill, anchor, and submit rx urb */ /* fill, anchor, and submit rx urb */
usb_fill_bulk_urb(urb, usb_fill_bulk_urb(urb,
dev->udev, dev->udev,
...@@ -781,10 +786,17 @@ static int gs_can_open(struct net_device *netdev) ...@@ -781,10 +786,17 @@ static int gs_can_open(struct net_device *netdev)
"usb_submit failed (err=%d)\n", rc); "usb_submit failed (err=%d)\n", rc);
usb_unanchor_urb(urb); usb_unanchor_urb(urb);
usb_free_coherent(dev->udev,
sizeof(struct gs_host_frame),
buf,
buf_dma);
usb_free_urb(urb); usb_free_urb(urb);
break; break;
} }
dev->rxbuf[i] = buf;
dev->rxbuf_dma[i] = buf_dma;
/* Drop reference, /* Drop reference,
* USB core will take care of freeing it * USB core will take care of freeing it
*/ */
...@@ -842,13 +854,20 @@ static int gs_can_close(struct net_device *netdev) ...@@ -842,13 +854,20 @@ static int gs_can_close(struct net_device *netdev)
int rc; int rc;
struct gs_can *dev = netdev_priv(netdev); struct gs_can *dev = netdev_priv(netdev);
struct gs_usb *parent = dev->parent; struct gs_usb *parent = dev->parent;
unsigned int i;
netif_stop_queue(netdev); netif_stop_queue(netdev);
/* Stop polling */ /* Stop polling */
parent->active_channels--; parent->active_channels--;
if (!parent->active_channels) if (!parent->active_channels) {
usb_kill_anchored_urbs(&parent->rx_submitted); usb_kill_anchored_urbs(&parent->rx_submitted);
for (i = 0; i < GS_MAX_RX_URBS; i++)
usb_free_coherent(dev->udev,
sizeof(struct gs_host_frame),
dev->rxbuf[i],
dev->rxbuf_dma[i]);
}
/* Stop sending URBs */ /* Stop sending URBs */
usb_kill_anchored_urbs(&dev->tx_submitted); usb_kill_anchored_urbs(&dev->tx_submitted);
......
...@@ -35,9 +35,10 @@ ...@@ -35,9 +35,10 @@
#define KVASER_USB_RX_BUFFER_SIZE 3072 #define KVASER_USB_RX_BUFFER_SIZE 3072
#define KVASER_USB_MAX_NET_DEVICES 5 #define KVASER_USB_MAX_NET_DEVICES 5
/* USB devices features */ /* Kvaser USB device quirks */
#define KVASER_USB_HAS_SILENT_MODE BIT(0) #define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0)
#define KVASER_USB_HAS_TXRX_ERRORS BIT(1) #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1)
#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ BIT(2)
/* Device capabilities */ /* Device capabilities */
#define KVASER_USB_CAP_BERR_CAP 0x01 #define KVASER_USB_CAP_BERR_CAP 0x01
...@@ -65,12 +66,7 @@ struct kvaser_usb_dev_card_data_hydra { ...@@ -65,12 +66,7 @@ struct kvaser_usb_dev_card_data_hydra {
struct kvaser_usb_dev_card_data { struct kvaser_usb_dev_card_data {
u32 ctrlmode_supported; u32 ctrlmode_supported;
u32 capabilities; u32 capabilities;
union { struct kvaser_usb_dev_card_data_hydra hydra;
struct {
enum kvaser_usb_leaf_family family;
} leaf;
struct kvaser_usb_dev_card_data_hydra hydra;
};
}; };
/* Context for an outstanding, not yet ACKed, transmission */ /* Context for an outstanding, not yet ACKed, transmission */
...@@ -83,7 +79,7 @@ struct kvaser_usb { ...@@ -83,7 +79,7 @@ struct kvaser_usb {
struct usb_device *udev; struct usb_device *udev;
struct usb_interface *intf; struct usb_interface *intf;
struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES]; struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES];
const struct kvaser_usb_dev_ops *ops; const struct kvaser_usb_driver_info *driver_info;
const struct kvaser_usb_dev_cfg *cfg; const struct kvaser_usb_dev_cfg *cfg;
struct usb_endpoint_descriptor *bulk_in, *bulk_out; struct usb_endpoint_descriptor *bulk_in, *bulk_out;
...@@ -165,6 +161,12 @@ struct kvaser_usb_dev_ops { ...@@ -165,6 +161,12 @@ struct kvaser_usb_dev_ops {
u16 transid); u16 transid);
}; };
struct kvaser_usb_driver_info {
u32 quirks;
enum kvaser_usb_leaf_family family;
const struct kvaser_usb_dev_ops *ops;
};
struct kvaser_usb_dev_cfg { struct kvaser_usb_dev_cfg {
const struct can_clock clock; const struct can_clock clock;
const unsigned int timestamp_freq; const unsigned int timestamp_freq;
...@@ -184,4 +186,7 @@ int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd, ...@@ -184,4 +186,7 @@ int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd,
int len); int len);
int kvaser_usb_can_rx_over_error(struct net_device *netdev); int kvaser_usb_can_rx_over_error(struct net_device *netdev);
extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const;
#endif /* KVASER_USB_H */ #endif /* KVASER_USB_H */
...@@ -375,7 +375,7 @@ static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = { ...@@ -375,7 +375,7 @@ static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = {
.brp_inc = 1, .brp_inc = 1,
}; };
static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = { const struct can_bittiming_const kvaser_usb_flexc_bittiming_const = {
.name = "kvaser_usb_flex", .name = "kvaser_usb_flex",
.tseg1_min = 4, .tseg1_min = 4,
.tseg1_max = 16, .tseg1_max = 16,
...@@ -2052,7 +2052,7 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc = { ...@@ -2052,7 +2052,7 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc = {
.freq = 24 * MEGA /* Hz */, .freq = 24 * MEGA /* Hz */,
}, },
.timestamp_freq = 1, .timestamp_freq = 1,
.bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c, .bittiming_const = &kvaser_usb_flexc_bittiming_const,
}; };
static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt = { static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt = {
......
...@@ -101,16 +101,6 @@ ...@@ -101,16 +101,6 @@
#define USBCAN_ERROR_STATE_RX_ERROR BIT(1) #define USBCAN_ERROR_STATE_RX_ERROR BIT(1)
#define USBCAN_ERROR_STATE_BUSERROR BIT(2) #define USBCAN_ERROR_STATE_BUSERROR BIT(2)
/* bittiming parameters */
#define KVASER_USB_TSEG1_MIN 1
#define KVASER_USB_TSEG1_MAX 16
#define KVASER_USB_TSEG2_MIN 1
#define KVASER_USB_TSEG2_MAX 8
#define KVASER_USB_SJW_MAX 4
#define KVASER_USB_BRP_MIN 1
#define KVASER_USB_BRP_MAX 64
#define KVASER_USB_BRP_INC 1
/* ctrl modes */ /* ctrl modes */
#define KVASER_CTRL_MODE_NORMAL 1 #define KVASER_CTRL_MODE_NORMAL 1
#define KVASER_CTRL_MODE_SILENT 2 #define KVASER_CTRL_MODE_SILENT 2
...@@ -343,48 +333,68 @@ struct kvaser_usb_err_summary { ...@@ -343,48 +333,68 @@ struct kvaser_usb_err_summary {
}; };
}; };
static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = { static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = {
.name = "kvaser_usb", .name = "kvaser_usb_ucii",
.tseg1_min = KVASER_USB_TSEG1_MIN, .tseg1_min = 4,
.tseg1_max = KVASER_USB_TSEG1_MAX, .tseg1_max = 16,
.tseg2_min = KVASER_USB_TSEG2_MIN, .tseg2_min = 2,
.tseg2_max = KVASER_USB_TSEG2_MAX, .tseg2_max = 8,
.sjw_max = KVASER_USB_SJW_MAX, .sjw_max = 4,
.brp_min = KVASER_USB_BRP_MIN, .brp_min = 1,
.brp_max = KVASER_USB_BRP_MAX, .brp_max = 16,
.brp_inc = KVASER_USB_BRP_INC, .brp_inc = 1,
};
static const struct can_bittiming_const kvaser_usb_leaf_m32c_bittiming_const = {
.name = "kvaser_usb_leaf",
.tseg1_min = 3,
.tseg1_max = 16,
.tseg2_min = 2,
.tseg2_max = 8,
.sjw_max = 4,
.brp_min = 2,
.brp_max = 128,
.brp_inc = 2,
}; };
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = { static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_usbcan_dev_cfg = {
.clock = { .clock = {
.freq = 8 * MEGA /* Hz */, .freq = 8 * MEGA /* Hz */,
}, },
.timestamp_freq = 1, .timestamp_freq = 1,
.bittiming_const = &kvaser_usb_leaf_bittiming_const, .bittiming_const = &kvaser_usb_leaf_m16c_bittiming_const,
};
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg = {
.clock = {
.freq = 16 * MEGA /* Hz */,
},
.timestamp_freq = 1,
.bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const,
}; };
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = { static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_16mhz = {
.clock = { .clock = {
.freq = 16 * MEGA /* Hz */, .freq = 16 * MEGA /* Hz */,
}, },
.timestamp_freq = 1, .timestamp_freq = 1,
.bittiming_const = &kvaser_usb_leaf_bittiming_const, .bittiming_const = &kvaser_usb_flexc_bittiming_const,
}; };
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = { static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_24mhz = {
.clock = { .clock = {
.freq = 24 * MEGA /* Hz */, .freq = 24 * MEGA /* Hz */,
}, },
.timestamp_freq = 1, .timestamp_freq = 1,
.bittiming_const = &kvaser_usb_leaf_bittiming_const, .bittiming_const = &kvaser_usb_flexc_bittiming_const,
}; };
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = { static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = {
.clock = { .clock = {
.freq = 32 * MEGA /* Hz */, .freq = 32 * MEGA /* Hz */,
}, },
.timestamp_freq = 1, .timestamp_freq = 1,
.bittiming_const = &kvaser_usb_leaf_bittiming_const, .bittiming_const = &kvaser_usb_flexc_bittiming_const,
}; };
static void * static void *
...@@ -404,7 +414,7 @@ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, ...@@ -404,7 +414,7 @@ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
sizeof(struct kvaser_cmd_tx_can); sizeof(struct kvaser_cmd_tx_can);
cmd->u.tx_can.channel = priv->channel; cmd->u.tx_can.channel = priv->channel;
switch (dev->card_data.leaf.family) { switch (dev->driver_info->family) {
case KVASER_LEAF: case KVASER_LEAF:
cmd_tx_can_flags = &cmd->u.tx_can.leaf.flags; cmd_tx_can_flags = &cmd->u.tx_can.leaf.flags;
break; break;
...@@ -524,16 +534,23 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, ...@@ -524,16 +534,23 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
dev->fw_version = le32_to_cpu(softinfo->fw_version); dev->fw_version = le32_to_cpu(softinfo->fw_version);
dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) {
case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: /* Firmware expects bittiming parameters calculated for 16MHz
dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; * clock, regardless of the actual clock
break; */
case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg;
dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz; } else {
break; switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz; dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_16mhz;
break; break;
case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_24mhz;
break;
case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_32mhz;
break;
}
} }
} }
...@@ -550,7 +567,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) ...@@ -550,7 +567,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
if (err) if (err)
return err; return err;
switch (dev->card_data.leaf.family) { switch (dev->driver_info->family) {
case KVASER_LEAF: case KVASER_LEAF:
kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo); kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo);
break; break;
...@@ -558,7 +575,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) ...@@ -558,7 +575,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version);
dev->max_tx_urbs = dev->max_tx_urbs =
le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx); le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx);
dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz; dev->cfg = &kvaser_usb_leaf_usbcan_dev_cfg;
break; break;
} }
...@@ -597,7 +614,7 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev) ...@@ -597,7 +614,7 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev)
dev->nchannels = cmd.u.cardinfo.nchannels; dev->nchannels = cmd.u.cardinfo.nchannels;
if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES || if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES ||
(dev->card_data.leaf.family == KVASER_USBCAN && (dev->driver_info->family == KVASER_USBCAN &&
dev->nchannels > MAX_USBCAN_NET_DEVICES)) dev->nchannels > MAX_USBCAN_NET_DEVICES))
return -EINVAL; return -EINVAL;
...@@ -730,7 +747,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, ...@@ -730,7 +747,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
new_state < CAN_STATE_BUS_OFF) new_state < CAN_STATE_BUS_OFF)
priv->can.can_stats.restarts++; priv->can.can_stats.restarts++;
switch (dev->card_data.leaf.family) { switch (dev->driver_info->family) {
case KVASER_LEAF: case KVASER_LEAF:
if (es->leaf.error_factor) { if (es->leaf.error_factor) {
priv->can.can_stats.bus_error++; priv->can.can_stats.bus_error++;
...@@ -809,7 +826,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, ...@@ -809,7 +826,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
} }
} }
switch (dev->card_data.leaf.family) { switch (dev->driver_info->family) {
case KVASER_LEAF: case KVASER_LEAF:
if (es->leaf.error_factor) { if (es->leaf.error_factor) {
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
...@@ -999,7 +1016,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, ...@@ -999,7 +1016,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
stats = &priv->netdev->stats; stats = &priv->netdev->stats;
if ((cmd->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) && if ((cmd->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) &&
(dev->card_data.leaf.family == KVASER_LEAF && (dev->driver_info->family == KVASER_LEAF &&
cmd->id == CMD_LEAF_LOG_MESSAGE)) { cmd->id == CMD_LEAF_LOG_MESSAGE)) {
kvaser_usb_leaf_leaf_rx_error(dev, cmd); kvaser_usb_leaf_leaf_rx_error(dev, cmd);
return; return;
...@@ -1015,7 +1032,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, ...@@ -1015,7 +1032,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
return; return;
} }
switch (dev->card_data.leaf.family) { switch (dev->driver_info->family) {
case KVASER_LEAF: case KVASER_LEAF:
rx_data = cmd->u.leaf.rx_can.data; rx_data = cmd->u.leaf.rx_can.data;
break; break;
...@@ -1030,7 +1047,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, ...@@ -1030,7 +1047,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
return; return;
} }
if (dev->card_data.leaf.family == KVASER_LEAF && cmd->id == if (dev->driver_info->family == KVASER_LEAF && cmd->id ==
CMD_LEAF_LOG_MESSAGE) { CMD_LEAF_LOG_MESSAGE) {
cf->can_id = le32_to_cpu(cmd->u.leaf.log_message.id); cf->can_id = le32_to_cpu(cmd->u.leaf.log_message.id);
if (cf->can_id & KVASER_EXTENDED_FRAME) if (cf->can_id & KVASER_EXTENDED_FRAME)
...@@ -1128,14 +1145,14 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, ...@@ -1128,14 +1145,14 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
break; break;
case CMD_LEAF_LOG_MESSAGE: case CMD_LEAF_LOG_MESSAGE:
if (dev->card_data.leaf.family != KVASER_LEAF) if (dev->driver_info->family != KVASER_LEAF)
goto warn; goto warn;
kvaser_usb_leaf_rx_can_msg(dev, cmd); kvaser_usb_leaf_rx_can_msg(dev, cmd);
break; break;
case CMD_CHIP_STATE_EVENT: case CMD_CHIP_STATE_EVENT:
case CMD_CAN_ERROR_EVENT: case CMD_CAN_ERROR_EVENT:
if (dev->card_data.leaf.family == KVASER_LEAF) if (dev->driver_info->family == KVASER_LEAF)
kvaser_usb_leaf_leaf_rx_error(dev, cmd); kvaser_usb_leaf_leaf_rx_error(dev, cmd);
else else
kvaser_usb_leaf_usbcan_rx_error(dev, cmd); kvaser_usb_leaf_usbcan_rx_error(dev, cmd);
...@@ -1147,12 +1164,12 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, ...@@ -1147,12 +1164,12 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
/* Ignored commands */ /* Ignored commands */
case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: case CMD_USBCAN_CLOCK_OVERFLOW_EVENT:
if (dev->card_data.leaf.family != KVASER_USBCAN) if (dev->driver_info->family != KVASER_USBCAN)
goto warn; goto warn;
break; break;
case CMD_FLUSH_QUEUE_REPLY: case CMD_FLUSH_QUEUE_REPLY:
if (dev->card_data.leaf.family != KVASER_LEAF) if (dev->driver_info->family != KVASER_LEAF)
goto warn; goto warn;
break; break;
......
...@@ -258,7 +258,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd2 = { ...@@ -258,7 +258,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd2 = {
.tseg2_min = 1, .tseg2_min = 1,
.tseg2_max = 128, .tseg2_max = 128,
.sjw_max = 128, .sjw_max = 128,
.brp_min = 2, .brp_min = 1,
.brp_max = 256, .brp_max = 256,
.brp_inc = 1, .brp_inc = 1,
}; };
...@@ -271,7 +271,7 @@ static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { ...@@ -271,7 +271,7 @@ static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = {
.tseg2_min = 1, .tseg2_min = 1,
.tseg2_max = 16, .tseg2_max = 16,
.sjw_max = 16, .sjw_max = 16,
.brp_min = 2, .brp_min = 1,
.brp_max = 256, .brp_max = 256,
.brp_inc = 1, .brp_inc = 1,
}; };
......
...@@ -100,6 +100,7 @@ static inline u64 get_u64(const struct canfd_frame *cp, int offset) ...@@ -100,6 +100,7 @@ static inline u64 get_u64(const struct canfd_frame *cp, int offset)
struct bcm_op { struct bcm_op {
struct list_head list; struct list_head list;
struct rcu_head rcu;
int ifindex; int ifindex;
canid_t can_id; canid_t can_id;
u32 flags; u32 flags;
...@@ -718,10 +719,9 @@ static struct bcm_op *bcm_find_op(struct list_head *ops, ...@@ -718,10 +719,9 @@ static struct bcm_op *bcm_find_op(struct list_head *ops,
return NULL; return NULL;
} }
static void bcm_remove_op(struct bcm_op *op) static void bcm_free_op_rcu(struct rcu_head *rcu_head)
{ {
hrtimer_cancel(&op->timer); struct bcm_op *op = container_of(rcu_head, struct bcm_op, rcu);
hrtimer_cancel(&op->thrtimer);
if ((op->frames) && (op->frames != &op->sframe)) if ((op->frames) && (op->frames != &op->sframe))
kfree(op->frames); kfree(op->frames);
...@@ -732,6 +732,14 @@ static void bcm_remove_op(struct bcm_op *op) ...@@ -732,6 +732,14 @@ static void bcm_remove_op(struct bcm_op *op)
kfree(op); kfree(op);
} }
static void bcm_remove_op(struct bcm_op *op)
{
hrtimer_cancel(&op->timer);
hrtimer_cancel(&op->thrtimer);
call_rcu(&op->rcu, bcm_free_op_rcu);
}
static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op) static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
{ {
if (op->rx_reg_dev == dev) { if (op->rx_reg_dev == dev) {
...@@ -757,6 +765,9 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh, ...@@ -757,6 +765,9 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) && if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) &&
(op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) { (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) {
/* disable automatic timer on frame reception */
op->flags |= RX_NO_AUTOTIMER;
/* /*
* Don't care if we're bound or not (due to netdev * Don't care if we're bound or not (due to netdev
* problems) can_rx_unregister() is always a save * problems) can_rx_unregister() is always a save
...@@ -785,7 +796,6 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh, ...@@ -785,7 +796,6 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
bcm_rx_handler, op); bcm_rx_handler, op);
list_del(&op->list); list_del(&op->list);
synchronize_rcu();
bcm_remove_op(op); bcm_remove_op(op);
return 1; /* done */ return 1; /* done */
} }
......
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