OSDN Git Service

can: mcp251xfd: add len8_dlc support
authorMarc Kleine-Budde <mkl@pengutronix.de>
Sun, 20 Dec 2020 17:47:51 +0000 (18:47 +0100)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Wed, 27 Jan 2021 09:01:47 +0000 (10:01 +0100)
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 <mkl@pengutronix.de>
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c

index e6d98e1..8f78a29 100644 (file)
@@ -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;