From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
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