diff options
author | Maxime Ripard <maxime@cerno.tech> | 2022-09-14 12:22:18 +0100 |
---|---|---|
committer | Maxime Ripard <maxime@cerno.tech> | 2022-09-14 12:22:18 +0100 |
commit | a108772d03d8bdb43258218b00bfe43bbe1e8800 (patch) | |
tree | 11b1f413ab384f2b5de0773f01b6886e2c601f8b /drivers/net/can/spi | |
parent | 75cebd664d57a78af3e46c14bd2659df0a08847b (diff) | |
parent | 213cb76ddc8b875e772f9f4d173feefa122716af (diff) |
Merge drm/drm-next into drm-misc-next
We need 6.0-rc1 to merge the backlight rework PR.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Diffstat (limited to 'drivers/net/can/spi')
-rw-r--r-- | drivers/net/can/spi/hi311x.c | 12 | ||||
-rw-r--r-- | drivers/net/can/spi/mcp251x.c | 24 | ||||
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 20 | ||||
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c | 2 | ||||
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c | 1 |
6 files changed, 49 insertions, 11 deletions
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c index ebc4ebb44c98..b87dc420428d 100644 --- a/drivers/net/can/spi/hi311x.c +++ b/drivers/net/can/spi/hi311x.c @@ -20,6 +20,7 @@ #include <linux/completion.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/ethtool.h> #include <linux/freezer.h> #include <linux/interrupt.h> #include <linux/io.h> @@ -667,8 +668,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) txerr = hi3110_read(spi, HI3110_READ_TEC); rxerr = hi3110_read(spi, HI3110_READ_REC); - cf->data[6] = txerr; - cf->data[7] = rxerr; tx_state = txerr >= rxerr ? new_state : 0; rx_state = txerr <= rxerr ? new_state : 0; can_change_state(net, cf, tx_state, rx_state); @@ -681,6 +680,10 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) hi3110_hw_sleep(spi); break; } + } else { + cf->can_id |= CAN_ERR_CNT; + cf->data[6] = txerr; + cf->data[7] = rxerr; } } @@ -800,6 +803,10 @@ static const struct net_device_ops hi3110_netdev_ops = { .ndo_start_xmit = hi3110_hard_start_xmit, }; +static const struct ethtool_ops hi3110_ethtool_ops = { + .get_ts_info = ethtool_op_get_ts_info, +}; + static const struct of_device_id hi3110_of_match[] = { { .compatible = "holt,hi3110", @@ -854,6 +861,7 @@ static int hi3110_can_probe(struct spi_device *spi) goto out_free; net->netdev_ops = &hi3110_netdev_ops; + net->ethtool_ops = &hi3110_ethtool_ops; net->flags |= IFF_ECHO; priv = netdev_priv(net); diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c index 666a4505a55a..c320de474f40 100644 --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c @@ -26,6 +26,7 @@ #include <linux/completion.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/ethtool.h> #include <linux/freezer.h> #include <linux/gpio.h> #include <linux/gpio/driver.h> @@ -1069,9 +1070,6 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); - /* mask out flags we don't care about */ - intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR; - /* receive buffer 0 */ if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); @@ -1081,6 +1079,18 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) if (mcp251x_is_2510(spi)) mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00); + + /* check if buffer 1 is already known to be full, no need to re-read */ + if (!(intf & CANINTF_RX1IF)) { + u8 intf1, eflag1; + + /* intf needs to be read again to avoid a race condition */ + mcp251x_read_2regs(spi, CANINTF, &intf1, &eflag1); + + /* combine flags from both operations for error handling */ + intf |= intf1; + eflag |= eflag1; + } } /* receive buffer 1 */ @@ -1091,6 +1101,9 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) clear_intf |= CANINTF_RX1IF; } + /* mask out flags we don't care about */ + intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR; + /* any error or tx interrupt we need to clear? */ if (intf & (CANINTF_ERR | CANINTF_TX)) clear_intf |= intf & (CANINTF_ERR | CANINTF_TX); @@ -1248,6 +1261,10 @@ static const struct net_device_ops mcp251x_netdev_ops = { .ndo_change_mtu = can_change_mtu, }; +static const struct ethtool_ops mcp251x_ethtool_ops = { + .get_ts_info = ethtool_op_get_ts_info, +}; + static const struct of_device_id mcp251x_of_match[] = { { .compatible = "microchip,mcp2510", @@ -1313,6 +1330,7 @@ static int mcp251x_can_probe(struct spi_device *spi) goto out_free; net->netdev_ops = &mcp251x_netdev_ops; + net->ethtool_ops = &mcp251x_ethtool_ops; net->flags |= IFF_ECHO; priv = netdev_priv(net); diff --git a/drivers/net/can/spi/mcp251xfd/Kconfig b/drivers/net/can/spi/mcp251xfd/Kconfig index dd0fc0a54be1..877e4356010d 100644 --- a/drivers/net/can/spi/mcp251xfd/Kconfig +++ b/drivers/net/can/spi/mcp251xfd/Kconfig @@ -2,6 +2,7 @@ config CAN_MCP251XFD tristate "Microchip MCP251xFD SPI CAN controllers" + select CAN_RX_OFFLOAD select REGMAP select WANT_DEV_COREDUMP help diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 9b47b07162fe..68df6d4641b5 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1099,6 +1099,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) err = mcp251xfd_get_berr_counter(priv->ndev, &bec); if (err) return err; + cf->can_id |= CAN_ERR_CNT; cf->data[6] = bec.txerr; cf->data[7] = bec.rxerr; } @@ -1670,6 +1671,7 @@ static const struct net_device_ops mcp251xfd_netdev_ops = { .ndo_open = mcp251xfd_open, .ndo_stop = mcp251xfd_stop, .ndo_start_xmit = mcp251xfd_start_xmit, + .ndo_eth_ioctl = can_eth_ioctl_hwts, .ndo_change_mtu = can_change_mtu, }; @@ -1690,8 +1692,8 @@ static int mcp251xfd_register_chip_detect(struct mcp251xfd_priv *priv) u32 osc; int err; - /* The OSC_LPMEN is only supported on MCP2518FD, so use it to - * autodetect the model. + /* The OSC_LPMEN is only supported on MCP2518FD and MCP251863, + * so use it to autodetect the model. */ err = regmap_update_bits(priv->map_reg, MCP251XFD_REG_OSC, MCP251XFD_REG_OSC_LPMEN, @@ -1703,10 +1705,18 @@ static int mcp251xfd_register_chip_detect(struct mcp251xfd_priv *priv) if (err) return err; - if (osc & MCP251XFD_REG_OSC_LPMEN) - devtype_data = &mcp251xfd_devtype_data_mcp2518fd; - else + if (osc & MCP251XFD_REG_OSC_LPMEN) { + /* We cannot distinguish between MCP2518FD and + * MCP251863. If firmware specifies MCP251863, keep + * it, otherwise set to MCP2518FD. + */ + if (mcp251xfd_is_251863(priv)) + devtype_data = &mcp251xfd_devtype_data_mcp251863; + else + devtype_data = &mcp251xfd_devtype_data_mcp2518fd; + } else { devtype_data = &mcp251xfd_devtype_data_mcp2517fd; + } if (!mcp251xfd_is_251XFD(priv) && priv->devtype_data.model != devtype_data->model) { diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c index c991b30bc9f0..004eaf96262b 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c @@ -253,7 +253,7 @@ void mcp251xfd_dump(const struct mcp251xfd_priv *priv) file_size += mcp251xfd_dump_reg_space[i].size / sizeof(u32) * sizeof(struct mcp251xfd_dump_object_reg); - /* TEF ring, RX ring, TX rings */ + /* TEF ring, RX rings, TX ring */ rings_num = 1 + priv->rx_ring_num + 1; obj_num += rings_num; file_size += rings_num * __MCP251XFD_DUMP_OBJECT_RING_KEY_MAX * diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c index 6c7a57f16cc6..3585f02575df 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c @@ -124,6 +124,7 @@ static const struct ethtool_ops mcp251xfd_ethtool_ops = { .set_ringparam = mcp251xfd_ring_set_ringparam, .get_coalesce = mcp251xfd_ring_get_coalesce, .set_coalesce = mcp251xfd_ring_set_coalesce, + .get_ts_info = can_ethtool_op_get_ts_info_hwts, }; void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv) |