net: can: rockchip: canfd: Add delay work to check tx errors

Fixes: aed0776380 ("canfd: Support extended frames transmit for rk3568")
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
Change-Id: I7d3ea5ca8ac501d81ec9f0ca15f6e3816080a4b5
This commit is contained in:
Elaine Zhang
2022-10-18 18:21:27 +08:00
committed by Tao Huang
parent 4bf4829448
commit 1377256d12

View File

@@ -230,6 +230,7 @@ struct rockchip_canfd {
u32 rx_fifo_mask;
bool txtorx;
u32 tx_invalid[4];
struct delayed_work tx_err_work;
};
static inline u32 rockchip_canfd_read(const struct rockchip_canfd *priv,
@@ -483,6 +484,25 @@ static int rockchip_canfd_set_mode(struct net_device *ndev,
return 0;
}
static void rockchip_canfd_tx_err_delay_work(struct work_struct *work)
{
struct rockchip_canfd *rcan =
container_of(work, struct rockchip_canfd, tx_err_work.work);
u32 mode, err_code, id;
id = rockchip_canfd_read(rcan, CAN_TXID);
err_code = rockchip_canfd_read(rcan, CAN_ERR_CODE);
if (err_code & 0x1fe0000) {
mode = rockchip_canfd_read(rcan, CAN_MODE);
rockchip_canfd_write(rcan, CAN_MODE, 0);
rockchip_canfd_write(rcan, CAN_MODE, mode);
rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);
schedule_delayed_work(&rcan->tx_err_work, 1);
} else if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && id & CAN_EFF_FLAG) {
schedule_delayed_work(&rcan->tx_err_work, 1);
}
}
/* transmit a CAN message
* message layout in the sk_buff should be like this:
* xx xx xx xx ff ll 00 11 22 33 44 55 66 77
@@ -565,6 +585,9 @@ static int rockchip_canfd_start_xmit(struct sk_buff *skb,
rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && cf->can_id & CAN_EFF_FLAG)
schedule_delayed_work(&rcan->tx_err_work, 1);
can_put_echo_skb(skb, ndev, 0);
return NETDEV_TX_OK;
@@ -706,7 +729,7 @@ static int rockchip_canfd_err(struct net_device *ndev, u32 isr)
stats->rx_packets++;
stats->rx_bytes += cf->can_dlc;
netif_receive_skb(skb);
netif_rx(skb);
return 0;
}
@@ -732,6 +755,7 @@ static irqreturn_t rockchip_canfd_interrupt(int irq, void *dev_id)
stats->tx_bytes += (dlc & DLC_MASK);
stats->tx_packets++;
if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && dlc & FORMAT_MASK) {
cancel_delayed_work(&rcan->tx_err_work);
rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, FORMAT_MASK);
quota = (rockchip_canfd_read(rcan, CAN_RXFC) &
rcan->rx_fifo_mask) >>
@@ -814,6 +838,7 @@ static int rockchip_canfd_close(struct net_device *ndev)
close_candev(ndev);
can_led_event(ndev, CAN_LED_EVENT_STOP);
pm_runtime_put(rcan->dev);
cancel_delayed_work_sync(&rcan->tx_err_work);
netdev_dbg(ndev, "%s\n", __func__);
return 0;
@@ -1036,6 +1061,8 @@ static int rockchip_canfd_probe(struct platform_device *pdev)
ndev->flags |= IFF_ECHO;
rcan->can.restart_ms = 1;
INIT_DELAYED_WORK(&rcan->tx_err_work, rockchip_canfd_tx_err_delay_work);
platform_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, &pdev->dev);