Commit 8ac8321e authored by Stephane Grosjean's avatar Stephane Grosjean Committed by Marc Kleine-Budde

can: peak: add support for PEAK PCAN-PCIe FD CAN-FD boards

This patch adds the support of the PCAN-PCI Express FD boards made
by PEAK-System, for computers using the PCI Express slot.

The PCAN-PCI Express FD has one or two CAN FD channels, depending
on the model. A galvanic isolation of the CAN ports protects
the electronics of the card and the respective computer against
disturbances of up to 500 Volts. The PCAN-PCI Express FD can be operated
with ambient temperatures in a range of -40 to +85 °C.

Such boards run an extented version of the CAN-FD IP running into USB
CAN-FD interfaces from PEAK-System, so this patch adds several new commands
and their corresponding data types to the PEAK CAN-FD common definitions
header file too.
Signed-off-by: default avatarStephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent c3df7c57
...@@ -142,6 +142,7 @@ source "drivers/net/can/cc770/Kconfig" ...@@ -142,6 +142,7 @@ source "drivers/net/can/cc770/Kconfig"
source "drivers/net/can/ifi_canfd/Kconfig" source "drivers/net/can/ifi_canfd/Kconfig"
source "drivers/net/can/m_can/Kconfig" source "drivers/net/can/m_can/Kconfig"
source "drivers/net/can/mscan/Kconfig" source "drivers/net/can/mscan/Kconfig"
source "drivers/net/can/peak_canfd/Kconfig"
source "drivers/net/can/rcar/Kconfig" source "drivers/net/can/rcar/Kconfig"
source "drivers/net/can/sja1000/Kconfig" source "drivers/net/can/sja1000/Kconfig"
source "drivers/net/can/softing/Kconfig" source "drivers/net/can/softing/Kconfig"
......
...@@ -26,6 +26,7 @@ obj-$(CONFIG_CAN_IFI_CANFD) += ifi_canfd/ ...@@ -26,6 +26,7 @@ obj-$(CONFIG_CAN_IFI_CANFD) += ifi_canfd/
obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o
obj-$(CONFIG_CAN_MSCAN) += mscan/ obj-$(CONFIG_CAN_MSCAN) += mscan/
obj-$(CONFIG_CAN_M_CAN) += m_can/ obj-$(CONFIG_CAN_M_CAN) += m_can/
obj-$(CONFIG_CAN_PEAK_PCIEFD) += peak_canfd/
obj-$(CONFIG_CAN_SJA1000) += sja1000/ obj-$(CONFIG_CAN_SJA1000) += sja1000/
obj-$(CONFIG_CAN_SUN4I) += sun4i_can.o obj-$(CONFIG_CAN_SUN4I) += sun4i_can.o
obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
......
config CAN_PEAK_PCIEFD
depends on PCI
tristate "PEAK-System PCAN-PCIe FD cards"
---help---
This driver adds support for the PEAK-System PCI Express FD
CAN-FD cards family.
These 1x or 2x CAN-FD channels cards offer CAN 2.0 a/b as well as
CAN-FD access to the CAN bus. Besides the nominal bitrate of up to
1 Mbit/s, the data bytes of CAN-FD frames can be transmitted with
up to 12 Mbit/s. A galvanic isolation of the CAN ports protects the
electronics of the card and the respective computer against
disturbances of up to 500 Volts. The PCAN-PCI Express FD can be
operated with ambient temperatures in a range of -40 to +85 °C.
#
# Makefile for the PEAK-System CAN-FD IP module drivers
#
obj-$(CONFIG_CAN_PEAK_PCIEFD) += peak_pciefd.o
peak_pciefd-y := peak_pciefd_main.o peak_canfd.o
This diff is collapsed.
/*
* CAN driver for PEAK System micro-CAN based adapters
*
* Copyright (C) 2003-2011 PEAK System-Technik GmbH
* Copyright (C) 2011-2013 Stephane Grosjean <s.grosjean@peak-system.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published
* by the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#ifndef PEAK_CANFD_USER_H
#define PEAK_CANFD_USER_H
#include <linux/can/dev/peak_canfd.h>
#define PCANFD_ECHO_SKB_DEF -1
/* data structure private to each uCAN interface */
struct peak_canfd_priv {
struct can_priv can; /* socket-can private data */
struct net_device *ndev; /* network device */
int index; /* channel index */
struct can_berr_counter bec; /* rx/tx err counters */
int echo_idx; /* echo skb free slot index */
spinlock_t echo_lock;
int cmd_len;
void *cmd_buffer;
int cmd_maxlen;
int (*pre_cmd)(struct peak_canfd_priv *priv);
int (*write_cmd)(struct peak_canfd_priv *priv);
int (*post_cmd)(struct peak_canfd_priv *priv);
int (*enable_tx_path)(struct peak_canfd_priv *priv);
void *(*alloc_tx_msg)(struct peak_canfd_priv *priv, u16 msg_size,
int *room_left);
int (*write_tx_msg)(struct peak_canfd_priv *priv,
struct pucan_tx_msg *msg);
};
struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
int echo_skb_max);
int peak_canfd_handle_msg(struct peak_canfd_priv *priv,
struct pucan_rx_msg *msg);
int peak_canfd_handle_msgs_list(struct peak_canfd_priv *priv,
struct pucan_rx_msg *rx_msg, int rx_count);
#endif
This diff is collapsed.
...@@ -23,11 +23,14 @@ ...@@ -23,11 +23,14 @@
#define PUCAN_CMD_LISTEN_ONLY_MODE 0x003 #define PUCAN_CMD_LISTEN_ONLY_MODE 0x003
#define PUCAN_CMD_TIMING_SLOW 0x004 #define PUCAN_CMD_TIMING_SLOW 0x004
#define PUCAN_CMD_TIMING_FAST 0x005 #define PUCAN_CMD_TIMING_FAST 0x005
#define PUCAN_CMD_SET_STD_FILTER 0x006
#define PUCAN_CMD_RESERVED2 0x007
#define PUCAN_CMD_FILTER_STD 0x008 #define PUCAN_CMD_FILTER_STD 0x008
#define PUCAN_CMD_TX_ABORT 0x009 #define PUCAN_CMD_TX_ABORT 0x009
#define PUCAN_CMD_WR_ERR_CNT 0x00a #define PUCAN_CMD_WR_ERR_CNT 0x00a
#define PUCAN_CMD_SET_EN_OPTION 0x00b #define PUCAN_CMD_SET_EN_OPTION 0x00b
#define PUCAN_CMD_CLR_DIS_OPTION 0x00c #define PUCAN_CMD_CLR_DIS_OPTION 0x00c
#define PUCAN_CMD_RX_BARRIER 0x010
#define PUCAN_CMD_END_OF_COLLECTION 0x3ff #define PUCAN_CMD_END_OF_COLLECTION 0x3ff
/* uCAN received messages list */ /* uCAN received messages list */
...@@ -35,6 +38,10 @@ ...@@ -35,6 +38,10 @@
#define PUCAN_MSG_ERROR 0x0002 #define PUCAN_MSG_ERROR 0x0002
#define PUCAN_MSG_STATUS 0x0003 #define PUCAN_MSG_STATUS 0x0003
#define PUCAN_MSG_BUSLOAD 0x0004 #define PUCAN_MSG_BUSLOAD 0x0004
#define PUCAN_MSG_CACHE_CRITICAL 0x0102
/* uCAN transmitted messages */
#define PUCAN_MSG_CAN_TX 0x1000 #define PUCAN_MSG_CAN_TX 0x1000
/* uCAN command common header */ /* uCAN command common header */
...@@ -43,6 +50,12 @@ struct __packed pucan_command { ...@@ -43,6 +50,12 @@ struct __packed pucan_command {
u16 args[3]; u16 args[3];
}; };
/* return the opcode from the opcode_channel field of a command */
static inline u16 pucan_cmd_get_opcode(struct pucan_command *c)
{
return le16_to_cpu(c->opcode_channel) & 0x3ff;
}
#define PUCAN_TSLOW_BRP_BITS 10 #define PUCAN_TSLOW_BRP_BITS 10
#define PUCAN_TSLOW_TSGEG1_BITS 8 #define PUCAN_TSLOW_TSGEG1_BITS 8
#define PUCAN_TSLOW_TSGEG2_BITS 7 #define PUCAN_TSLOW_TSGEG2_BITS 7
...@@ -108,6 +121,27 @@ struct __packed pucan_filter_std { ...@@ -108,6 +121,27 @@ struct __packed pucan_filter_std {
__le32 mask; /* CAN-ID bitmask in idx range */ __le32 mask; /* CAN-ID bitmask in idx range */
}; };
#define PUCAN_FLTSTD_ROW_IDX_MAX ((1 << PUCAN_FLTSTD_ROW_IDX_BITS) - 1)
/* uCAN SET_STD_FILTER command fields */
struct __packed pucan_std_filter {
__le16 opcode_channel;
u8 unused;
u8 idx;
__le32 mask; /* CAN-ID bitmask in idx range */
};
/* uCAN TX_ABORT commands fields */
#define PUCAN_TX_ABORT_FLUSH 0x0001
struct __packed pucan_tx_abort {
__le16 opcode_channel;
__le16 flags;
u32 unused;
};
/* uCAN WR_ERR_CNT command fields */ /* uCAN WR_ERR_CNT command fields */
#define PUCAN_WRERRCNT_TE 0x4000 /* Tx error cntr write Enable */ #define PUCAN_WRERRCNT_TE 0x4000 /* Tx error cntr write Enable */
#define PUCAN_WRERRCNT_RE 0x8000 /* Rx error cntr write Enable */ #define PUCAN_WRERRCNT_RE 0x8000 /* Rx error cntr write Enable */
...@@ -184,6 +218,12 @@ struct __packed pucan_error_msg { ...@@ -184,6 +218,12 @@ struct __packed pucan_error_msg {
u8 rx_err_cnt; u8 rx_err_cnt;
}; };
static inline int pucan_error_get_channel(const struct pucan_error_msg *msg)
{
return msg->channel_type_d & 0x0f;
}
#define PUCAN_RX_BARRIER 0x10
#define PUCAN_BUS_PASSIVE 0x20 #define PUCAN_BUS_PASSIVE 0x20
#define PUCAN_BUS_WARNING 0x40 #define PUCAN_BUS_WARNING 0x40
#define PUCAN_BUS_BUSOFF 0x80 #define PUCAN_BUS_BUSOFF 0x80
...@@ -197,6 +237,31 @@ struct __packed pucan_status_msg { ...@@ -197,6 +237,31 @@ struct __packed pucan_status_msg {
u8 unused[3]; u8 unused[3];
}; };
static inline int pucan_status_get_channel(const struct pucan_status_msg *msg)
{
return msg->channel_p_w_b & 0x0f;
}
static inline int pucan_status_is_rx_barrier(const struct pucan_status_msg *msg)
{
return msg->channel_p_w_b & PUCAN_RX_BARRIER;
}
static inline int pucan_status_is_passive(const struct pucan_status_msg *msg)
{
return msg->channel_p_w_b & PUCAN_BUS_PASSIVE;
}
static inline int pucan_status_is_warning(const struct pucan_status_msg *msg)
{
return msg->channel_p_w_b & PUCAN_BUS_WARNING;
}
static inline int pucan_status_is_busoff(const struct pucan_status_msg *msg)
{
return msg->channel_p_w_b & PUCAN_BUS_BUSOFF;
}
/* uCAN transmitted message format */ /* uCAN transmitted message format */
#define PUCAN_MSG_CHANNEL_DLC(c, d) (((c) & 0xf) | ((d) << 4)) #define PUCAN_MSG_CHANNEL_DLC(c, d) (((c) & 0xf) | ((d) << 4))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment