linux/drivers/net/can/m_can/m_can.c

// SPDX-License-Identifier: GPL-2.0
// CAN bus driver for Bosch M_CAN controller
// Copyright (C) 2014 Freescale Semiconductor, Inc.
//      Dong Aisheng <[email protected]>
// Copyright (C) 2018-19 Texas Instruments Incorporated - http://www.ti.com/

/* Bosch M_CAN user manual can be obtained from:
 * https://github.com/linux-can/can-doc/tree/master/m_can
 */

#include <linux/bitfield.h>
#include <linux/can/dev.h>
#include <linux/ethtool.h>
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>

#include "m_can.h"

/* registers definition */
enum m_can_reg {};

/* message ram configuration data length */
#define MRAM_CFG_LEN

/* Core Release Register (CREL) */
#define CREL_REL_MASK
#define CREL_STEP_MASK
#define CREL_SUBSTEP_MASK

/* Data Bit Timing & Prescaler Register (DBTP) */
#define DBTP_TDC
#define DBTP_DBRP_MASK
#define DBTP_DTSEG1_MASK
#define DBTP_DTSEG2_MASK
#define DBTP_DSJW_MASK

/* Transmitter Delay Compensation Register (TDCR) */
#define TDCR_TDCO_MASK
#define TDCR_TDCF_MASK

/* Test Register (TEST) */
#define TEST_LBCK

/* CC Control Register (CCCR) */
#define CCCR_TXP
#define CCCR_TEST
#define CCCR_DAR
#define CCCR_MON
#define CCCR_CSR
#define CCCR_CSA
#define CCCR_ASM
#define CCCR_CCE
#define CCCR_INIT
/* for version 3.0.x */
#define CCCR_CMR_MASK
#define CCCR_CMR_CANFD
#define CCCR_CMR_CANFD_BRS
#define CCCR_CMR_CAN
#define CCCR_CME_MASK
#define CCCR_CME_CAN
#define CCCR_CME_CANFD
#define CCCR_CME_CANFD_BRS
/* for version >=3.1.x */
#define CCCR_EFBI
#define CCCR_PXHD
#define CCCR_BRSE
#define CCCR_FDOE
/* for version >=3.2.x */
#define CCCR_NISO
/* for version >=3.3.x */
#define CCCR_WMM
#define CCCR_UTSU

/* Nominal Bit Timing & Prescaler Register (NBTP) */
#define NBTP_NSJW_MASK
#define NBTP_NBRP_MASK
#define NBTP_NTSEG1_MASK
#define NBTP_NTSEG2_MASK

/* Timestamp Counter Configuration Register (TSCC) */
#define TSCC_TCP_MASK
#define TSCC_TSS_MASK
#define TSCC_TSS_DISABLE
#define TSCC_TSS_INTERNAL
#define TSCC_TSS_EXTERNAL

/* Timestamp Counter Value Register (TSCV) */
#define TSCV_TSC_MASK

/* Error Counter Register (ECR) */
#define ECR_RP
#define ECR_REC_MASK
#define ECR_TEC_MASK

/* Protocol Status Register (PSR) */
#define PSR_BO
#define PSR_EW
#define PSR_EP
#define PSR_LEC_MASK
#define PSR_DLEC_MASK

/* Interrupt Register (IR) */
#define IR_ALL_INT

/* Renamed bits for versions > 3.1.x */
#define IR_ARA
#define IR_PED
#define IR_PEA

/* Bits for version 3.0.x */
#define IR_STE
#define IR_FOE
#define IR_ACKE
#define IR_BE
#define IR_CRCE
#define IR_WDI
#define IR_BO
#define IR_EW
#define IR_EP
#define IR_ELO
#define IR_BEU
#define IR_BEC
#define IR_DRX
#define IR_TOO
#define IR_MRAF
#define IR_TSW
#define IR_TEFL
#define IR_TEFF
#define IR_TEFW
#define IR_TEFN
#define IR_TFE
#define IR_TCF
#define IR_TC
#define IR_HPM
#define IR_RF1L
#define IR_RF1F
#define IR_RF1W
#define IR_RF1N
#define IR_RF0L
#define IR_RF0F
#define IR_RF0W
#define IR_RF0N
#define IR_ERR_STATE

/* Interrupts for version 3.0.x */
#define IR_ERR_LEC_30X
#define IR_ERR_BUS_30X
#define IR_ERR_ALL_30X

/* Interrupts for version >= 3.1.x */
#define IR_ERR_LEC_31X
#define IR_ERR_BUS_31X
#define IR_ERR_ALL_31X

/* Interrupt Line Select (ILS) */
#define ILS_ALL_INT0
#define ILS_ALL_INT1

/* Interrupt Line Enable (ILE) */
#define ILE_EINT1
#define ILE_EINT0

/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */
#define RXFC_FWM_MASK
#define RXFC_FS_MASK

/* Rx FIFO 0/1 Status (RXF0S/RXF1S) */
#define RXFS_RFL
#define RXFS_FF
#define RXFS_FPI_MASK
#define RXFS_FGI_MASK
#define RXFS_FFL_MASK

/* Rx Buffer / FIFO Element Size Configuration (RXESC) */
#define RXESC_RBDS_MASK
#define RXESC_F1DS_MASK
#define RXESC_F0DS_MASK
#define RXESC_64B

/* Tx Buffer Configuration (TXBC) */
#define TXBC_TFQS_MASK
#define TXBC_NDTB_MASK

/* Tx FIFO/Queue Status (TXFQS) */
#define TXFQS_TFQF
#define TXFQS_TFQPI_MASK
#define TXFQS_TFGI_MASK
#define TXFQS_TFFL_MASK

/* Tx Buffer Element Size Configuration (TXESC) */
#define TXESC_TBDS_MASK
#define TXESC_TBDS_64B

/* Tx Event FIFO Configuration (TXEFC) */
#define TXEFC_EFWM_MASK
#define TXEFC_EFS_MASK

/* Tx Event FIFO Status (TXEFS) */
#define TXEFS_TEFL
#define TXEFS_EFF
#define TXEFS_EFGI_MASK
#define TXEFS_EFFL_MASK

/* Tx Event FIFO Acknowledge (TXEFA) */
#define TXEFA_EFAI_MASK

/* Message RAM Configuration (in bytes) */
#define SIDF_ELEMENT_SIZE
#define XIDF_ELEMENT_SIZE
#define RXF0_ELEMENT_SIZE
#define RXF1_ELEMENT_SIZE
#define RXB_ELEMENT_SIZE
#define TXE_ELEMENT_SIZE
#define TXB_ELEMENT_SIZE

/* Message RAM Elements */
#define M_CAN_FIFO_ID
#define M_CAN_FIFO_DLC
#define M_CAN_FIFO_DATA

/* Rx Buffer Element */
/* R0 */
#define RX_BUF_ESI
#define RX_BUF_XTD
#define RX_BUF_RTR
/* R1 */
#define RX_BUF_ANMF
#define RX_BUF_FDF
#define RX_BUF_BRS
#define RX_BUF_RXTS_MASK

/* Tx Buffer Element */
/* T0 */
#define TX_BUF_ESI
#define TX_BUF_XTD
#define TX_BUF_RTR
/* T1 */
#define TX_BUF_EFC
#define TX_BUF_FDF
#define TX_BUF_BRS
#define TX_BUF_MM_MASK
#define TX_BUF_DLC_MASK

/* Tx event FIFO Element */
/* E1 */
#define TX_EVENT_MM_MASK
#define TX_EVENT_TXTS_MASK

/* Hrtimer polling interval */
#define HRTIMER_POLL_INTERVAL_MS

/* The ID and DLC registers are adjacent in M_CAN FIFO memory,
 * and we can save a (potentially slow) bus round trip by combining
 * reads and writes to them.
 */
struct id_and_dlc {};

struct m_can_fifo_element {};

static inline u32 m_can_read(struct m_can_classdev *cdev, enum m_can_reg reg)
{}

static inline void m_can_write(struct m_can_classdev *cdev, enum m_can_reg reg,
			       u32 val)
{}

static int
m_can_fifo_read(struct m_can_classdev *cdev,
		u32 fgi, unsigned int offset, void *val, size_t val_count)
{}

static int
m_can_fifo_write(struct m_can_classdev *cdev,
		 u32 fpi, unsigned int offset, const void *val, size_t val_count)
{}

static inline int m_can_fifo_write_no_off(struct m_can_classdev *cdev,
					  u32 fpi, u32 val)
{}

static int
m_can_txe_fifo_read(struct m_can_classdev *cdev, u32 fgi, u32 offset, u32 *val)
{}

static int m_can_cccr_update_bits(struct m_can_classdev *cdev, u32 mask, u32 val)
{}

static int m_can_config_enable(struct m_can_classdev *cdev)
{}

static int m_can_config_disable(struct m_can_classdev *cdev)
{}

static void m_can_interrupt_enable(struct m_can_classdev *cdev, u32 interrupts)
{}

static void m_can_coalescing_disable(struct m_can_classdev *cdev)
{}

static inline void m_can_enable_all_interrupts(struct m_can_classdev *cdev)
{}

static inline void m_can_disable_all_interrupts(struct m_can_classdev *cdev)
{}

/* Retrieve internal timestamp counter from TSCV.TSC, and shift it to 32-bit
 * width.
 */
static u32 m_can_get_timestamp(struct m_can_classdev *cdev)
{}

static void m_can_clean(struct net_device *net)
{}

/* For peripherals, pass skb to rx-offload, which will push skb from
 * napi. For non-peripherals, RX is done in napi already, so push
 * directly. timestamp is used to ensure good skb ordering in
 * rx-offload and is ignored for non-peripherals.
 */
static void m_can_receive_skb(struct m_can_classdev *cdev,
			      struct sk_buff *skb,
			      u32 timestamp)
{}

static int m_can_read_fifo(struct net_device *dev, u32 fgi)
{}

static int m_can_do_rx_poll(struct net_device *dev, int quota)
{}

static int m_can_handle_lost_msg(struct net_device *dev)
{}

static int m_can_handle_lec_err(struct net_device *dev,
				enum m_can_lec_type lec_type)
{}

static int __m_can_get_berr_counter(const struct net_device *dev,
				    struct can_berr_counter *bec)
{}

static int m_can_clk_start(struct m_can_classdev *cdev)
{}

static void m_can_clk_stop(struct m_can_classdev *cdev)
{}

static int m_can_get_berr_counter(const struct net_device *dev,
				  struct can_berr_counter *bec)
{}

static int m_can_handle_state_change(struct net_device *dev,
				     enum can_state new_state)
{}

static int m_can_handle_state_errors(struct net_device *dev, u32 psr)
{}

static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus)
{}

static inline bool is_lec_err(u8 lec)
{}

static inline bool m_can_is_protocol_err(u32 irqstatus)
{}

static int m_can_handle_protocol_error(struct net_device *dev, u32 irqstatus)
{}

static int m_can_handle_bus_errors(struct net_device *dev, u32 irqstatus,
				   u32 psr)
{}

static int m_can_rx_handler(struct net_device *dev, int quota, u32 irqstatus)
{}

static int m_can_rx_peripheral(struct net_device *dev, u32 irqstatus)
{}

static int m_can_poll(struct napi_struct *napi, int quota)
{}

/* Echo tx skb and update net stats. Peripherals use rx-offload for
 * echo. timestamp is used for peripherals to ensure correct ordering
 * by rx-offload, and is ignored for non-peripherals.
 */
static unsigned int m_can_tx_update_stats(struct m_can_classdev *cdev,
					  unsigned int msg_mark, u32 timestamp)
{}

static void m_can_finish_tx(struct m_can_classdev *cdev, int transmitted,
			    unsigned int transmitted_frame_len)
{}

static netdev_tx_t m_can_start_tx(struct m_can_classdev *cdev)
{}

static int m_can_echo_tx_event(struct net_device *dev)
{}

static void m_can_coalescing_update(struct m_can_classdev *cdev, u32 ir)
{}

static irqreturn_t m_can_isr(int irq, void *dev_id)
{}

static enum hrtimer_restart m_can_coalescing_timer(struct hrtimer *timer)
{}

static const struct can_bittiming_const m_can_bittiming_const_30X =;

static const struct can_bittiming_const m_can_data_bittiming_const_30X =;

static const struct can_bittiming_const m_can_bittiming_const_31X =;

static const struct can_bittiming_const m_can_data_bittiming_const_31X =;

static int m_can_set_bittiming(struct net_device *dev)
{}

/* Configure M_CAN chip:
 * - set rx buffer/fifo element size
 * - configure rx fifo
 * - accept non-matching frame into fifo 0
 * - configure tx buffer
 *		- >= v3.1.x: TX FIFO is used
 * - configure mode
 * - setup bittiming
 * - configure timestamp generation
 */
static int m_can_chip_config(struct net_device *dev)
{}

static int m_can_start(struct net_device *dev)
{}

static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
{}

/* Checks core release number of M_CAN
 * returns 0 if an unsupported device is detected
 * else it returns the release and step coded as:
 * return value = 10 * <release> + 1 * <step>
 */
static int m_can_check_core_release(struct m_can_classdev *cdev)
{}

/* Selectable Non ISO support only in version 3.2.x
 * Return 1 if the bit is writable, 0 if it is not, or negative on error.
 */
static int m_can_niso_supported(struct m_can_classdev *cdev)
{}

static int m_can_dev_setup(struct m_can_classdev *cdev)
{}

static void m_can_stop(struct net_device *dev)
{}

static int m_can_close(struct net_device *dev)
{}

static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev,
				    struct sk_buff *skb)
{}

static void m_can_tx_submit(struct m_can_classdev *cdev)
{}

static void m_can_tx_work_queue(struct work_struct *ws)
{}

static void m_can_tx_queue_skb(struct m_can_classdev *cdev, struct sk_buff *skb,
			       bool submit)
{}

static netdev_tx_t m_can_start_peripheral_xmit(struct m_can_classdev *cdev,
					       struct sk_buff *skb)
{}

static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
				    struct net_device *dev)
{}

static enum hrtimer_restart hrtimer_callback(struct hrtimer *timer)
{}

static int m_can_open(struct net_device *dev)
{}

static const struct net_device_ops m_can_netdev_ops =;

static int m_can_get_coalesce(struct net_device *dev,
			      struct ethtool_coalesce *ec,
			      struct kernel_ethtool_coalesce *kec,
			      struct netlink_ext_ack *ext_ack)
{}

static int m_can_set_coalesce(struct net_device *dev,
			      struct ethtool_coalesce *ec,
			      struct kernel_ethtool_coalesce *kec,
			      struct netlink_ext_ack *ext_ack)
{}

static const struct ethtool_ops m_can_ethtool_ops =;

static const struct ethtool_ops m_can_ethtool_ops_polling =;

static int register_m_can_dev(struct net_device *dev)
{}

int m_can_check_mram_cfg(struct m_can_classdev *cdev, u32 mram_max_size)
{}
EXPORT_SYMBOL_GPL();

static void m_can_of_parse_mram(struct m_can_classdev *cdev,
				const u32 *mram_config_vals)
{}

int m_can_init_ram(struct m_can_classdev *cdev)
{}
EXPORT_SYMBOL_GPL();

int m_can_class_get_clocks(struct m_can_classdev *cdev)
{}
EXPORT_SYMBOL_GPL();

struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
						int sizeof_priv)
{}
EXPORT_SYMBOL_GPL();

void m_can_class_free_dev(struct net_device *net)
{}
EXPORT_SYMBOL_GPL();

int m_can_class_register(struct m_can_classdev *cdev)
{}
EXPORT_SYMBOL_GPL();

void m_can_class_unregister(struct m_can_classdev *cdev)
{}
EXPORT_SYMBOL_GPL();

int m_can_class_suspend(struct device *dev)
{}
EXPORT_SYMBOL_GPL();

int m_can_class_resume(struct device *dev)
{}
EXPORT_SYMBOL_GPL();

MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_DESCRIPTION();