// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
 *
 * CTU CAN FD IP Core
 *
 * Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU
 * Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded
 * Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU
 * Copyright (C) 2018-2022 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded
 *
 * Project advisors:
 *     Jiri Novak <jnovak@fel.cvut.cz>
 *     Pavel Pisa <pisa@cmp.felk.cvut.cz>
 *
 * Department of Measurement         (http://meas.fel.cvut.cz/)
 * Faculty of Electrical Engineering (http://www.fel.cvut.cz)
 * Czech Technical University        (http://www.cvut.cz/)
 ******************************************************************************/

#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/bitfield.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/can/error.h>
#include <linux/pm_runtime.h>

#include "ctucanfd.h"
#include "ctucanfd_kregs.h"
#include "ctucanfd_kframe.h"

#ifdef DEBUG
#define  ctucan_netdev_dbg(ndev, args...) \
		netdev_dbg(ndev, args)
#else
#define ctucan_netdev_dbg(...) do { } while (0)
#endif

#define CTUCANFD_ID 0xCAFD

/* TX buffer rotation:
 * - when a buffer transitions to empty state, rotate order and priorities
 * - if more buffers seem to transition at the same time, rotate by the number of buffers
 * - it may be assumed that buffers transition to empty state in FIFO order (because we manage
 *   priorities that way)
 * - at frame filling, do not rotate anything, just increment buffer modulo counter
 */

#define CTUCANFD_FLAG_RX_FFW_BUFFERED	1

#define CTUCAN_STATE_TO_TEXT_ENTRY(st) \
		[st] = #st

enum ctucan_txtb_status {
	TXT_NOT_EXIST       = 0x0,
	TXT_RDY             = 0x1,
	TXT_TRAN            = 0x2,
	TXT_ABTP            = 0x3,
	TXT_TOK             = 0x4,
	TXT_ERR             = 0x6,
	TXT_ABT             = 0x7,
	TXT_ETY             = 0x8,
};

enum ctucan_txtb_command {
	TXT_CMD_SET_EMPTY   = 0x01,
	TXT_CMD_SET_READY   = 0x02,
	TXT_CMD_SET_ABORT   = 0x04
};

static const struct can_bittiming_const ctu_can_fd_bit_timing_max = {
	.name = "ctu_can_fd",
	.tseg1_min = 2,
	.tseg1_max = 190,
	.tseg2_min = 1,
	.tseg2_max = 63,
	.sjw_max = 31,
	.brp_min = 1,
	.brp_max = 8,
	.brp_inc = 1,
};

static const struct can_bittiming_const ctu_can_fd_bit_timing_data_max = {
	.name = "ctu_can_fd",
	.tseg1_min = 2,
	.tseg1_max = 94,
	.tseg2_min = 1,
	.tseg2_max = 31,
	.sjw_max = 31,
	.brp_min = 1,
	.brp_max = 2,
	.brp_inc = 1,
};

static const char * const ctucan_state_strings[CAN_STATE_MAX] = {
	CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_ERROR_ACTIVE),
	CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_ERROR_WARNING),
	CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_ERROR_PASSIVE),
	CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_BUS_OFF),
	CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_STOPPED),
	CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_SLEEPING)
};

static void ctucan_write32_le(struct ctucan_priv *priv,
			      enum ctu_can_fd_can_registers reg, u32 val)
{
	iowrite32(val, priv->mem_base + reg);
}

static void ctucan_write32_be(struct ctucan_priv *priv,
			      enum ctu_can_fd_can_registers reg, u32 val)
{
	iowrite32be(val, priv->mem_base + reg);
}

static u32 ctucan_read32_le(struct ctucan_priv *priv,
			    enum ctu_can_fd_can_registers reg)
{
	return ioread32(priv->mem_base + reg);
}

static u32 ctucan_read32_be(struct ctucan_priv *priv,
			    enum ctu_can_fd_can_registers reg)
{
	return ioread32be(priv->mem_base + reg);
}

static void ctucan_write32(struct ctucan_priv *priv, enum ctu_can_fd_can_registers reg, u32 val)
{
	priv->write_reg(priv, reg, val);
}

static u32 ctucan_read32(struct ctucan_priv *priv, enum ctu_can_fd_can_registers reg)
{
	return priv->read_reg(priv, reg);
}

static void ctucan_write_txt_buf(struct ctucan_priv *priv, enum ctu_can_fd_can_registers buf_base,
				 u32 offset, u32 val)
{
	priv->write_reg(priv, buf_base + offset, val);
}

#define CTU_CAN_FD_TXTNF(priv) (!!FIELD_GET(REG_STATUS_TXNF, ctucan_read32(priv, CTUCANFD_STATUS)))
#define CTU_CAN_FD_ENABLED(priv) (!!FIELD_GET(REG_MODE_ENA, ctucan_read32(priv, CTUCANFD_MODE)))

/**
 * ctucan_state_to_str() - Converts CAN controller state code to corresponding text
 * @state:	CAN controller state code
 *
 * Return: Pointer to string representation of the error state
 */
static const char *ctucan_state_to_str(enum can_state state)
{
	const char *txt = NULL;

	if (state >= 0 && state < CAN_STATE_MAX)
		txt = ctucan_state_strings[state];
	return txt ? txt : "UNKNOWN";
}

/**
 * ctucan_reset() - Issues software reset request to CTU CAN FD
 * @ndev:	Pointer to net_device structure
 *
 * Return: 0 for success, -%ETIMEDOUT if CAN controller does not leave reset
 */
static int ctucan_reset(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	int i = 100;

	ctucan_write32(priv, CTUCANFD_MODE, REG_MODE_RST);
	clear_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags);

	do {
		u16 device_id = FIELD_GET(REG_DEVICE_ID_DEVICE_ID,
					  ctucan_read32(priv, CTUCANFD_DEVICE_ID));

		if (device_id == 0xCAFD)
			return 0;
		if (!i--) {
			netdev_warn(ndev, "device did not leave reset\n");
			return -ETIMEDOUT;
		}
		usleep_range(100, 200);
	} while (1);
}

/**
 * ctucan_set_btr() - Sets CAN bus bit timing in CTU CAN FD
 * @ndev:	Pointer to net_device structure
 * @bt:		Pointer to Bit timing structure
 * @nominal:	True - Nominal bit timing, False - Data bit timing
 *
 * Return: 0 - OK, -%EPERM if controller is enabled
 */
static int ctucan_set_btr(struct net_device *ndev, struct can_bittiming *bt, bool nominal)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	int max_ph1_len = 31;
	u32 btr = 0;
	u32 prop_seg = bt->prop_seg;
	u32 phase_seg1 = bt->phase_seg1;

	if (CTU_CAN_FD_ENABLED(priv)) {
		netdev_err(ndev, "BUG! Cannot set bittiming - CAN is enabled\n");
		return -EPERM;
	}

	if (nominal)
		max_ph1_len = 63;

	/* The timing calculation functions have only constraints on tseg1, which is prop_seg +
	 * phase1_seg combined. tseg1 is then split in half and stored into prog_seg and phase_seg1.
	 * In CTU CAN FD, PROP is 6/7 bits wide but PH1 only 6/5, so we must re-distribute the
	 * values here.
	 */
	if (phase_seg1 > max_ph1_len) {
		prop_seg += phase_seg1 - max_ph1_len;
		phase_seg1 = max_ph1_len;
		bt->prop_seg = prop_seg;
		bt->phase_seg1 = phase_seg1;
	}

	if (nominal) {
		btr = FIELD_PREP(REG_BTR_PROP, prop_seg);
		btr |= FIELD_PREP(REG_BTR_PH1, phase_seg1);
		btr |= FIELD_PREP(REG_BTR_PH2, bt->phase_seg2);
		btr |= FIELD_PREP(REG_BTR_BRP, bt->brp);
		btr |= FIELD_PREP(REG_BTR_SJW, bt->sjw);

		ctucan_write32(priv, CTUCANFD_BTR, btr);
	} else {
		btr = FIELD_PREP(REG_BTR_FD_PROP_FD, prop_seg);
		btr |= FIELD_PREP(REG_BTR_FD_PH1_FD, phase_seg1);
		btr |= FIELD_PREP(REG_BTR_FD_PH2_FD, bt->phase_seg2);
		btr |= FIELD_PREP(REG_BTR_FD_BRP_FD, bt->brp);
		btr |= FIELD_PREP(REG_BTR_FD_SJW_FD, bt->sjw);

		ctucan_write32(priv, CTUCANFD_BTR_FD, btr);
	}

	return 0;
}

/**
 * ctucan_set_bittiming() - CAN set nominal bit timing routine
 * @ndev:	Pointer to net_device structure
 *
 * Return: 0 on success, -%EPERM on error
 */
static int ctucan_set_bittiming(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	struct can_bittiming *bt = &priv->can.bittiming;

	/* Note that bt may be modified here */
	return ctucan_set_btr(ndev, bt, true);
}

/**
 * ctucan_set_data_bittiming() - CAN set data bit timing routine
 * @ndev:	Pointer to net_device structure
 *
 * Return: 0 on success, -%EPERM on error
 */
static int ctucan_set_data_bittiming(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	struct can_bittiming *dbt = &priv->can.data_bittiming;

	/* Note that dbt may be modified here */
	return ctucan_set_btr(ndev, dbt, false);
}

/**
 * ctucan_set_secondary_sample_point() - Sets secondary sample point in CTU CAN FD
 * @ndev:	Pointer to net_device structure
 *
 * Return: 0 on success, -%EPERM if controller is enabled
 */
static int ctucan_set_secondary_sample_point(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	struct can_bittiming *dbt = &priv->can.data_bittiming;
	int ssp_offset = 0;
	u32 ssp_cfg = 0; /* No SSP by default */

	if (CTU_CAN_FD_ENABLED(priv)) {
		netdev_err(ndev, "BUG! Cannot set SSP - CAN is enabled\n");
		return -EPERM;
	}

	/* Use SSP for bit-rates above 1 Mbits/s */
	if (dbt->bitrate > 1000000) {
		/* Calculate SSP in minimal time quanta */
		ssp_offset = (priv->can.clock.freq / 1000) * dbt->sample_point / dbt->bitrate;

		if (ssp_offset > 127) {
			netdev_warn(ndev, "SSP offset saturated to 127\n");
			ssp_offset = 127;
		}

		ssp_cfg = FIELD_PREP(REG_TRV_DELAY_SSP_OFFSET, ssp_offset);
		ssp_cfg |= FIELD_PREP(REG_TRV_DELAY_SSP_SRC, 0x1);
	}

	ctucan_write32(priv, CTUCANFD_TRV_DELAY, ssp_cfg);

	return 0;
}

/**
 * ctucan_set_mode() - Sets CTU CAN FDs mode
 * @priv:	Pointer to private data
 * @mode:	Pointer to controller modes to be set
 */
static void ctucan_set_mode(struct ctucan_priv *priv, const struct can_ctrlmode *mode)
{
	u32 mode_reg = ctucan_read32(priv, CTUCANFD_MODE);

	mode_reg = (mode->flags & CAN_CTRLMODE_LOOPBACK) ?
			(mode_reg | REG_MODE_ILBP) :
			(mode_reg & ~REG_MODE_ILBP);

	mode_reg = (mode->flags & CAN_CTRLMODE_LISTENONLY) ?
			(mode_reg | REG_MODE_BMM) :
			(mode_reg & ~REG_MODE_BMM);

	mode_reg = (mode->flags & CAN_CTRLMODE_FD) ?
			(mode_reg | REG_MODE_FDE) :
			(mode_reg & ~REG_MODE_FDE);

	mode_reg = (mode->flags & CAN_CTRLMODE_PRESUME_ACK) ?
			(mode_reg | REG_MODE_ACF) :
			(mode_reg & ~REG_MODE_ACF);

	mode_reg = (mode->flags & CAN_CTRLMODE_FD_NON_ISO) ?
			(mode_reg | REG_MODE_NISOFD) :
			(mode_reg & ~REG_MODE_NISOFD);

	/* One shot mode supported indirectly via Retransmit limit */
	mode_reg &= ~FIELD_PREP(REG_MODE_RTRTH, 0xF);
	mode_reg = (mode->flags & CAN_CTRLMODE_ONE_SHOT) ?
			(mode_reg | REG_MODE_RTRLE) :
			(mode_reg & ~REG_MODE_RTRLE);

	/* Some bits fixed:
	 *   TSTM  - Off, User shall not be able to change REC/TEC by hand during operation
	 */
	mode_reg &= ~REG_MODE_TSTM;

	ctucan_write32(priv, CTUCANFD_MODE, mode_reg);
}

/**
 * ctucan_chip_start() - This routine starts the driver
 * @ndev:	Pointer to net_device structure
 *
 * Routine expects that chip is in reset state. It setups initial
 * Tx buffers for FIFO priorities, sets bittiming, enables interrupts,
 * switches core to operational mode and changes controller
 * state to %CAN_STATE_STOPPED.
 *
 * Return: 0 on success and failure value on error
 */
static int ctucan_chip_start(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	u32 int_ena, int_msk;
	u32 mode_reg;
	int err;
	struct can_ctrlmode mode;

	priv->txb_prio = 0x01234567;
	priv->txb_head = 0;
	priv->txb_tail = 0;
	ctucan_write32(priv, CTUCANFD_TX_PRIORITY, priv->txb_prio);

	/* Configure bit-rates and ssp */
	err = ctucan_set_bittiming(ndev);
	if (err < 0)
		return err;

	err = ctucan_set_data_bittiming(ndev);
	if (err < 0)
		return err;

	err = ctucan_set_secondary_sample_point(ndev);
	if (err < 0)
		return err;

	/* Configure modes */
	mode.flags = priv->can.ctrlmode;
	mode.mask = 0xFFFFFFFF;
	ctucan_set_mode(priv, &mode);

	/* Configure interrupts */
	int_ena = REG_INT_STAT_RBNEI |
		  REG_INT_STAT_TXBHCI |
		  REG_INT_STAT_EWLI |
		  REG_INT_STAT_FCSI;

	/* Bus error reporting -> Allow Error/Arb.lost interrupts */
	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
		int_ena |= REG_INT_STAT_ALI |
			   REG_INT_STAT_BEI;
	}

	int_msk = ~int_ena; /* Mask all disabled interrupts */

	/* It's after reset, so there is no need to clear anything */
	ctucan_write32(priv, CTUCANFD_INT_MASK_SET, int_msk);
	ctucan_write32(priv, CTUCANFD_INT_ENA_SET, int_ena);

	/* Controller enters ERROR_ACTIVE on initial FCSI */
	priv->can.state = CAN_STATE_STOPPED;

	/* Enable the controller */
	mode_reg = ctucan_read32(priv, CTUCANFD_MODE);
	mode_reg |= REG_MODE_ENA;
	ctucan_write32(priv, CTUCANFD_MODE, mode_reg);

	return 0;
}

/**
 * ctucan_do_set_mode() - Sets mode of the driver
 * @ndev:	Pointer to net_device structure
 * @mode:	Tells the mode of the driver
 *
 * This check the drivers state and calls the corresponding modes to set.
 *
 * Return: 0 on success and failure value on error
 */
static int ctucan_do_set_mode(struct net_device *ndev, enum can_mode mode)
{
	int ret;

	switch (mode) {
	case CAN_MODE_START:
		ret = ctucan_reset(ndev);
		if (ret < 0)
			return ret;
		ret = ctucan_chip_start(ndev);
		if (ret < 0) {
			netdev_err(ndev, "ctucan_chip_start failed!\n");
			return ret;
		}
		netif_wake_queue(ndev);
		break;
	default:
		ret = -EOPNOTSUPP;
		break;
	}

	return ret;
}

/**
 * ctucan_get_tx_status() - Gets status of TXT buffer
 * @priv:	Pointer to private data
 * @buf:	Buffer index (0-based)
 *
 * Return: Status of TXT buffer
 */
static enum ctucan_txtb_status ctucan_get_tx_status(struct ctucan_priv *priv, u8 buf)
{
	u32 tx_status = ctucan_read32(priv, CTUCANFD_TX_STATUS);
	enum ctucan_txtb_status status = (tx_status >> (buf * 4)) & 0x7;

	return status;
}

/**
 * ctucan_is_txt_buf_writable() - Checks if frame can be inserted to TXT Buffer
 * @priv:	Pointer to private data
 * @buf:	Buffer index (0-based)
 *
 * Return: True - Frame can be inserted to TXT Buffer, False - If attempted, frame will not be
 *	   inserted to TXT Buffer
 */
static bool ctucan_is_txt_buf_writable(struct ctucan_priv *priv, u8 buf)
{
	enum ctucan_txtb_status buf_status;

	buf_status = ctucan_get_tx_status(priv, buf);
	if (buf_status == TXT_RDY || buf_status == TXT_TRAN || buf_status == TXT_ABTP)
		return false;

	return true;
}

/**
 * ctucan_insert_frame() - Inserts frame to TXT buffer
 * @priv:	Pointer to private data
 * @cf:		Pointer to CAN frame to be inserted
 * @buf:	TXT Buffer index to which frame is inserted (0-based)
 * @isfdf:	True - CAN FD Frame, False - CAN 2.0 Frame
 *
 * Return: True - Frame inserted successfully
 *	   False - Frame was not inserted due to one of:
 *			1. TXT Buffer is not writable (it is in wrong state)
 *			2. Invalid TXT buffer index
 *			3. Invalid frame length
 */
static bool ctucan_insert_frame(struct ctucan_priv *priv, const struct canfd_frame *cf, u8 buf,
				bool isfdf)
{
	u32 buf_base;
	u32 ffw = 0;
	u32 idw = 0;
	unsigned int i;

	if (buf >= priv->ntxbufs)
		return false;

	if (!ctucan_is_txt_buf_writable(priv, buf))
		return false;

	if (cf->len > CANFD_MAX_DLEN)
		return false;

	/* Prepare Frame format */
	if (cf->can_id & CAN_RTR_FLAG)
		ffw |= REG_FRAME_FORMAT_W_RTR;

	if (cf->can_id & CAN_EFF_FLAG)
		ffw |= REG_FRAME_FORMAT_W_IDE;

	if (isfdf) {
		ffw |= REG_FRAME_FORMAT_W_FDF;
		if (cf->flags & CANFD_BRS)
			ffw |= REG_FRAME_FORMAT_W_BRS;
	}

	ffw |= FIELD_PREP(REG_FRAME_FORMAT_W_DLC, can_fd_len2dlc(cf->len));

	/* Prepare identifier */
	if (cf->can_id & CAN_EFF_FLAG)
		idw = cf->can_id & CAN_EFF_MASK;
	else
		idw = FIELD_PREP(REG_IDENTIFIER_W_IDENTIFIER_BASE, cf->can_id & CAN_SFF_MASK);

	/* Write ID, Frame format, Don't write timestamp -> Time triggered transmission disabled */
	buf_base = (buf + 1) * 0x100;
	ctucan_write_txt_buf(priv, buf_base, CTUCANFD_FRAME_FORMAT_W, ffw);
	ctucan_write_txt_buf(priv, buf_base, CTUCANFD_IDENTIFIER_W, idw);

	/* Write Data payload */
	if (!(cf->can_id & CAN_RTR_FLAG)) {
		for (i = 0; i < cf->len; i += 4) {
			u32 data = le32_to_cpu(*(__le32 *)(cf->data + i));

			ctucan_write_txt_buf(priv, buf_base, CTUCANFD_DATA_1_4_W + i, data);
		}
	}

	return true;
}

/**
 * ctucan_give_txtb_cmd() - Applies command on TXT buffer
 * @priv:	Pointer to private data
 * @cmd:	Command to give
 * @buf:	Buffer index (0-based)
 */
static void ctucan_give_txtb_cmd(struct ctucan_priv *priv, enum ctucan_txtb_command cmd, u8 buf)
{
	u32 tx_cmd = cmd;

	tx_cmd |= 1 << (buf + 8);
	ctucan_write32(priv, CTUCANFD_TX_COMMAND, tx_cmd);
}

/**
 * ctucan_start_xmit() - Starts the transmission
 * @skb:	sk_buff pointer that contains data to be Txed
 * @ndev:	Pointer to net_device structure
 *
 * Invoked from upper layers to initiate transmission. Uses the next available free TXT Buffer and
 * populates its fields to start the transmission.
 *
 * Return: %NETDEV_TX_OK on success, %NETDEV_TX_BUSY when no free TXT buffer is available,
 *         negative return values reserved for error cases
 */
static netdev_tx_t ctucan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	struct canfd_frame *cf = (struct canfd_frame *)skb->data;
	u32 txtb_id;
	bool ok;
	unsigned long flags;

	if (can_dropped_invalid_skb(ndev, skb))
		return NETDEV_TX_OK;

	if (unlikely(!CTU_CAN_FD_TXTNF(priv))) {
		netif_stop_queue(ndev);
		netdev_err(ndev, "BUG!, no TXB free when queue awake!\n");
		return NETDEV_TX_BUSY;
	}

	txtb_id = priv->txb_head % priv->ntxbufs;
	ctucan_netdev_dbg(ndev, "%s: using TXB#%u\n", __func__, txtb_id);
	ok = ctucan_insert_frame(priv, cf, txtb_id, can_is_canfd_skb(skb));

	if (!ok) {
		netdev_err(ndev, "BUG! TXNF set but cannot insert frame into TXTB! HW Bug?");
		kfree_skb(skb);
		ndev->stats.tx_dropped++;
		return NETDEV_TX_OK;
	}

	can_put_echo_skb(skb, ndev, txtb_id, 0);

	spin_lock_irqsave(&priv->tx_lock, flags);
	ctucan_give_txtb_cmd(priv, TXT_CMD_SET_READY, txtb_id);
	priv->txb_head++;

	/* Check if all TX buffers are full */
	if (!CTU_CAN_FD_TXTNF(priv))
		netif_stop_queue(ndev);

	spin_unlock_irqrestore(&priv->tx_lock, flags);

	return NETDEV_TX_OK;
}

/**
 * ctucan_read_rx_frame() - Reads frame from RX FIFO
 * @priv:	Pointer to CTU CAN FD's private data
 * @cf:		Pointer to CAN frame struct
 * @ffw:	Previously read frame format word
 *
 * Note: Frame format word must be read separately and provided in 'ffw'.
 */
static void ctucan_read_rx_frame(struct ctucan_priv *priv, struct canfd_frame *cf, u32 ffw)
{
	u32 idw;
	unsigned int i;
	unsigned int wc;
	unsigned int len;

	idw = ctucan_read32(priv, CTUCANFD_RX_DATA);
	if (FIELD_GET(REG_FRAME_FORMAT_W_IDE, ffw))
		cf->can_id = (idw & CAN_EFF_MASK) | CAN_EFF_FLAG;
	else
		cf->can_id = (idw >> 18) & CAN_SFF_MASK;

	/* BRS, ESI, RTR Flags */
	cf->flags = 0;
	if (FIELD_GET(REG_FRAME_FORMAT_W_FDF, ffw)) {
		if (FIELD_GET(REG_FRAME_FORMAT_W_BRS, ffw))
			cf->flags |= CANFD_BRS;
		if (FIELD_GET(REG_FRAME_FORMAT_W_ESI_RSV, ffw))
			cf->flags |= CANFD_ESI;
	} else if (FIELD_GET(REG_FRAME_FORMAT_W_RTR, ffw)) {
		cf->can_id |= CAN_RTR_FLAG;
	}

	wc = FIELD_GET(REG_FRAME_FORMAT_W_RWCNT, ffw) - 3;

	/* DLC */
	if (FIELD_GET(REG_FRAME_FORMAT_W_DLC, ffw) <= 8) {
		len = FIELD_GET(REG_FRAME_FORMAT_W_DLC, ffw);
	} else {
		if (FIELD_GET(REG_FRAME_FORMAT_W_FDF, ffw))
			len = wc << 2;
		else
			len = 8;
	}
	cf->len = len;
	if (unlikely(len > wc * 4))
		len = wc * 4;

	/* Timestamp - Read and throw away */
	ctucan_read32(priv, CTUCANFD_RX_DATA);
	ctucan_read32(priv, CTUCANFD_RX_DATA);

	/* Data */
	for (i = 0; i < len; i += 4) {
		u32 data = ctucan_read32(priv, CTUCANFD_RX_DATA);
		*(__le32 *)(cf->data + i) = cpu_to_le32(data);
	}
	while (unlikely(i < wc * 4)) {
		ctucan_read32(priv, CTUCANFD_RX_DATA);
		i += 4;
	}
}

/**
 * ctucan_rx() -  Called from CAN ISR to complete the received frame processing
 * @ndev:	Pointer to net_device structure
 *
 * This function is invoked from the CAN isr(poll) to process the Rx frames. It does minimal
 * processing and invokes "netif_receive_skb" to complete further processing.
 * Return: 1 when frame is passed to the network layer, 0 when the first frame word is read but
 *	   system is out of free SKBs temporally and left code to resolve SKB allocation later,
 *         -%EAGAIN in a case of empty Rx FIFO.
 */
static int ctucan_rx(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	struct net_device_stats *stats = &ndev->stats;
	struct canfd_frame *cf;
	struct sk_buff *skb;
	u32 ffw;

	if (test_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags)) {
		ffw = priv->rxfrm_first_word;
		clear_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags);
	} else {
		ffw = ctucan_read32(priv, CTUCANFD_RX_DATA);
	}

	if (!FIELD_GET(REG_FRAME_FORMAT_W_RWCNT, ffw))
		return -EAGAIN;

	if (FIELD_GET(REG_FRAME_FORMAT_W_FDF, ffw))
		skb = alloc_canfd_skb(ndev, &cf);
	else
		skb = alloc_can_skb(ndev, (struct can_frame **)&cf);

	if (unlikely(!skb)) {
		priv->rxfrm_first_word = ffw;
		set_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags);
		return 0;
	}

	ctucan_read_rx_frame(priv, cf, ffw);

	stats->rx_bytes += cf->len;
	stats->rx_packets++;
	netif_receive_skb(skb);

	return 1;
}

/**
 * ctucan_read_fault_state() - Reads CTU CAN FDs fault confinement state.
 * @priv:	Pointer to private data
 *
 * Returns: Fault confinement state of controller
 */
static enum can_state ctucan_read_fault_state(struct ctucan_priv *priv)
{
	u32 fs;
	u32 rec_tec;
	u32 ewl;

	fs = ctucan_read32(priv, CTUCANFD_EWL);
	rec_tec = ctucan_read32(priv, CTUCANFD_REC);
	ewl = FIELD_GET(REG_EWL_EW_LIMIT, fs);

	if (FIELD_GET(REG_EWL_ERA, fs)) {
		if (ewl > FIELD_GET(REG_REC_REC_VAL, rec_tec) &&
		    ewl > FIELD_GET(REG_REC_TEC_VAL, rec_tec))
			return CAN_STATE_ERROR_ACTIVE;
		else
			return CAN_STATE_ERROR_WARNING;
	} else if (FIELD_GET(REG_EWL_ERP, fs)) {
		return CAN_STATE_ERROR_PASSIVE;
	} else if (FIELD_GET(REG_EWL_BOF, fs)) {
		return CAN_STATE_BUS_OFF;
	}

	WARN(true, "Invalid error state");
	return CAN_STATE_ERROR_PASSIVE;
}

/**
 * ctucan_get_rec_tec() - Reads REC/TEC counter values from controller
 * @priv:	Pointer to private data
 * @bec:	Pointer to Error counter structure
 */
static void ctucan_get_rec_tec(struct ctucan_priv *priv, struct can_berr_counter *bec)
{
	u32 err_ctrs = ctucan_read32(priv, CTUCANFD_REC);

	bec->rxerr = FIELD_GET(REG_REC_REC_VAL, err_ctrs);
	bec->txerr = FIELD_GET(REG_REC_TEC_VAL, err_ctrs);
}

/**
 * ctucan_err_interrupt() - Error frame ISR
 * @ndev:	net_device pointer
 * @isr:	interrupt status register value
 *
 * This is the CAN error interrupt and it will check the type of error and forward the error
 * frame to upper layers.
 */
static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	struct net_device_stats *stats = &ndev->stats;
	struct can_frame *cf;
	struct sk_buff *skb;
	enum can_state state;
	struct can_berr_counter bec;
	u32 err_capt_alc;
	int dologerr = net_ratelimit();

	ctucan_get_rec_tec(priv, &bec);
	state = ctucan_read_fault_state(priv);
	err_capt_alc = ctucan_read32(priv, CTUCANFD_ERR_CAPT);

	if (dologerr)
		netdev_info(ndev, "%s: ISR = 0x%08x, rxerr %d, txerr %d, error type %lu, pos %lu, ALC id_field %lu, bit %lu\n",
			    __func__, isr, bec.rxerr, bec.txerr,
			    FIELD_GET(REG_ERR_CAPT_ERR_TYPE, err_capt_alc),
			    FIELD_GET(REG_ERR_CAPT_ERR_POS, err_capt_alc),
			    FIELD_GET(REG_ERR_CAPT_ALC_ID_FIELD, err_capt_alc),
			    FIELD_GET(REG_ERR_CAPT_ALC_BIT, err_capt_alc));

	skb = alloc_can_err_skb(ndev, &cf);

	/* EWLI: error warning limit condition met
	 * FCSI: fault confinement state changed
	 * ALI:  arbitration lost (just informative)
	 * BEI:  bus error interrupt
	 */
	if (FIELD_GET(REG_INT_STAT_FCSI, isr) || FIELD_GET(REG_INT_STAT_EWLI, isr)) {
		netdev_info(ndev, "state changes from %s to %s\n",
			    ctucan_state_to_str(priv->can.state),
			    ctucan_state_to_str(state));

		if (priv->can.state == state)
			netdev_warn(ndev,
				    "current and previous state is the same! (missed interrupt?)\n");

		priv->can.state = state;
		switch (state) {
		case CAN_STATE_BUS_OFF:
			priv->can.can_stats.bus_off++;
			can_bus_off(ndev);
			if (skb)
				cf->can_id |= CAN_ERR_BUSOFF;
			break;
		case CAN_STATE_ERROR_PASSIVE:
			priv->can.can_stats.error_passive++;
			if (skb) {
				cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
				cf->data[1] = (bec.rxerr > 127) ?
						CAN_ERR_CRTL_RX_PASSIVE :
						CAN_ERR_CRTL_TX_PASSIVE;
				cf->data[6] = bec.txerr;
				cf->data[7] = bec.rxerr;
			}
			break;
		case CAN_STATE_ERROR_WARNING:
			priv->can.can_stats.error_warning++;
			if (skb) {
				cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
				cf->data[1] |= (bec.txerr > bec.rxerr) ?
					CAN_ERR_CRTL_TX_WARNING :
					CAN_ERR_CRTL_RX_WARNING;
				cf->data[6] = bec.txerr;
				cf->data[7] = bec.rxerr;
			}
			break;
		case CAN_STATE_ERROR_ACTIVE:
			cf->can_id |= CAN_ERR_CNT;
			cf->data[1] = CAN_ERR_CRTL_ACTIVE;
			cf->data[6] = bec.txerr;
			cf->data[7] = bec.rxerr;
			break;
		default:
			netdev_warn(ndev, "unhandled error state (%d:%s)!\n",
				    state, ctucan_state_to_str(state));
			break;
		}
	}

	/* Check for Arbitration Lost interrupt */
	if (FIELD_GET(REG_INT_STAT_ALI, isr)) {
		if (dologerr)
			netdev_info(ndev, "arbitration lost\n");
		priv->can.can_stats.arbitration_lost++;
		if (skb) {
			cf->can_id |= CAN_ERR_LOSTARB;
			cf->data[0] = CAN_ERR_LOSTARB_UNSPEC;
		}
	}

	/* Check for Bus Error interrupt */
	if (FIELD_GET(REG_INT_STAT_BEI, isr)) {
		netdev_info(ndev, "bus error\n");
		priv->can.can_stats.bus_error++;
		stats->rx_errors++;
		if (skb) {
			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
			cf->data[2] = CAN_ERR_PROT_UNSPEC;
			cf->data[3] = CAN_ERR_PROT_LOC_UNSPEC;
		}
	}

	if (skb) {
		stats->rx_packets++;
		stats->rx_bytes += cf->can_dlc;
		netif_rx(skb);
	}
}

/**
 * ctucan_rx_poll() - Poll routine for rx packets (NAPI)
 * @napi:	NAPI structure pointer
 * @quota:	Max number of rx packets to be processed.
 *
 * This is the poll routine for rx part. It will process the packets maximux quota value.
 *
 * Return: Number of packets received
 */
static int ctucan_rx_poll(struct napi_struct *napi, int quota)
{
	struct net_device *ndev = napi->dev;
	struct ctucan_priv *priv = netdev_priv(ndev);
	int work_done = 0;
	u32 status;
	u32 framecnt;
	int res = 1;

	framecnt = FIELD_GET(REG_RX_STATUS_RXFRC, ctucan_read32(priv, CTUCANFD_RX_STATUS));
	while (framecnt && work_done < quota && res > 0) {
		res = ctucan_rx(ndev);
		work_done++;
		framecnt = FIELD_GET(REG_RX_STATUS_RXFRC, ctucan_read32(priv, CTUCANFD_RX_STATUS));
	}

	/* Check for RX FIFO Overflow */
	status = ctucan_read32(priv, CTUCANFD_STATUS);
	if (FIELD_GET(REG_STATUS_DOR, status)) {
		struct net_device_stats *stats = &ndev->stats;
		struct can_frame *cf;
		struct sk_buff *skb;

		netdev_info(ndev, "rx_poll: rx fifo overflow\n");
		stats->rx_over_errors++;
		stats->rx_errors++;
		skb = alloc_can_err_skb(ndev, &cf);
		if (skb) {
			cf->can_id |= CAN_ERR_CRTL;
			cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
			stats->rx_packets++;
			stats->rx_bytes += cf->can_dlc;
			netif_rx(skb);
		}

		/* Clear Data Overrun */
		ctucan_write32(priv, CTUCANFD_COMMAND, REG_COMMAND_CDO);
	}

	if (!framecnt && res != 0) {
		if (napi_complete_done(napi, work_done)) {
			/* Clear and enable RBNEI. It is level-triggered, so
			 * there is no race condition.
			 */
			ctucan_write32(priv, CTUCANFD_INT_STAT, REG_INT_STAT_RBNEI);
			ctucan_write32(priv, CTUCANFD_INT_MASK_CLR, REG_INT_STAT_RBNEI);
		}
	}

	return work_done;
}

/**
 * ctucan_rotate_txb_prio() - Rotates priorities of TXT Buffers
 * @ndev:	net_device pointer
 */
static void ctucan_rotate_txb_prio(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	u32 prio = priv->txb_prio;

	prio = (prio << 4) | ((prio >> ((priv->ntxbufs - 1) * 4)) & 0xF);
	ctucan_netdev_dbg(ndev, "%s: from 0x%08x to 0x%08x\n", __func__, priv->txb_prio, prio);
	priv->txb_prio = prio;
	ctucan_write32(priv, CTUCANFD_TX_PRIORITY, prio);
}

/**
 * ctucan_tx_interrupt() - Tx done Isr
 * @ndev:	net_device pointer
 */
static void ctucan_tx_interrupt(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	struct net_device_stats *stats = &ndev->stats;
	bool first = true;
	bool some_buffers_processed;
	unsigned long flags;
	enum ctucan_txtb_status txtb_status;
	u32 txtb_id;

	/*  read tx_status
	 *  if txb[n].finished (bit 2)
	 *	if ok -> echo
	 *	if error / aborted -> ?? (find how to handle oneshot mode)
	 *	txb_tail++
	 */
	do {
		spin_lock_irqsave(&priv->tx_lock, flags);

		some_buffers_processed = false;
		while ((int)(priv->txb_head - priv->txb_tail) > 0) {
			txtb_id = priv->txb_tail % priv->ntxbufs;
			txtb_status = ctucan_get_tx_status(priv, txtb_id);

			ctucan_netdev_dbg(ndev, "TXI: TXB#%u: status 0x%x\n", txtb_id, txtb_status);

			switch (txtb_status) {
			case TXT_TOK:
				ctucan_netdev_dbg(ndev, "TXT_OK\n");
				stats->tx_bytes += can_get_echo_skb(ndev, txtb_id, NULL);
				stats->tx_packets++;
				break;
			case TXT_ERR:
				/* This indicated that retransmit limit has been reached. Obviously
				 * we should not echo the frame, but also not indicate any kind of
				 * error. If desired, it was already reported (possible multiple
				 * times) on each arbitration lost.
				 */
				netdev_warn(ndev, "TXB in Error state\n");
				can_free_echo_skb(ndev, txtb_id, NULL);
				stats->tx_dropped++;
				break;
			case TXT_ABT:
				/* Same as for TXT_ERR, only with different cause. We *could*
				 * re-queue the frame, but multiqueue/abort is not supported yet
				 * anyway.
				 */
				netdev_warn(ndev, "TXB in Aborted state\n");
				can_free_echo_skb(ndev, txtb_id, NULL);
				stats->tx_dropped++;
				break;
			default:
				/* Bug only if the first buffer is not finished, otherwise it is
				 * pretty much expected.
				 */
				if (first) {
					netdev_err(ndev,
						   "BUG: TXB#%u not in a finished state (0x%x)!\n",
						   txtb_id, txtb_status);
					spin_unlock_irqrestore(&priv->tx_lock, flags);
					/* do not clear nor wake */
					return;
				}
				goto clear;
			}
			priv->txb_tail++;
			first = false;
			some_buffers_processed = true;
			/* Adjust priorities *before* marking the buffer as empty. */
			ctucan_rotate_txb_prio(ndev);
			ctucan_give_txtb_cmd(priv, TXT_CMD_SET_EMPTY, txtb_id);
		}
clear:
		spin_unlock_irqrestore(&priv->tx_lock, flags);

		/* If no buffers were processed this time, we cannot clear - that would introduce
		 * a race condition.
		 */
		if (some_buffers_processed) {
			/* Clear the interrupt again. We do not want to receive again interrupt for
			 * the buffer already handled. If it is the last finished one then it would
			 * cause log of spurious interrupt.
			 */
			ctucan_write32(priv, CTUCANFD_INT_STAT, REG_INT_STAT_TXBHCI);
		}
	} while (some_buffers_processed);

	spin_lock_irqsave(&priv->tx_lock, flags);

	/* Check if at least one TX buffer is free */
	if (CTU_CAN_FD_TXTNF(priv))
		netif_wake_queue(ndev);

	spin_unlock_irqrestore(&priv->tx_lock, flags);
}

/**
 * ctucan_interrupt() - CAN Isr
 * @irq:	irq number
 * @dev_id:	device id pointer
 *
 * This is the CTU CAN FD ISR. It checks for the type of interrupt
 * and invokes the corresponding ISR.
 *
 * Return:
 * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise
 */
static irqreturn_t ctucan_interrupt(int irq, void *dev_id)
{
	struct net_device *ndev = (struct net_device *)dev_id;
	struct ctucan_priv *priv = netdev_priv(ndev);
	u32 isr, icr;
	u32 imask;
	int irq_loops;

	for (irq_loops = 0; irq_loops < 10000; irq_loops++) {
		/* Get the interrupt status */
		isr = ctucan_read32(priv, CTUCANFD_INT_STAT);

		if (!isr)
			return irq_loops ? IRQ_HANDLED : IRQ_NONE;

		/* Receive Buffer Not Empty Interrupt */
		if (FIELD_GET(REG_INT_STAT_RBNEI, isr)) {
			ctucan_netdev_dbg(ndev, "RXBNEI\n");
			/* Mask RXBNEI the first, then clear interrupt and schedule NAPI. Even if
			 * another IRQ fires, RBNEI will always be 0 (masked).
			 */
			icr = REG_INT_STAT_RBNEI;
			ctucan_write32(priv, CTUCANFD_INT_MASK_SET, icr);
			ctucan_write32(priv, CTUCANFD_INT_STAT, icr);
			napi_schedule(&priv->napi);
		}

		/* TXT Buffer HW Command Interrupt */
		if (FIELD_GET(REG_INT_STAT_TXBHCI, isr)) {
			ctucan_netdev_dbg(ndev, "TXBHCI\n");
			/* Cleared inside */
			ctucan_tx_interrupt(ndev);
		}

		/* Error interrupts */
		if (FIELD_GET(REG_INT_STAT_EWLI, isr) ||
		    FIELD_GET(REG_INT_STAT_FCSI, isr) ||
		    FIELD_GET(REG_INT_STAT_ALI, isr)) {
			icr = isr & (REG_INT_STAT_EWLI | REG_INT_STAT_FCSI | REG_INT_STAT_ALI);

			ctucan_netdev_dbg(ndev, "some ERR interrupt: clearing 0x%08x\n", icr);
			ctucan_write32(priv, CTUCANFD_INT_STAT, icr);
			ctucan_err_interrupt(ndev, isr);
		}
		/* Ignore RI, TI, LFI, RFI, BSI */
	}

	netdev_err(ndev, "%s: stuck interrupt (isr=0x%08x), stopping\n", __func__, isr);

	if (FIELD_GET(REG_INT_STAT_TXBHCI, isr)) {
		int i;

		netdev_err(ndev, "txb_head=0x%08x txb_tail=0x%08x\n",
			   priv->txb_head, priv->txb_tail);
		for (i = 0; i < priv->ntxbufs; i++) {
			u32 status = ctucan_get_tx_status(priv, i);

			netdev_err(ndev, "txb[%d] txb status=0x%08x\n", i, status);
		}
	}

	imask = 0xffffffff;
	ctucan_write32(priv, CTUCANFD_INT_ENA_CLR, imask);
	ctucan_write32(priv, CTUCANFD_INT_MASK_SET, imask);

	return IRQ_HANDLED;
}

/**
 * ctucan_chip_stop() - Driver stop routine
 * @ndev:	Pointer to net_device structure
 *
 * This is the drivers stop routine. It will disable the
 * interrupts and disable the controller.
 */
static void ctucan_chip_stop(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	u32 mask = 0xffffffff;
	u32 mode;

	/* Disable interrupts and disable CAN */
	ctucan_write32(priv, CTUCANFD_INT_ENA_CLR, mask);
	ctucan_write32(priv, CTUCANFD_INT_MASK_SET, mask);
	mode = ctucan_read32(priv, CTUCANFD_MODE);
	mode &= ~REG_MODE_ENA;
	ctucan_write32(priv, CTUCANFD_MODE, mode);

	priv->can.state = CAN_STATE_STOPPED;
}

/**
 * ctucan_open() - Driver open routine
 * @ndev:	Pointer to net_device structure
 *
 * This is the driver open routine.
 * Return: 0 on success and failure value on error
 */
static int ctucan_open(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	int ret;

	ret = pm_runtime_get_sync(priv->dev);
	if (ret < 0) {
		netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
			   __func__, ret);
		pm_runtime_put_noidle(priv->dev);
		return ret;
	}

	ret = ctucan_reset(ndev);
	if (ret < 0)
		goto err_reset;

	/* Common open */
	ret = open_candev(ndev);
	if (ret) {
		netdev_warn(ndev, "open_candev failed!\n");
		goto err_open;
	}

	ret = request_irq(ndev->irq, ctucan_interrupt, priv->irq_flags, ndev->name, ndev);
	if (ret < 0) {
		netdev_err(ndev, "irq allocation for CAN failed\n");
		goto err_irq;
	}

	ret = ctucan_chip_start(ndev);
	if (ret < 0) {
		netdev_err(ndev, "ctucan_chip_start failed!\n");
		goto err_chip_start;
	}

	netdev_info(ndev, "ctu_can_fd device registered\n");
	napi_enable(&priv->napi);
	netif_start_queue(ndev);

	return 0;

err_chip_start:
	free_irq(ndev->irq, ndev);
err_irq:
	close_candev(ndev);
err_open:
err_reset:
	pm_runtime_put(priv->dev);

	return ret;
}

/**
 * ctucan_close() - Driver close routine
 * @ndev:	Pointer to net_device structure
 *
 * Return: 0 always
 */
static int ctucan_close(struct net_device *ndev)
{
	struct ctucan_priv *priv = netdev_priv(ndev);

	netif_stop_queue(ndev);
	napi_disable(&priv->napi);
	ctucan_chip_stop(ndev);
	free_irq(ndev->irq, ndev);
	close_candev(ndev);

	pm_runtime_put(priv->dev);

	return 0;
}

/**
 * ctucan_get_berr_counter() - error counter routine
 * @ndev:	Pointer to net_device structure
 * @bec:	Pointer to can_berr_counter structure
 *
 * This is the driver error counter routine.
 * Return: 0 on success and failure value on error
 */
static int ctucan_get_berr_counter(const struct net_device *ndev, struct can_berr_counter *bec)
{
	struct ctucan_priv *priv = netdev_priv(ndev);
	int ret;

	ret = pm_runtime_get_sync(priv->dev);
	if (ret < 0) {
		netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n", __func__, ret);
		pm_runtime_put_noidle(priv->dev);
		return ret;
	}

	ctucan_get_rec_tec(priv, bec);
	pm_runtime_put(priv->dev);

	return 0;
}

static const struct net_device_ops ctucan_netdev_ops = {
	.ndo_open	= ctucan_open,
	.ndo_stop	= ctucan_close,
	.ndo_start_xmit	= ctucan_start_xmit,
	.ndo_change_mtu	= can_change_mtu,
};

static const struct ethtool_ops ctucan_ethtool_ops = {
	.get_ts_info = ethtool_op_get_ts_info,
};

int ctucan_suspend(struct device *dev)
{
	struct net_device *ndev = dev_get_drvdata(dev);
	struct ctucan_priv *priv = netdev_priv(ndev);

	if (netif_running(ndev)) {
		netif_stop_queue(ndev);
		netif_device_detach(ndev);
	}

	priv->can.state = CAN_STATE_SLEEPING;

	return 0;
}
EXPORT_SYMBOL(ctucan_suspend);

int ctucan_resume(struct device *dev)
{
	struct net_device *ndev = dev_get_drvdata(dev);
	struct ctucan_priv *priv = netdev_priv(ndev);

	priv->can.state = CAN_STATE_ERROR_ACTIVE;

	if (netif_running(ndev)) {
		netif_device_attach(ndev);
		netif_start_queue(ndev);
	}

	return 0;
}
EXPORT_SYMBOL(ctucan_resume);

int ctucan_probe_common(struct device *dev, void __iomem *addr, int irq, unsigned int ntxbufs,
			unsigned long can_clk_rate, int pm_enable_call,
			void (*set_drvdata_fnc)(struct device *dev, struct net_device *ndev))
{
	struct ctucan_priv *priv;
	struct net_device *ndev;
	int ret;

	/* Create a CAN device instance */
	ndev = alloc_candev(sizeof(struct ctucan_priv), ntxbufs);
	if (!ndev)
		return -ENOMEM;

	priv = netdev_priv(ndev);
	spin_lock_init(&priv->tx_lock);
	INIT_LIST_HEAD(&priv->peers_on_pdev);
	priv->ntxbufs = ntxbufs;
	priv->dev = dev;
	priv->can.bittiming_const = &ctu_can_fd_bit_timing_max;
	priv->can.data_bittiming_const = &ctu_can_fd_bit_timing_data_max;
	priv->can.do_set_mode = ctucan_do_set_mode;

	/* Needed for timing adjustment to be performed as soon as possible */
	priv->can.do_set_bittiming = ctucan_set_bittiming;
	priv->can.do_set_data_bittiming = ctucan_set_data_bittiming;

	priv->can.do_get_berr_counter = ctucan_get_berr_counter;
	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK
					| CAN_CTRLMODE_LISTENONLY
					| CAN_CTRLMODE_FD
					| CAN_CTRLMODE_PRESUME_ACK
					| CAN_CTRLMODE_BERR_REPORTING
					| CAN_CTRLMODE_FD_NON_ISO
					| CAN_CTRLMODE_ONE_SHOT;
	priv->mem_base = addr;

	/* Get IRQ for the device */
	ndev->irq = irq;
	ndev->flags |= IFF_ECHO;	/* We support local echo */

	if (set_drvdata_fnc)
		set_drvdata_fnc(dev, ndev);
	SET_NETDEV_DEV(ndev, dev);
	ndev->netdev_ops = &ctucan_netdev_ops;
	ndev->ethtool_ops = &ctucan_ethtool_ops;

	/* Getting the can_clk info */
	if (!can_clk_rate) {
		priv->can_clk = devm_clk_get(dev, NULL);
		if (IS_ERR(priv->can_clk)) {
			dev_err(dev, "Device clock not found.\n");
			ret = PTR_ERR(priv->can_clk);
			goto err_free;
		}
		can_clk_rate = clk_get_rate(priv->can_clk);
	}

	priv->write_reg = ctucan_write32_le;
	priv->read_reg = ctucan_read32_le;

	if (pm_enable_call)
		pm_runtime_enable(dev);
	ret = pm_runtime_get_sync(dev);
	if (ret < 0) {
		netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
			   __func__, ret);
		pm_runtime_put_noidle(priv->dev);
		goto err_pmdisable;
	}

	/* Check for big-endianity and set according IO-accessors */
	if ((ctucan_read32(priv, CTUCANFD_DEVICE_ID) & 0xFFFF) != CTUCANFD_ID) {
		priv->write_reg = ctucan_write32_be;
		priv->read_reg = ctucan_read32_be;
		if ((ctucan_read32(priv, CTUCANFD_DEVICE_ID) & 0xFFFF) != CTUCANFD_ID) {
			netdev_err(ndev, "CTU_CAN_FD signature not found\n");
			ret = -ENODEV;
			goto err_deviceoff;
		}
	}

	ret = ctucan_reset(ndev);
	if (ret < 0)
		goto err_deviceoff;

	priv->can.clock.freq = can_clk_rate;

	netif_napi_add(ndev, &priv->napi, ctucan_rx_poll, NAPI_POLL_WEIGHT);

	ret = register_candev(ndev);
	if (ret) {
		dev_err(dev, "fail to register failed (err=%d)\n", ret);
		goto err_deviceoff;
	}

	pm_runtime_put(dev);

	netdev_dbg(ndev, "mem_base=0x%p irq=%d clock=%d, no. of txt buffers:%d\n",
		   priv->mem_base, ndev->irq, priv->can.clock.freq, priv->ntxbufs);

	return 0;

err_deviceoff:
	pm_runtime_put(priv->dev);
err_pmdisable:
	if (pm_enable_call)
		pm_runtime_disable(dev);
err_free:
	list_del_init(&priv->peers_on_pdev);
	free_candev(ndev);
	return ret;
}
EXPORT_SYMBOL(ctucan_probe_common);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Martin Jerabek <martin.jerabek01@gmail.com>");
MODULE_AUTHOR("Pavel Pisa <pisa@cmp.felk.cvut.cz>");
MODULE_AUTHOR("Ondrej Ille <ondrej.ille@gmail.com>");
MODULE_DESCRIPTION("CTU CAN FD interface");
