From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/net/can/rockchip/rockchip_canfd.c | 77 ++++++++++++++++++++++++++++---------- 1 files changed, 57 insertions(+), 20 deletions(-) diff --git a/kernel/drivers/net/can/rockchip/rockchip_canfd.c b/kernel/drivers/net/can/rockchip/rockchip_canfd.c index abdcdb5..dba7f14 100644 --- a/kernel/drivers/net/can/rockchip/rockchip_canfd.c +++ b/kernel/drivers/net/can/rockchip/rockchip_canfd.c @@ -214,6 +214,8 @@ #define CAN_RXFRD_OFFSET(n) (CAN_RXFRD + CAN_RF_SIZE * (n)) #define CAN_RX_FILTER_MASK 0x1fffffff +#define NOACK_ERR_FLAG 0xc200800 +#define CAN_BUSOFF_FLAG 0x20 #define DRV_NAME "rockchip_canfd" @@ -234,6 +236,7 @@ bool txtorx; u32 tx_invalid[4]; struct delayed_work tx_err_work; + u32 delay_time_ms; }; static inline u32 rockchip_canfd_read(const struct rockchip_canfd *priv, @@ -357,6 +360,12 @@ rockchip_canfd_write(rcan, CAN_DBTP, reg_btp); } + if (bt->bitrate > 200000) + rcan->delay_time_ms = 1; + else if (bt->bitrate > 50000) + rcan->delay_time_ms = 5; + else + rcan->delay_time_ms = 20; netdev_dbg(ndev, "%s NBTP=0x%08x, DBTP=0x%08x, TDCR=0x%08x\n", __func__, rockchip_canfd_read(rcan, CAN_NBTP), @@ -428,6 +437,10 @@ if (rcan->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) val |= MODE_SELF_TEST | MODE_LBACK; + /* Listen-only mode */ + if (rcan->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) + val |= MODE_SILENT; + rockchip_canfd_write(rcan, CAN_MODE, val); rockchip_canfd_set_bittiming(ndev); @@ -487,13 +500,27 @@ { struct rockchip_canfd *rcan = container_of(work, struct rockchip_canfd, tx_err_work.work); - u32 mode; + u32 mode, err_code; 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); + err_code = rockchip_canfd_read(rcan, CAN_ERR_CODE); + if ((err_code & NOACK_ERR_FLAG) == NOACK_ERR_FLAG) { + rockchip_canfd_write(rcan, CAN_MODE, + rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX); + rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ); + rockchip_canfd_write(rcan, CAN_MODE, + rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX)); + schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms)); + } else { + rockchip_canfd_write(rcan, CAN_MODE, 0); + rockchip_canfd_write(rcan, CAN_MODE, mode); + rockchip_canfd_write(rcan, CAN_MODE, + rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX); + rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ); + rockchip_canfd_write(rcan, CAN_MODE, + rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX)); + schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms)); + } } /* transmit a CAN message @@ -569,10 +596,9 @@ for (i = 0; i < cf->len; i += 4) rockchip_canfd_write(rcan, CAN_TXDAT0 + i, *(u32 *)(cf->data + i)); + can_put_echo_skb(skb, ndev, 0); rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ); local_irq_restore(flags); - can_put_echo_skb(skb, ndev, 0); - return NETDEV_TX_OK; } @@ -583,12 +609,13 @@ rockchip_canfd_write(rcan, CAN_TXDAT0 + i, *(u32 *)(cf->data + i)); - rockchip_canfd_write(rcan, CAN_CMD, cmd); - - schedule_delayed_work(&rcan->tx_err_work, 1); - can_put_echo_skb(skb, ndev, 0); - + rockchip_canfd_write(rcan, CAN_MODE, + rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX); + rockchip_canfd_write(rcan, CAN_CMD, cmd); + rockchip_canfd_write(rcan, CAN_MODE, + rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX)); + schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms)); return NETDEV_TX_OK; } @@ -740,9 +767,6 @@ cf->data[7] = rxerr; } - if (isr & TX_LOSTARB_INT) - schedule_delayed_work(&rcan->tx_err_work, 1); - if (isr & BUS_OFF_INT) { rcan->can.state = CAN_STATE_BUS_OFF; rcan->can.can_stats.bus_off++; @@ -772,8 +796,14 @@ } if (rcan->can.state >= CAN_STATE_BUS_OFF || - ((sta_reg & 0x20) == 0x20)) - can_bus_off(ndev); + ((sta_reg & CAN_BUSOFF_FLAG) == CAN_BUSOFF_FLAG)) { + cancel_delayed_work(&rcan->tx_err_work); + netif_stop_queue(ndev); + rockchip_canfd_stop(ndev); + can_free_echo_skb(ndev, 0); + rockchip_canfd_start(ndev); + netif_start_queue(ndev); + } stats->rx_packets++; stats->rx_bytes += cf->can_dlc; @@ -788,13 +818,14 @@ struct rockchip_canfd *rcan = netdev_priv(ndev); struct net_device_stats *stats = &ndev->stats; u32 err_int = ERR_WARN_INT | RX_BUF_OV_INT | PASSIVE_ERR_INT | - TX_LOSTARB_INT | BUS_ERR_INT | BUS_OFF_INT; + BUS_ERR_INT | BUS_OFF_INT; u32 isr; u32 dlc = 0; u32 quota, work_done = 0; isr = rockchip_canfd_read(rcan, CAN_INT); if (isr & TX_FINISH_INT) { + cancel_delayed_work(&rcan->tx_err_work); dlc = rockchip_canfd_read(rcan, CAN_TXFIC); /* transmission complete interrupt */ if (dlc & FDF_MASK) @@ -802,7 +833,6 @@ else stats->tx_bytes += (dlc & DLC_MASK); stats->tx_packets++; - cancel_delayed_work(&rcan->tx_err_work); if (rcan->txtorx && rcan->mode <= ROCKCHIP_RK3568_CAN_MODE && dlc & FORMAT_MASK) { rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, FORMAT_MASK); quota = rockchip_canfd_get_rx_fifo_cnt(ndev); @@ -814,6 +844,10 @@ rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ); rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, 0); } + if (read_poll_timeout_atomic(rockchip_canfd_read, quota, + !(quota & 0x3), + 0, 5000000, false, rcan, CAN_CMD)) + netdev_err(ndev, "Warning: wait tx req timeout!\n"); rockchip_canfd_write(rcan, CAN_CMD, 0); can_get_echo_skb(ndev, 0); netif_wake_queue(ndev); @@ -825,7 +859,10 @@ rockchip_canfd_write(rcan, CAN_INT_MASK, 0x1); napi_schedule(&rcan->napi); } else { - quota = rockchip_canfd_get_rx_fifo_cnt(ndev); + work_done = 0; + quota = (rockchip_canfd_read(rcan, CAN_RXFC) & + rcan->rx_fifo_mask) >> + rcan->rx_fifo_shift; if (quota) { while (work_done < quota) work_done += rockchip_canfd_rx(ndev); -- Gitblit v1.6.2