linux/drivers/net/can/grcan.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
 *
 * 2012 (c) Aeroflex Gaisler AB
 *
 * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
 * VHDL IP core library.
 *
 * Full documentation of the GRCAN core can be found here:
 * http://www.gaisler.com/products/grlib/grip.pdf
 *
 * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
 * open firmware properties.
 *
 * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
 * sysfs interface.
 *
 * See "Documentation/admin-guide/kernel-parameters.rst" for information on the module
 * parameters.
 *
 * Contributors: Andreas Larsson <[email protected]>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/io.h>
#include <linux/can/dev.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/of.h>
#include <linux/of_irq.h>

#include <linux/dma-mapping.h>

#define DRV_NAME

#define GRCAN_NAPI_WEIGHT

#define GRCAN_RESERVE_SIZE(slot1, slot2)

struct grcan_registers {};

#define GRCAN_CONF_ABORT
#define GRCAN_CONF_ENABLE0
#define GRCAN_CONF_ENABLE1
#define GRCAN_CONF_SELECT
#define GRCAN_CONF_SILENT
#define GRCAN_CONF_SAM
#define GRCAN_CONF_BPR
#define GRCAN_CONF_RSJ
#define GRCAN_CONF_PS1
#define GRCAN_CONF_PS2
#define GRCAN_CONF_SCALER
#define GRCAN_CONF_OPERATION
#define GRCAN_CONF_TIMING

#define GRCAN_CONF_RSJ_MIN
#define GRCAN_CONF_RSJ_MAX
#define GRCAN_CONF_PS1_MIN
#define GRCAN_CONF_PS1_MAX
#define GRCAN_CONF_PS2_MIN
#define GRCAN_CONF_PS2_MAX
#define GRCAN_CONF_SCALER_MIN
#define GRCAN_CONF_SCALER_MAX
#define GRCAN_CONF_SCALER_INC

#define GRCAN_CONF_BPR_BIT
#define GRCAN_CONF_RSJ_BIT
#define GRCAN_CONF_PS1_BIT
#define GRCAN_CONF_PS2_BIT
#define GRCAN_CONF_SCALER_BIT

#define GRCAN_STAT_PASS
#define GRCAN_STAT_OFF
#define GRCAN_STAT_OR
#define GRCAN_STAT_AHBERR
#define GRCAN_STAT_ACTIVE
#define GRCAN_STAT_RXERRCNT
#define GRCAN_STAT_TXERRCNT

#define GRCAN_STAT_ERRCTR_RELATED

#define GRCAN_STAT_RXERRCNT_BIT
#define GRCAN_STAT_TXERRCNT_BIT

#define GRCAN_STAT_ERRCNT_WARNING_LIMIT
#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT

#define GRCAN_CTRL_RESET
#define GRCAN_CTRL_ENABLE

#define GRCAN_TXCTRL_ENABLE
#define GRCAN_TXCTRL_ONGOING
#define GRCAN_TXCTRL_SINGLE

#define GRCAN_RXCTRL_ENABLE
#define GRCAN_RXCTRL_ONGOING

/* Relative offset of IRQ sources to AMBA Plug&Play */
#define GRCAN_IRQIX_IRQ
#define GRCAN_IRQIX_TXSYNC
#define GRCAN_IRQIX_RXSYNC

#define GRCAN_IRQ_PASS
#define GRCAN_IRQ_OFF
#define GRCAN_IRQ_OR
#define GRCAN_IRQ_RXAHBERR
#define GRCAN_IRQ_TXAHBERR
#define GRCAN_IRQ_RXIRQ
#define GRCAN_IRQ_TXIRQ
#define GRCAN_IRQ_RXFULL
#define GRCAN_IRQ_TXEMPTY
#define GRCAN_IRQ_RX
#define GRCAN_IRQ_TX
#define GRCAN_IRQ_RXSYNC
#define GRCAN_IRQ_TXSYNC
#define GRCAN_IRQ_RXERRCTR
#define GRCAN_IRQ_TXERRCTR
#define GRCAN_IRQ_RXMISS
#define GRCAN_IRQ_TXLOSS

#define GRCAN_IRQ_NONE
#define GRCAN_IRQ_ALL

#define GRCAN_IRQ_ERRCTR_RELATED
#define GRCAN_IRQ_ERRORS
#define GRCAN_IRQ_DEFAULT

#define GRCAN_MSG_SIZE

#define GRCAN_MSG_IDE
#define GRCAN_MSG_RTR
#define GRCAN_MSG_BID
#define GRCAN_MSG_EID
#define GRCAN_MSG_IDE_BIT
#define GRCAN_MSG_RTR_BIT
#define GRCAN_MSG_BID_BIT
#define GRCAN_MSG_EID_BIT

#define GRCAN_MSG_DLC
#define GRCAN_MSG_TXERRC
#define GRCAN_MSG_RXERRC
#define GRCAN_MSG_DLC_BIT
#define GRCAN_MSG_TXERRC_BIT
#define GRCAN_MSG_RXERRC_BIT
#define GRCAN_MSG_AHBERR
#define GRCAN_MSG_OR
#define GRCAN_MSG_OFF
#define GRCAN_MSG_PASS

#define GRCAN_MSG_DATA_SLOT_INDEX(i)
#define GRCAN_MSG_DATA_SHIFT(i)

#define GRCAN_BUFFER_ALIGNMENT
#define GRCAN_DEFAULT_BUFFER_SIZE
#define GRCAN_VALID_TR_SIZE_MASK

#define GRCAN_INVALID_BUFFER_SIZE(s)

#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
#error "Invalid default buffer size"
#endif

struct grcan_dma_buffer {};

struct grcan_dma {};

/* GRCAN configuration parameters */
struct grcan_device_config {};

#define GRCAN_DEFAULT_DEVICE_CONFIG

#define GRCAN_TXBUG_SAFE_GRLIB_VERSION
#define GRLIB_VERSION_MASK

/* GRCAN private data structure */
struct grcan_priv {};

/* Wait time for a short wait for ongoing to clear */
#define GRCAN_SHORTWAIT_USECS

/* Limit on the number of transmitted bits of an eff frame according to the CAN
 * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
 * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
 * bits end of frame
 */
#define GRCAN_EFF_FRAME_MAX_BITS

#if defined(__BIG_ENDIAN)
static inline u32 grcan_read_reg(u32 __iomem *reg)
{
	return ioread32be(reg);
}

static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
{
	iowrite32be(val, reg);
}
#else
static inline u32 grcan_read_reg(u32 __iomem *reg)
{}

static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
{}
#endif

static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
{}

static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
{}

static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
{}

static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
{}

/* a and b should both be in [0,size] and a == b == size should not hold */
static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
{}

/* a and b should both be in [0,size) */
static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
{}

/* Available slots for new transmissions */
static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
{}

/* Configuration parameters that can be set via module parameters */
static struct grcan_device_config grcan_module_config =;

static const struct can_bittiming_const grcan_bittiming_const =;

static int grcan_set_bittiming(struct net_device *dev)
{}

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

static int grcan_poll(struct napi_struct *napi, int budget);

/* Reset device, but keep configuration information */
static void grcan_reset(struct net_device *dev)
{}

/* stop device without changing any configurations */
static void grcan_stop_hardware(struct net_device *dev)
{}

/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
 * is true and free them otherwise.
 *
 * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
 * continue until priv->eskbp catches up to regs->txrd.
 *
 * priv->lock *must* be held when calling this function
 */
static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
{}

static void grcan_lost_one_shot_frame(struct net_device *dev)
{}

static void grcan_err(struct net_device *dev, u32 sources, u32 status)
{}

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

/* Reset device and restart operations from where they were.
 *
 * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
 * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
 * for single shot)
 */
static void grcan_running_reset(struct timer_list *t)
{}

/* Waiting time in usecs corresponding to the transmission of three maximum
 * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
 * of time makes sure that the can controller have time to finish sending or
 * receiving a frame with a good margin.
 *
 * usecs/sec * number of frames * bits/frame / bits/sec
 */
static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
{}

/* Set timer so that it will not fire until after a period in which the can
 * controller have a good margin to finish transmitting a frame unless it has
 * hanged
 */
static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
{}

/* Disable channels and schedule a running reset */
static void grcan_initiate_running_reset(struct timer_list *t)
{}

static void grcan_free_dma_buffers(struct net_device *dev)
{}

static int grcan_allocate_dma_buffers(struct net_device *dev,
				      size_t tsize, size_t rsize)
{}

/* priv->lock *must* be held when calling this function */
static int grcan_start(struct net_device *dev)
{}

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

static int grcan_open(struct net_device *dev)
{}

static int grcan_close(struct net_device *dev)
{}

static void grcan_transmit_catch_up(struct net_device *dev)
{}

static int grcan_receive(struct net_device *dev, int budget)
{}

static int grcan_poll(struct napi_struct *napi, int budget)
{}

/* Work tx bug by waiting while for the risky situation to clear. If that fails,
 * drop a frame in one-shot mode or indicate a busy device otherwise.
 *
 * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
 * value that should be returned by grcan_start_xmit when aborting the xmit.
 */
static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
				  u32 txwr, u32 oneshotmode,
				  netdev_tx_t *netdev_tx_status)
{}

/* Notes on the tx cyclic buffer handling:
 *
 * regs->txwr	- the next slot for the driver to put data to be sent
 * regs->txrd	- the next slot for the device to read data
 * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
 *
 * grcan_start_xmit can enter more messages as long as regs->txwr does
 * not reach priv->eskbp (within 1 message gap)
 *
 * The device sends messages until regs->txrd reaches regs->txwr
 *
 * The interrupt calls handler calls can_put_echo_skb until
 * priv->eskbp reaches regs->txrd
 */
static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
				    struct net_device *dev)
{}

/* ========== Setting up sysfs interface and module parameters ========== */

#define GRCAN_NOT_BOOL(unsigned_val)

#define GRCAN_MODULE_PARAM(name, mtype, valcheckf, desc)

#define GRCAN_CONFIG_ATTR(name, desc)

/* The following configuration options are made available both via module
 * parameters and writable sysfs files. See the chapter about GRCAN in the
 * documentation for the GRLIB VHDL library for further details.
 */
GRCAN_CONFIG_ATTR();

GRCAN_CONFIG_ATTR();

GRCAN_CONFIG_ATTR();

/* The tx and rx buffer size configuration options are only available via module
 * parameters.
 */
GRCAN_MODULE_PARAM();
GRCAN_MODULE_PARAM();

/* Function that makes sure that configuration done using
 * module parameters are set to valid values
 */
static void grcan_sanitize_module_config(struct platform_device *ofdev)
{}

static const struct attribute *const sysfs_grcan_attrs[] =;

static const struct attribute_group sysfs_grcan_group =;

/* ========== Setting up the driver ========== */

static const struct net_device_ops grcan_netdev_ops =;

static const struct ethtool_ops grcan_ethtool_ops =;

static int grcan_setup_netdev(struct platform_device *ofdev,
			      void __iomem *base,
			      int irq, u32 ambafreq, bool txbug)
{}

static int grcan_probe(struct platform_device *ofdev)
{}

static void grcan_remove(struct platform_device *ofdev)
{}

static const struct of_device_id grcan_match[] =;

MODULE_DEVICE_TABLE(of, grcan_match);

static struct platform_driver grcan_driver =;

module_platform_driver();

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