From 12da7a1f3cb6ec5c8a1256bbc17cc931f72f7329 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 27 Jan 2021 09:13:03 +0100 Subject: [PATCH 01/12] can: gw: fix typo This patch fixes a typo found by codespell. Fixes: 94c23097f991 ("can: gw: support modification of Classical CAN DLCs") Link: https://lore.kernel.org/r/20210127085529.2768537-3-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- net/can/gw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/can/gw.c b/net/can/gw.c index 8598d9da0e5f..ba4124805602 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -225,7 +225,7 @@ static void mod_store_ccdlc(struct canfd_frame *cf) if (ccf->len <= CAN_MAX_DLEN) return; - /* potentially broken values are catched in can_can_gw_rcv() */ + /* potentially broken values are caught in can_can_gw_rcv() */ if (ccf->len > CAN_MAX_RAW_DLC) return; From 02ee6808179100b46345f3b4e6ecc083b9d08e9d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 27 Jan 2021 09:13:03 +0100 Subject: [PATCH 02/12] can: flexcan: fix typos This patch fixes two typos found by codespell. Fixes: 812f0116c66a ("can: flexcan: add CAN wakeup function for i.MX8QM") Link: https://lore.kernel.org/r/20210127085529.2768537-2-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 5d9157c655e9..971ada36e37f 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1975,14 +1975,14 @@ static int flexcan_setup_stop_mode_scfw(struct platform_device *pdev) priv = netdev_priv(dev); priv->scu_idx = scu_idx; - /* this function could be defered probe, return -EPROBE_DEFER */ + /* this function could be deferred probe, return -EPROBE_DEFER */ return imx_scu_get_handle(&priv->sc_ipc_handle); } /* flexcan_setup_stop_mode - Setup stop mode for wakeup * * Return: = 0 setup stop mode successfully or doesn't support this feature - * < 0 fail to setup stop mode (could be defered probe) + * < 0 fail to setup stop mode (could be deferred probe) */ static int flexcan_setup_stop_mode(struct platform_device *pdev) { From 6fe27d68b45666381691b6a841a2adbda8c8d153 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Wed, 20 Jan 2021 02:03:55 +0900 Subject: [PATCH 03/12] can: dev: export can_get_state_str() function The can_get_state_str() function is also relevant to the drivers. Export the symbol and make it visible in the can/dev.h header. Link: https://lore.kernel.org/r/20210119170355.12040-1-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/dev.c | 3 ++- include/linux/can/dev.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index 01e4a194f187..d9281ae853f8 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -74,7 +74,7 @@ static int can_rx_state_to_frame(struct net_device *dev, enum can_state state) } } -static const char *can_get_state_str(const enum can_state state) +const char *can_get_state_str(const enum can_state state) { switch (state) { case CAN_STATE_ERROR_ACTIVE: @@ -95,6 +95,7 @@ static const char *can_get_state_str(const enum can_state state) return ""; } +EXPORT_SYMBOL_GPL(can_get_state_str); void can_change_state(struct net_device *dev, struct can_frame *cf, enum can_state tx_state, enum can_state rx_state) diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 7faf6a37d5b2..ac4d83a1ab81 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -123,6 +123,7 @@ void unregister_candev(struct net_device *dev); int can_restart_now(struct net_device *dev); void can_bus_off(struct net_device *dev); +const char *can_get_state_str(const enum can_state state); void can_change_state(struct net_device *dev, struct can_frame *cf, enum can_state tx_state, enum can_state rx_state); From 54eca60b1c94fb1de3e59a936d428a291879de8a Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 17 Jan 2021 23:06:28 +0100 Subject: [PATCH 04/12] can: length: can_fd_len2dlc(): make legnth calculation readable again In commit 652562e5ff06 ("can: length: can_fd_len2dlc(): simplify length calculcation") the readability of the code degraded and became more error prone. To counteract this, partially convert that patch and replace open coded values (of the original code) with proper defines. Fixes: 652562e5ff06 ("can: length: can_fd_len2dlc(): simplify length calculcation") Cc: Vincent MAILHOL Link: https://lore.kernel.org/r/20210118201346.79422-1-socketcan@hartkopp.net Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/length.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/dev/length.c b/drivers/net/can/dev/length.c index d35c4e82314d..b48140b1102e 100644 --- a/drivers/net/can/dev/length.c +++ b/drivers/net/can/dev/length.c @@ -27,12 +27,17 @@ static const u8 len2dlc[] = { 13, 13, 13, 13, 13, 13, 13, 13, /* 25 - 32 */ 14, 14, 14, 14, 14, 14, 14, 14, /* 33 - 40 */ 14, 14, 14, 14, 14, 14, 14, 14, /* 41 - 48 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 49 - 56 */ + 15, 15, 15, 15, 15, 15, 15, 15 /* 57 - 64 */ }; /* map the sanitized data length to an appropriate data length code */ u8 can_fd_len2dlc(u8 len) { - if (len >= ARRAY_SIZE(len2dlc)) + /* check for length mapping table size at build time */ + BUILD_BUG_ON(ARRAY_SIZE(len2dlc) != CANFD_MAX_DLEN + 1); + + if (unlikely(len > CANFD_MAX_DLEN)) return CANFD_MAX_DLC; return len2dlc[len]; From 22d63be91c5016207d0de25ed279707865f07e4f Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sun, 24 Jan 2021 07:09:16 -0800 Subject: [PATCH 05/12] can: mcba_usb: remove h from printk format specifier This change fixes the checkpatch warning described in this commit commit cbacb5ab0aa0 ("docs: printk-formats: Stop encouraging use of unnecessary %h[xudi] and %hh[xudi]") Standard integer promotion is already done and %hx and %hhx is useless so do not encourage the use of %hh[xudi] or %h[xudi]. Link: https://lore.kernel.org/r/20210124150916.1920434-1-trix@redhat.com Signed-off-by: Tom Rix Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/mcba_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c index 4232a7126c1b..1f649d178010 100644 --- a/drivers/net/can/usb/mcba_usb.c +++ b/drivers/net/can/usb/mcba_usb.c @@ -466,7 +466,7 @@ static void mcba_usb_process_ka_usb(struct mcba_priv *priv, struct mcba_usb_msg_ka_usb *msg) { if (unlikely(priv->usb_ka_first_pass)) { - netdev_info(priv->netdev, "PIC USB version %hhu.%hhu\n", + netdev_info(priv->netdev, "PIC USB version %u.%u\n", msg->soft_ver_major, msg->soft_ver_minor); priv->usb_ka_first_pass = false; @@ -492,7 +492,7 @@ static void mcba_usb_process_ka_can(struct mcba_priv *priv, struct mcba_usb_msg_ka_can *msg) { if (unlikely(priv->can_ka_first_pass)) { - netdev_info(priv->netdev, "PIC CAN version %hhu.%hhu\n", + netdev_info(priv->netdev, "PIC CAN version %u.%u\n", msg->soft_ver_major, msg->soft_ver_minor); priv->can_ka_first_pass = false; @@ -554,7 +554,7 @@ static void mcba_usb_process_rx(struct mcba_priv *priv, break; default: - netdev_warn(priv->netdev, "Unsupported msg (0x%hhX)", + netdev_warn(priv->netdev, "Unsupported msg (0x%X)", msg->cmd_id); break; } From cdc4c698e4be256634e722494dac0fa40e4137e2 Mon Sep 17 00:00:00 2001 From: Su Yanjun Date: Fri, 22 Jan 2021 16:13:34 +0800 Subject: [PATCH 06/12] can: mcp251xfd: replace sizeof(u32) with val_bytes in regmap The sizeof(u32) is hardcoded. It's better to use the config value from the regmap. It increases the size of target object, but it's flexible when new mcp chip need other val_bytes. Link: https://lore.kernel.org/r/20210122081334.213957-1-suyanjun218@gmail.com Signed-off-by: Su Yanjun Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 00e9855c23d1..897c9310266a 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1308,6 +1308,7 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv, const u8 offset, const u8 len) { const struct mcp251xfd_tx_ring *tx_ring = priv->tx; + const int val_bytes = regmap_get_val_bytes(priv->map_rx); if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) && (offset > tx_ring->obj_num || @@ -1322,7 +1323,7 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv, return regmap_bulk_read(priv->map_rx, mcp251xfd_get_tef_obj_addr(offset), hw_tef_obj, - sizeof(*hw_tef_obj) / sizeof(u32) * len); + sizeof(*hw_tef_obj) / val_bytes * len); } static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) @@ -1510,12 +1511,13 @@ mcp251xfd_rx_obj_read(const struct mcp251xfd_priv *priv, struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj, const u8 offset, const u8 len) { + const int val_bytes = regmap_get_val_bytes(priv->map_rx); int err; err = regmap_bulk_read(priv->map_rx, mcp251xfd_get_rx_obj_addr(ring, offset), hw_rx_obj, - len * ring->obj_size / sizeof(u32)); + len * ring->obj_size / val_bytes); return err; } @@ -2137,6 +2139,7 @@ static int mcp251xfd_handle_spicrcif(struct mcp251xfd_priv *priv) static irqreturn_t mcp251xfd_irq(int irq, void *dev_id) { struct mcp251xfd_priv *priv = dev_id; + const int val_bytes = regmap_get_val_bytes(priv->map_reg); irqreturn_t handled = IRQ_NONE; int err; @@ -2162,7 +2165,7 @@ static irqreturn_t mcp251xfd_irq(int irq, void *dev_id) err = regmap_bulk_read(priv->map_reg, MCP251XFD_REG_INT, &priv->regs_status, sizeof(priv->regs_status) / - sizeof(u32)); + val_bytes); if (err) goto out_fail; From 9845b8f530196fd86fcc46c1c1298bf94b1604bf Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 20 Dec 2020 14:02:29 +0100 Subject: [PATCH 07/12] can: mcp251xfd: mcp251xfd_start_xmit(): use mcp251xfd_get_tx_free() to check TX is is full This patch replaces an open coded check if the TX ring is full by a check if mcp251xfd_get_tx_free() returns 0. Link: https://lore.kernel.org/r/20210114153448.1506901-2-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 897c9310266a..1dbb87c28049 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -2436,7 +2436,7 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, /* Stop queue if we occupy the complete TX FIFO */ tx_head = mcp251xfd_get_tx_head(tx_ring); tx_ring->head++; - if (tx_ring->head - tx_ring->tail >= tx_ring->obj_num) + if (mcp251xfd_get_tx_free(tx_ring) == 0) netif_stop_queue(ndev); can_put_echo_skb(skb, ndev, tx_head, 0); From 561aa5b4ce223064ea655da899013bec5326ec45 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 21 Dec 2020 21:48:20 +0100 Subject: [PATCH 08/12] can: mcp251xfd: mcp251xfd_tx_obj_from_skb(): clean up padding of CAN-FD frames CAN-FD frames have only specific frame length (0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64). A CAN-FD frame provided by user space might not cover the whole CAN-FD frame. To avoid sending garbage over the CAN bus the driver pads the CAN frame with 0x0 (if MCP251XFD_SANITIZE_CAN is activated). This patch cleans up the pad len calculation. Rounding to full u32 brings no benefit, in case of CRC transfers, the hw_tx_obj->data is not aligned to u32 anyway. Link: https://lore.kernel.org/r/20210114153448.1506901-3-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 1dbb87c28049..aa992e71d787 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -2303,7 +2303,7 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv, union mcp251xfd_tx_obj_load_buf *load_buf; u8 dlc; u32 id, flags; - int offset, len; + int pad_len, len; if (cfd->can_id & CAN_EFF_FLAG) { u32 sid, eid; @@ -2351,13 +2351,14 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv, put_unaligned_le32(id, &hw_tx_obj->id); put_unaligned_le32(flags, &hw_tx_obj->flags); - /* Clear data at end of CAN frame */ - offset = round_down(cfd->len, sizeof(u32)); - len = round_up(can_fd_dlc2len(dlc), sizeof(u32)) - offset; - if (MCP251XFD_SANITIZE_CAN && len) - memset(hw_tx_obj->data + offset, 0x0, len); + /* Copy data */ memcpy(hw_tx_obj->data, cfd->data, cfd->len); + /* Clear unused data at end of CAN frame */ + pad_len = can_fd_dlc2len(dlc) - cfd->len; + if (MCP251XFD_SANITIZE_CAN && pad_len) + memset(hw_tx_obj->data + cfd->len, 0x0, pad_len); + /* Number of bytes to be written into the RAM of the controller */ len = sizeof(hw_tx_obj->id) + sizeof(hw_tx_obj->flags); if (MCP251XFD_SANITIZE_CAN) From e20b85c7eb2e91d9db166ac8b08eec61c0164e9b Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 21 Dec 2020 21:34:50 +0100 Subject: [PATCH 09/12] can: mcp251xfd: mcp251xfd_hw_rx_obj_to_skb(): don't copy data for RTR CAN frames in RX-path In Classical CAN there are RTR frames. RTR frames have the RTR bit set, may have a dlc != 0, but contain no data. This patch changes the RX-path to no copy any data for RTR frames, so that the data field in the CAN frame stays 0x0. Link: https://lore.kernel.org/r/20210114153448.1506901-4-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index aa992e71d787..92816be4f3d4 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1474,7 +1474,8 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, hw_rx_obj->flags)); } - memcpy(cfd->data, hw_rx_obj->data, cfd->len); + if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)) + memcpy(cfd->data, hw_rx_obj->data, cfd->len); } static int From a68eda203676d7504dbf02f50366d81928ab45bf Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 21 Dec 2020 21:34:50 +0100 Subject: [PATCH 10/12] can: mcp251xfd: mcp251xfd_tx_obj_from_skb(): don't copy data for RTR CAN frames in TX-path In Classical CAN there are RTR frames. RTR frames have the RTR bit set, may have a dlc != 0, but contain no data. This patch optimizes the TX-path to not copy any data for RTR frames. Link: https://lore.kernel.org/r/20210114153448.1506901-5-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 92816be4f3d4..e6d98e172a47 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -2304,7 +2304,7 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv, union mcp251xfd_tx_obj_load_buf *load_buf; u8 dlc; u32 id, flags; - int pad_len, len; + int len_sanitized = 0, len; if (cfd->can_id & CAN_EFF_FLAG) { u32 sid, eid; @@ -2331,6 +2331,8 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv, if (cfd->can_id & CAN_RTR_FLAG) flags |= MCP251XFD_OBJ_FLAGS_RTR; + else + len_sanitized = canfd_sanitize_len(cfd->len); /* CANFD */ if (can_is_canfd_skb(skb)) { @@ -2356,14 +2358,18 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv, memcpy(hw_tx_obj->data, cfd->data, cfd->len); /* Clear unused data at end of CAN frame */ - pad_len = can_fd_dlc2len(dlc) - cfd->len; - if (MCP251XFD_SANITIZE_CAN && pad_len) - memset(hw_tx_obj->data + cfd->len, 0x0, pad_len); + if (MCP251XFD_SANITIZE_CAN && len_sanitized) { + int pad_len; + + pad_len = len_sanitized - cfd->len; + if (pad_len) + memset(hw_tx_obj->data + cfd->len, 0x0, pad_len); + } /* Number of bytes to be written into the RAM of the controller */ len = sizeof(hw_tx_obj->id) + sizeof(hw_tx_obj->flags); if (MCP251XFD_SANITIZE_CAN) - len += round_up(can_fd_dlc2len(dlc), sizeof(u32)); + len += round_up(len_sanitized, sizeof(u32)); else len += round_up(cfd->len, sizeof(u32)); From 86f1e3b1dd9f08408b12405059e2ab3cf9690066 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 20 Dec 2020 18:47:51 +0100 Subject: [PATCH 11/12] can: mcp251xfd: add len8_dlc support This patch adds support for the Classical CAN raw DLC functionality to send and receive DLC values from 9 ... 15 to the mcp251xfd driver. Link: https://lore.kernel.org/r/20210114153448.1506901-6-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- .../net/can/spi/mcp251xfd/mcp251xfd-core.c | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index e6d98e172a47..8f78a29db39b 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1439,6 +1439,7 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, struct sk_buff *skb) { struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + u8 dlc; if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_IDE) { u32 sid, eid; @@ -1454,9 +1455,10 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, hw_rx_obj->id); } + dlc = FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC, hw_rx_obj->flags); + /* CANFD */ if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF) { - u8 dlc; if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_ESI) cfd->flags |= CANFD_ESI; @@ -1464,14 +1466,13 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_BRS) cfd->flags |= CANFD_BRS; - dlc = FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC, hw_rx_obj->flags); cfd->len = can_fd_dlc2len(dlc); } else { if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR) cfd->can_id |= CAN_RTR_FLAG; - cfd->len = can_cc_dlc2len(FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC, - hw_rx_obj->flags)); + can_frame_set_cc_len((struct can_frame *)cfd, dlc, + priv->can.ctrlmode); } if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)) @@ -2325,9 +2326,7 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv, * harm, only the lower 7 bits will be transferred into the * TEF object. */ - dlc = can_fd_len2dlc(cfd->len); - flags |= FIELD_PREP(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, seq) | - FIELD_PREP(MCP251XFD_OBJ_FLAGS_DLC, dlc); + flags |= FIELD_PREP(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, seq); if (cfd->can_id & CAN_RTR_FLAG) flags |= MCP251XFD_OBJ_FLAGS_RTR; @@ -2343,8 +2342,15 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv, if (cfd->flags & CANFD_BRS) flags |= MCP251XFD_OBJ_FLAGS_BRS; + + dlc = can_fd_len2dlc(cfd->len); + } else { + dlc = can_get_cc_dlc((struct can_frame *)cfd, + priv->can.ctrlmode); } + flags |= FIELD_PREP(MCP251XFD_OBJ_FLAGS_DLC, dlc); + load_buf = &tx_obj->buf; if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_TX) hw_tx_obj = &load_buf->crc.hw_tx_obj; @@ -2896,7 +2902,8 @@ static int mcp251xfd_probe(struct spi_device *spi) priv->can.data_bittiming_const = &mcp251xfd_data_bittiming_const; priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING | - CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO; + CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO | + CAN_CTRLMODE_CC_LEN8_DLC; priv->ndev = ndev; priv->spi = spi; priv->rx_int = rx_int; From 4162e18e949ba520d5116ac0323500355479a00e Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 13 Dec 2020 17:25:15 +0100 Subject: [PATCH 12/12] can: mcp251xfd: add BQL support This patch adds BQL support to the driver. Support for netdev_xmit_more() will be added in a separate patch series. Link: https://lore.kernel.org/r/20210114153448.1506901-7-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde --- .../net/can/spi/mcp251xfd/mcp251xfd-core.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 8f78a29db39b..3638b474d86b 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -335,6 +335,8 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv) u8 len; int i, j; + netdev_reset_queue(priv->ndev); + /* TEF */ tef_ring = priv->tef; tef_ring->head = 0; @@ -1249,7 +1251,8 @@ mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq) static int mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, - const struct mcp251xfd_hw_tef_obj *hw_tef_obj) + const struct mcp251xfd_hw_tef_obj *hw_tef_obj, + unsigned int *frame_len_ptr) { struct net_device_stats *stats = &priv->ndev->stats; u32 seq, seq_masked, tef_tail_masked; @@ -1271,7 +1274,8 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload, mcp251xfd_get_tef_tail(priv), - hw_tef_obj->ts, NULL); + hw_tef_obj->ts, + frame_len_ptr); stats->tx_packets++; priv->tef->tail++; @@ -1329,6 +1333,7 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv, static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) { struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX]; + unsigned int total_frame_len = 0; u8 tef_tail, len, l; int err, i; @@ -1350,7 +1355,9 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) } for (i = 0; i < len; i++) { - err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i]); + unsigned int frame_len; + + err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len); /* -EAGAIN means the Sequence Number in the TEF * doesn't match our tef_tail. This can happen if we * read the TEF objects too early. Leave loop let the @@ -1360,6 +1367,8 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) goto out_netif_wake_queue; if (err) return err; + + total_frame_len += frame_len; } out_netif_wake_queue: @@ -1390,6 +1399,7 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) return err; tx_ring->tail += len; + netdev_completed_queue(priv->ndev, len, total_frame_len); err = mcp251xfd_check_tef_tail(priv); if (err) @@ -2435,6 +2445,7 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, struct mcp251xfd_priv *priv = netdev_priv(ndev); struct mcp251xfd_tx_ring *tx_ring = priv->tx; struct mcp251xfd_tx_obj *tx_obj; + unsigned int frame_len; u8 tx_head; int err; @@ -2453,7 +2464,9 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, if (mcp251xfd_get_tx_free(tx_ring) == 0) netif_stop_queue(ndev); - can_put_echo_skb(skb, ndev, tx_head, 0); + frame_len = can_skb_get_frame_len(skb); + can_put_echo_skb(skb, ndev, tx_head, frame_len); + netdev_sent_queue(priv->ndev, frame_len); err = mcp251xfd_tx_obj_write(priv, tx_obj); if (err)