MLK-19787 can: flexcan: fix CAN can't receive remote request frame
authorJoakim Zhang <qiangqing.zhang@nxp.com>
Thu, 18 Oct 2018 05:06:19 +0000 (13:06 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
The flexcan driver allocates canfd-skb no matter whether use CAN FD
mode or not, it's unreasonable due to it will affect the parse of the
remote request frame.

To fix the issue, allocating can-skb with "alloc_can_skb()" in normal
mode and canfd-skb with "alloc_canfd_skb()" in fd mode.

Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
Signed-off-by: Arulpandiyan Vadivel <arulpandiyan_vadivel@mentor.com>
drivers/net/can/flexcan.c
drivers/net/can/rx-offload.c
include/linux/can/rx-offload.h

index a98129d..a74fa50 100644 (file)
@@ -1723,12 +1723,14 @@ static int flexcan_probe(struct platform_device *pdev)
        priv->pdata = dev_get_platdata(&pdev->dev);
        priv->devtype_data = devtype_data;
        priv->reg_xceiver = reg_xceiver;
+       priv->offload.is_canfd = false;
 
        if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
                if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) {
                        if (!(of_find_property(np, "disable-fd-mode", NULL))) {
                                priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
                                priv->can.bittiming_const = &flexcan_fd_bittiming_const;
+                               priv->offload.is_canfd = true;
                        }
 
                        priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP_FD;
index 46a9f35..d516e88 100644 (file)
@@ -125,8 +125,12 @@ static struct sk_buff *can_rx_offload_offload_one(struct can_rx_offload *offload
 
        /* If queue is full or skb not available, read to discard mailbox */
        if (likely(skb_queue_len(&offload->skb_queue) <=
-                  offload->skb_queue_len_max))
-               skb = alloc_canfd_skb(offload->dev, &cf);
+                  offload->skb_queue_len_max)) {
+               if (offload->is_canfd)
+                       skb = alloc_canfd_skb(offload->dev, &cf);
+               else
+                       skb = alloc_can_skb(offload->dev, (struct can_frame **)&cf);
+       }
 
        if (!skb) {
                struct canfd_frame cf_overflow;
index e4b1118..6448e7d 100644 (file)
@@ -35,6 +35,8 @@ struct can_rx_offload {
        struct napi_struct napi;
 
        bool inc;
+
+       bool is_canfd;
 };
 
 int can_rx_offload_add_timestamp(struct net_device *dev, struct can_rx_offload *offload);