xref: /openbmc/linux/drivers/net/can/kvaser_pciefd.c (revision 262d7a52ba27525e3c1203230c9f0524e48bbb34)
126ad340eSHenning Colliander // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
226ad340eSHenning Colliander /* Copyright (C) 2018 KVASER AB, Sweden. All rights reserved.
326ad340eSHenning Colliander  * Parts of this driver are based on the following:
426ad340eSHenning Colliander  *  - Kvaser linux pciefd driver (version 5.25)
526ad340eSHenning Colliander  *  - PEAK linux canfd driver
626ad340eSHenning Colliander  *  - Altera Avalon EPCS flash controller driver
726ad340eSHenning Colliander  */
826ad340eSHenning Colliander 
926ad340eSHenning Colliander #include <linux/kernel.h>
1026ad340eSHenning Colliander #include <linux/module.h>
1126ad340eSHenning Colliander #include <linux/device.h>
12fa5cc7e1SVincent Mailhol #include <linux/ethtool.h>
1326ad340eSHenning Colliander #include <linux/pci.h>
1426ad340eSHenning Colliander #include <linux/can/dev.h>
1526ad340eSHenning Colliander #include <linux/timer.h>
1626ad340eSHenning Colliander #include <linux/netdevice.h>
1726ad340eSHenning Colliander #include <linux/crc32.h>
1826ad340eSHenning Colliander #include <linux/iopoll.h>
1926ad340eSHenning Colliander 
2026ad340eSHenning Colliander MODULE_LICENSE("Dual BSD/GPL");
2126ad340eSHenning Colliander MODULE_AUTHOR("Kvaser AB <support@kvaser.com>");
2226ad340eSHenning Colliander MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
2326ad340eSHenning Colliander 
2426ad340eSHenning Colliander #define KVASER_PCIEFD_DRV_NAME "kvaser_pciefd"
2526ad340eSHenning Colliander 
2626ad340eSHenning Colliander #define KVASER_PCIEFD_WAIT_TIMEOUT msecs_to_jiffies(1000)
2726ad340eSHenning Colliander #define KVASER_PCIEFD_BEC_POLL_FREQ (jiffies + msecs_to_jiffies(200))
2826ad340eSHenning Colliander #define KVASER_PCIEFD_MAX_ERR_REP 256
2926ad340eSHenning Colliander #define KVASER_PCIEFD_CAN_TX_MAX_COUNT 17
3026ad340eSHenning Colliander #define KVASER_PCIEFD_MAX_CAN_CHANNELS 4
3126ad340eSHenning Colliander #define KVASER_PCIEFD_DMA_COUNT 2
3226ad340eSHenning Colliander 
3326ad340eSHenning Colliander #define KVASER_PCIEFD_DMA_SIZE (4 * 1024)
3426ad340eSHenning Colliander #define KVASER_PCIEFD_64BIT_DMA_BIT BIT(0)
3526ad340eSHenning Colliander 
3626ad340eSHenning Colliander #define KVASER_PCIEFD_VENDOR 0x1a07
3726ad340eSHenning Colliander #define KVASER_PCIEFD_4HS_ID 0x0d
3826ad340eSHenning Colliander #define KVASER_PCIEFD_2HS_ID 0x0e
3926ad340eSHenning Colliander #define KVASER_PCIEFD_HS_ID 0x0f
4026ad340eSHenning Colliander #define KVASER_PCIEFD_MINIPCIE_HS_ID 0x10
4126ad340eSHenning Colliander #define KVASER_PCIEFD_MINIPCIE_2HS_ID 0x11
4226ad340eSHenning Colliander 
4326ad340eSHenning Colliander /* PCIe IRQ registers */
4426ad340eSHenning Colliander #define KVASER_PCIEFD_IRQ_REG 0x40
4526ad340eSHenning Colliander #define KVASER_PCIEFD_IEN_REG 0x50
4626ad340eSHenning Colliander /* DMA map */
4726ad340eSHenning Colliander #define KVASER_PCIEFD_DMA_MAP_BASE 0x1000
4826ad340eSHenning Colliander /* Kvaser KCAN CAN controller registers */
4926ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN0_BASE 0x10000
5026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_BASE_OFFSET 0x1000
5126ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_FIFO_REG 0x100
5226ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_FIFO_LAST_REG 0x180
5326ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_CTRL_REG 0x2c0
5426ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_CMD_REG 0x400
5526ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IEN_REG 0x408
5626ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_REG 0x410
5726ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_TX_NPACKETS_REG 0x414
5826ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_REG 0x418
5926ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_REG 0x41c
6026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_BTRN_REG 0x420
617c6e6bceSJimmy Assarsson #define KVASER_PCIEFD_KCAN_BUS_LOAD_REG 0x424
6226ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_BTRD_REG 0x428
6326ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_PWM_REG 0x430
6426ad340eSHenning Colliander /* Loopback control register */
6526ad340eSHenning Colliander #define KVASER_PCIEFD_LOOP_REG 0x1f000
6626ad340eSHenning Colliander /* System identification and information registers */
6726ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_BASE 0x1f020
6826ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_VERSION_REG (KVASER_PCIEFD_SYSID_BASE + 0x8)
6926ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_CANFREQ_REG (KVASER_PCIEFD_SYSID_BASE + 0xc)
70ec44dd57SChrister Beskow #define KVASER_PCIEFD_SYSID_BUSFREQ_REG (KVASER_PCIEFD_SYSID_BASE + 0x10)
7126ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_BUILD_REG (KVASER_PCIEFD_SYSID_BASE + 0x14)
7226ad340eSHenning Colliander /* Shared receive buffer registers */
7326ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_BASE 0x1f200
74c589557dSJimmy Assarsson #define KVASER_PCIEFD_SRB_FIFO_LAST_REG (KVASER_PCIEFD_SRB_BASE + 0x1f4)
7526ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CMD_REG (KVASER_PCIEFD_SRB_BASE + 0x200)
7626ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IEN_REG (KVASER_PCIEFD_SRB_BASE + 0x204)
7726ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_REG (KVASER_PCIEFD_SRB_BASE + 0x20c)
7826ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_STAT_REG (KVASER_PCIEFD_SRB_BASE + 0x210)
79c589557dSJimmy Assarsson #define KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG (KVASER_PCIEFD_SRB_BASE + 0x214)
8026ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CTRL_REG (KVASER_PCIEFD_SRB_BASE + 0x218)
8126ad340eSHenning Colliander /* EPCS flash controller registers */
8226ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_BASE 0x1fc00
8326ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_RX_REG KVASER_PCIEFD_SPI_BASE
8426ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_TX_REG (KVASER_PCIEFD_SPI_BASE + 0x4)
8526ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_STATUS_REG (KVASER_PCIEFD_SPI_BASE + 0x8)
8626ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_CTRL_REG (KVASER_PCIEFD_SPI_BASE + 0xc)
8726ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_SSEL_REG (KVASER_PCIEFD_SPI_BASE + 0x14)
8826ad340eSHenning Colliander 
8926ad340eSHenning Colliander #define KVASER_PCIEFD_IRQ_ALL_MSK 0x1f
9026ad340eSHenning Colliander #define KVASER_PCIEFD_IRQ_SRB BIT(4)
9126ad340eSHenning Colliander 
9226ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_NRCHAN_SHIFT 24
9326ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_MAJOR_VER_SHIFT 16
9426ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_BUILD_VER_SHIFT 1
9526ad340eSHenning Colliander 
9626ad340eSHenning Colliander /* Reset DMA buffer 0, 1 and FIFO offset */
9726ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CMD_RDB0 BIT(4)
9826ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CMD_RDB1 BIT(5)
9926ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CMD_FOR BIT(0)
10026ad340eSHenning Colliander 
10126ad340eSHenning Colliander /* DMA packet done, buffer 0 and 1 */
10226ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_DPD0 BIT(8)
10326ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_DPD1 BIT(9)
10426ad340eSHenning Colliander /* DMA overflow, buffer 0 and 1 */
10526ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_DOF0 BIT(10)
10626ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_DOF1 BIT(11)
10726ad340eSHenning Colliander /* DMA underflow, buffer 0 and 1 */
10826ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_DUF0 BIT(12)
10926ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_DUF1 BIT(13)
11026ad340eSHenning Colliander 
11126ad340eSHenning Colliander /* DMA idle */
11226ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_STAT_DI BIT(15)
11326ad340eSHenning Colliander /* DMA support */
11426ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_STAT_DMA BIT(24)
11526ad340eSHenning Colliander 
116c589557dSJimmy Assarsson /* SRB current packet level */
117c589557dSJimmy Assarsson #define KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK 0xff
118c589557dSJimmy Assarsson 
11926ad340eSHenning Colliander /* DMA Enable */
12026ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE BIT(0)
12126ad340eSHenning Colliander 
12226ad340eSHenning Colliander /* EPCS flash controller definitions */
12326ad340eSHenning Colliander #define KVASER_PCIEFD_CFG_IMG_SZ (64 * 1024)
12426ad340eSHenning Colliander #define KVASER_PCIEFD_CFG_IMG_OFFSET (31 * 65536L)
12526ad340eSHenning Colliander #define KVASER_PCIEFD_CFG_MAX_PARAMS 256
12626ad340eSHenning Colliander #define KVASER_PCIEFD_CFG_MAGIC 0xcafef00d
12726ad340eSHenning Colliander #define KVASER_PCIEFD_CFG_PARAM_MAX_SZ 24
12826ad340eSHenning Colliander #define KVASER_PCIEFD_CFG_SYS_VER 1
12926ad340eSHenning Colliander #define KVASER_PCIEFD_CFG_PARAM_NR_CHAN 130
13026ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_TMT BIT(5)
13126ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_TRDY BIT(6)
13226ad340eSHenning Colliander #define KVASER_PCIEFD_SPI_RRDY BIT(7)
13326ad340eSHenning Colliander #define KVASER_PCIEFD_FLASH_ID_EPCS16 0x14
13426ad340eSHenning Colliander /* Commands for controlling the onboard flash */
13526ad340eSHenning Colliander #define KVASER_PCIEFD_FLASH_RES_CMD 0xab
13626ad340eSHenning Colliander #define KVASER_PCIEFD_FLASH_READ_CMD 0x3
13726ad340eSHenning Colliander #define KVASER_PCIEFD_FLASH_STATUS_CMD 0x5
13826ad340eSHenning Colliander 
13926ad340eSHenning Colliander /* Kvaser KCAN definitions */
14026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_CTRL_EFLUSH (4 << 29)
14126ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_CTRL_EFRAME (5 << 29)
14226ad340eSHenning Colliander 
14326ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_CMD_SEQ_SHIFT 16
14426ad340eSHenning Colliander /* Request status packet */
14526ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_CMD_SRQ BIT(0)
14626ad340eSHenning Colliander /* Abort, flush and reset */
14726ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_CMD_AT BIT(1)
14826ad340eSHenning Colliander 
14926ad340eSHenning Colliander /* Tx FIFO unaligned read */
15026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_TAR BIT(0)
15126ad340eSHenning Colliander /* Tx FIFO unaligned end */
15226ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_TAE BIT(1)
15326ad340eSHenning Colliander /* Bus parameter protection error */
15426ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_BPP BIT(2)
15526ad340eSHenning Colliander /* FDF bit when controller is in classic mode */
15626ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_FDIC BIT(3)
15726ad340eSHenning Colliander /* Rx FIFO overflow */
15826ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_ROF BIT(5)
15926ad340eSHenning Colliander /* Abort done */
16026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_ABD BIT(13)
16126ad340eSHenning Colliander /* Tx buffer flush done */
16226ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_TFD BIT(14)
16326ad340eSHenning Colliander /* Tx FIFO overflow */
16426ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_TOF BIT(15)
16526ad340eSHenning Colliander /* Tx FIFO empty */
16626ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_TE BIT(16)
16726ad340eSHenning Colliander /* Transmitter unaligned */
16826ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_TAL BIT(17)
16926ad340eSHenning Colliander 
17026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_TX_NPACKETS_MAX_SHIFT 16
17126ad340eSHenning Colliander 
17226ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_SEQNO_SHIFT 24
17326ad340eSHenning Colliander /* Abort request */
17426ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_AR BIT(7)
17526ad340eSHenning Colliander /* Idle state. Controller in reset mode and no abort or flush pending */
17626ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_IDLE BIT(10)
17726ad340eSHenning Colliander /* Bus off */
17826ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_BOFF BIT(11)
17926ad340eSHenning Colliander /* Reset mode request */
18026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_RMR BIT(14)
18126ad340eSHenning Colliander /* Controller in reset mode */
18226ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_IRM BIT(15)
18326ad340eSHenning Colliander /* Controller got one-shot capability */
18426ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_CAP BIT(16)
18526ad340eSHenning Colliander /* Controller got CAN FD capability */
18626ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_FD BIT(19)
18726ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_BUS_OFF_MSK (KVASER_PCIEFD_KCAN_STAT_AR | \
18826ad340eSHenning Colliander 	KVASER_PCIEFD_KCAN_STAT_BOFF | KVASER_PCIEFD_KCAN_STAT_RMR | \
18926ad340eSHenning Colliander 	KVASER_PCIEFD_KCAN_STAT_IRM)
19026ad340eSHenning Colliander 
19126ad340eSHenning Colliander /* Reset mode */
19226ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_RM BIT(8)
19326ad340eSHenning Colliander /* Listen only mode */
19426ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_LOM BIT(9)
19526ad340eSHenning Colliander /* Error packet enable */
19626ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_EPEN BIT(12)
19726ad340eSHenning Colliander /* CAN FD non-ISO */
19826ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_NIFDEN BIT(15)
19926ad340eSHenning Colliander /* Acknowledgment packet type */
20026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_APT BIT(20)
20126ad340eSHenning Colliander /* Active error flag enable. Clear to force error passive */
20226ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_EEN BIT(23)
20326ad340eSHenning Colliander /* Classic CAN mode */
20426ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_CCM BIT(31)
20526ad340eSHenning Colliander 
20626ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_BTRN_SJW_SHIFT 13
20726ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_BTRN_TSEG1_SHIFT 17
20826ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_BTRN_TSEG2_SHIFT 26
20926ad340eSHenning Colliander 
21026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_PWM_TOP_SHIFT 16
21126ad340eSHenning Colliander 
21226ad340eSHenning Colliander /* Kvaser KCAN packet types */
21326ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_DATA 0
21426ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_ACK 1
21526ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_TXRQ 2
21626ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_ERROR 3
21726ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_EFLUSH_ACK 4
21826ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_EFRAME_ACK 5
21926ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_ACK_DATA 6
22026ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_STATUS 8
22126ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_BUS_LOAD 9
22226ad340eSHenning Colliander 
22326ad340eSHenning Colliander /* Kvaser KCAN packet common definitions */
22426ad340eSHenning Colliander #define KVASER_PCIEFD_PACKET_SEQ_MSK 0xff
22526ad340eSHenning Colliander #define KVASER_PCIEFD_PACKET_CHID_SHIFT 25
22626ad340eSHenning Colliander #define KVASER_PCIEFD_PACKET_TYPE_SHIFT 28
22726ad340eSHenning Colliander 
22826ad340eSHenning Colliander /* Kvaser KCAN TDATA and RDATA first word */
22926ad340eSHenning Colliander #define KVASER_PCIEFD_RPACKET_IDE BIT(30)
23026ad340eSHenning Colliander #define KVASER_PCIEFD_RPACKET_RTR BIT(29)
23126ad340eSHenning Colliander /* Kvaser KCAN TDATA and RDATA second word */
23226ad340eSHenning Colliander #define KVASER_PCIEFD_RPACKET_ESI BIT(13)
23326ad340eSHenning Colliander #define KVASER_PCIEFD_RPACKET_BRS BIT(14)
23426ad340eSHenning Colliander #define KVASER_PCIEFD_RPACKET_FDF BIT(15)
23526ad340eSHenning Colliander #define KVASER_PCIEFD_RPACKET_DLC_SHIFT 8
23626ad340eSHenning Colliander /* Kvaser KCAN TDATA second word */
23726ad340eSHenning Colliander #define KVASER_PCIEFD_TPACKET_SMS BIT(16)
23826ad340eSHenning Colliander #define KVASER_PCIEFD_TPACKET_AREQ BIT(31)
23926ad340eSHenning Colliander 
24026ad340eSHenning Colliander /* Kvaser KCAN APACKET */
24126ad340eSHenning Colliander #define KVASER_PCIEFD_APACKET_FLU BIT(8)
24226ad340eSHenning Colliander #define KVASER_PCIEFD_APACKET_CT BIT(9)
24326ad340eSHenning Colliander #define KVASER_PCIEFD_APACKET_ABL BIT(10)
24426ad340eSHenning Colliander #define KVASER_PCIEFD_APACKET_NACK BIT(11)
24526ad340eSHenning Colliander 
24626ad340eSHenning Colliander /* Kvaser KCAN SPACK first word */
24726ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_RXERR_SHIFT 8
24826ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_BOFF BIT(16)
24926ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_IDET BIT(20)
25026ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_IRM BIT(21)
25126ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_RMCD BIT(22)
25226ad340eSHenning Colliander /* Kvaser KCAN SPACK second word */
25326ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_AUTO BIT(21)
25426ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_EWLR BIT(23)
25526ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_EPLR BIT(24)
25626ad340eSHenning Colliander 
25736aea60fSJimmy Assarsson /* Kvaser KCAN_EPACK second word */
25836aea60fSJimmy Assarsson #define KVASER_PCIEFD_EPACK_DIR_TX BIT(0)
25936aea60fSJimmy Assarsson 
26026ad340eSHenning Colliander struct kvaser_pciefd;
26126ad340eSHenning Colliander 
26226ad340eSHenning Colliander struct kvaser_pciefd_can {
26326ad340eSHenning Colliander 	struct can_priv can;
26426ad340eSHenning Colliander 	struct kvaser_pciefd *kv_pcie;
26526ad340eSHenning Colliander 	void __iomem *reg_base;
26626ad340eSHenning Colliander 	struct can_berr_counter bec;
26726ad340eSHenning Colliander 	u8 cmd_seq;
26826ad340eSHenning Colliander 	int err_rep_cnt;
26926ad340eSHenning Colliander 	int echo_idx;
27026ad340eSHenning Colliander 	spinlock_t lock; /* Locks sensitive registers (e.g. MODE) */
27126ad340eSHenning Colliander 	spinlock_t echo_lock; /* Locks the message echo buffer */
27226ad340eSHenning Colliander 	struct timer_list bec_poll_timer;
27326ad340eSHenning Colliander 	struct completion start_comp, flush_comp;
27426ad340eSHenning Colliander };
27526ad340eSHenning Colliander 
27626ad340eSHenning Colliander struct kvaser_pciefd {
27726ad340eSHenning Colliander 	struct pci_dev *pci;
27826ad340eSHenning Colliander 	void __iomem *reg_base;
27926ad340eSHenning Colliander 	struct kvaser_pciefd_can *can[KVASER_PCIEFD_MAX_CAN_CHANNELS];
28026ad340eSHenning Colliander 	void *dma_data[KVASER_PCIEFD_DMA_COUNT];
28126ad340eSHenning Colliander 	u8 nr_channels;
282ec44dd57SChrister Beskow 	u32 bus_freq;
28326ad340eSHenning Colliander 	u32 freq;
28426ad340eSHenning Colliander 	u32 freq_to_ticks_div;
28526ad340eSHenning Colliander };
28626ad340eSHenning Colliander 
28726ad340eSHenning Colliander struct kvaser_pciefd_rx_packet {
28826ad340eSHenning Colliander 	u32 header[2];
28926ad340eSHenning Colliander 	u64 timestamp;
29026ad340eSHenning Colliander };
29126ad340eSHenning Colliander 
29226ad340eSHenning Colliander struct kvaser_pciefd_tx_packet {
29326ad340eSHenning Colliander 	u32 header[2];
29426ad340eSHenning Colliander 	u8 data[64];
29526ad340eSHenning Colliander };
29626ad340eSHenning Colliander 
29726ad340eSHenning Colliander static const struct can_bittiming_const kvaser_pciefd_bittiming_const = {
29826ad340eSHenning Colliander 	.name = KVASER_PCIEFD_DRV_NAME,
29926ad340eSHenning Colliander 	.tseg1_min = 1,
300470e14c0SJimmy Assarsson 	.tseg1_max = 512,
30126ad340eSHenning Colliander 	.tseg2_min = 1,
30226ad340eSHenning Colliander 	.tseg2_max = 32,
30326ad340eSHenning Colliander 	.sjw_max = 16,
30426ad340eSHenning Colliander 	.brp_min = 1,
305470e14c0SJimmy Assarsson 	.brp_max = 8192,
30626ad340eSHenning Colliander 	.brp_inc = 1,
30726ad340eSHenning Colliander };
30826ad340eSHenning Colliander 
30926ad340eSHenning Colliander struct kvaser_pciefd_cfg_param {
31026ad340eSHenning Colliander 	__le32 magic;
31126ad340eSHenning Colliander 	__le32 nr;
31226ad340eSHenning Colliander 	__le32 len;
31326ad340eSHenning Colliander 	u8 data[KVASER_PCIEFD_CFG_PARAM_MAX_SZ];
31426ad340eSHenning Colliander };
31526ad340eSHenning Colliander 
31626ad340eSHenning Colliander struct kvaser_pciefd_cfg_img {
31726ad340eSHenning Colliander 	__le32 version;
31826ad340eSHenning Colliander 	__le32 magic;
31926ad340eSHenning Colliander 	__le32 crc;
32026ad340eSHenning Colliander 	struct kvaser_pciefd_cfg_param params[KVASER_PCIEFD_CFG_MAX_PARAMS];
32126ad340eSHenning Colliander };
32226ad340eSHenning Colliander 
32326ad340eSHenning Colliander static struct pci_device_id kvaser_pciefd_id_table[] = {
32426ad340eSHenning Colliander 	{ PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_4HS_ID), },
32526ad340eSHenning Colliander 	{ PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_2HS_ID), },
32626ad340eSHenning Colliander 	{ PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_HS_ID), },
32726ad340eSHenning Colliander 	{ PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_HS_ID), },
32826ad340eSHenning Colliander 	{ PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_2HS_ID), },
32926ad340eSHenning Colliander 	{ 0,},
33026ad340eSHenning Colliander };
33126ad340eSHenning Colliander MODULE_DEVICE_TABLE(pci, kvaser_pciefd_id_table);
33226ad340eSHenning Colliander 
33326ad340eSHenning Colliander /* Onboard flash memory functions */
33426ad340eSHenning Colliander static int kvaser_pciefd_spi_wait_loop(struct kvaser_pciefd *pcie, int msk)
33526ad340eSHenning Colliander {
33626ad340eSHenning Colliander 	u32 res;
33726ad340eSHenning Colliander 
3387912fc99SJinpeng Cui 	return readl_poll_timeout(pcie->reg_base + KVASER_PCIEFD_SPI_STATUS_REG,
33926ad340eSHenning Colliander 			res, res & msk, 0, 10);
34026ad340eSHenning Colliander }
34126ad340eSHenning Colliander 
34226ad340eSHenning Colliander static int kvaser_pciefd_spi_cmd(struct kvaser_pciefd *pcie, const u8 *tx,
34326ad340eSHenning Colliander 				 u32 tx_len, u8 *rx, u32 rx_len)
34426ad340eSHenning Colliander {
34526ad340eSHenning Colliander 	int c;
34626ad340eSHenning Colliander 
34726ad340eSHenning Colliander 	iowrite32(BIT(0), pcie->reg_base + KVASER_PCIEFD_SPI_SSEL_REG);
34826ad340eSHenning Colliander 	iowrite32(BIT(10), pcie->reg_base + KVASER_PCIEFD_SPI_CTRL_REG);
34926ad340eSHenning Colliander 	ioread32(pcie->reg_base + KVASER_PCIEFD_SPI_RX_REG);
35026ad340eSHenning Colliander 
35126ad340eSHenning Colliander 	c = tx_len;
35226ad340eSHenning Colliander 	while (c--) {
35326ad340eSHenning Colliander 		if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_TRDY))
35426ad340eSHenning Colliander 			return -EIO;
35526ad340eSHenning Colliander 
35626ad340eSHenning Colliander 		iowrite32(*tx++, pcie->reg_base + KVASER_PCIEFD_SPI_TX_REG);
35726ad340eSHenning Colliander 
35826ad340eSHenning Colliander 		if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_RRDY))
35926ad340eSHenning Colliander 			return -EIO;
36026ad340eSHenning Colliander 
36126ad340eSHenning Colliander 		ioread32(pcie->reg_base + KVASER_PCIEFD_SPI_RX_REG);
36226ad340eSHenning Colliander 	}
36326ad340eSHenning Colliander 
36426ad340eSHenning Colliander 	c = rx_len;
36526ad340eSHenning Colliander 	while (c-- > 0) {
36626ad340eSHenning Colliander 		if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_TRDY))
36726ad340eSHenning Colliander 			return -EIO;
36826ad340eSHenning Colliander 
36926ad340eSHenning Colliander 		iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SPI_TX_REG);
37026ad340eSHenning Colliander 
37126ad340eSHenning Colliander 		if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_RRDY))
37226ad340eSHenning Colliander 			return -EIO;
37326ad340eSHenning Colliander 
37426ad340eSHenning Colliander 		*rx++ = ioread32(pcie->reg_base + KVASER_PCIEFD_SPI_RX_REG);
37526ad340eSHenning Colliander 	}
37626ad340eSHenning Colliander 
37726ad340eSHenning Colliander 	if (kvaser_pciefd_spi_wait_loop(pcie, KVASER_PCIEFD_SPI_TMT))
37826ad340eSHenning Colliander 		return -EIO;
37926ad340eSHenning Colliander 
38026ad340eSHenning Colliander 	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SPI_CTRL_REG);
38126ad340eSHenning Colliander 
38226ad340eSHenning Colliander 	if (c != -1) {
38326ad340eSHenning Colliander 		dev_err(&pcie->pci->dev, "Flash SPI transfer failed\n");
38426ad340eSHenning Colliander 		return -EIO;
38526ad340eSHenning Colliander 	}
38626ad340eSHenning Colliander 
38726ad340eSHenning Colliander 	return 0;
38826ad340eSHenning Colliander }
38926ad340eSHenning Colliander 
39026ad340eSHenning Colliander static int kvaser_pciefd_cfg_read_and_verify(struct kvaser_pciefd *pcie,
39126ad340eSHenning Colliander 					     struct kvaser_pciefd_cfg_img *img)
39226ad340eSHenning Colliander {
39326ad340eSHenning Colliander 	int offset = KVASER_PCIEFD_CFG_IMG_OFFSET;
39426ad340eSHenning Colliander 	int res, crc;
39526ad340eSHenning Colliander 	u8 *crc_buff;
39626ad340eSHenning Colliander 
39726ad340eSHenning Colliander 	u8 cmd[] = {
39826ad340eSHenning Colliander 		KVASER_PCIEFD_FLASH_READ_CMD,
39926ad340eSHenning Colliander 		(u8)((offset >> 16) & 0xff),
40026ad340eSHenning Colliander 		(u8)((offset >> 8) & 0xff),
40126ad340eSHenning Colliander 		(u8)(offset & 0xff)
40226ad340eSHenning Colliander 	};
40326ad340eSHenning Colliander 
40426ad340eSHenning Colliander 	res = kvaser_pciefd_spi_cmd(pcie, cmd, ARRAY_SIZE(cmd), (u8 *)img,
40526ad340eSHenning Colliander 				    KVASER_PCIEFD_CFG_IMG_SZ);
40626ad340eSHenning Colliander 	if (res)
40726ad340eSHenning Colliander 		return res;
40826ad340eSHenning Colliander 
40926ad340eSHenning Colliander 	crc_buff = (u8 *)img->params;
41026ad340eSHenning Colliander 
41126ad340eSHenning Colliander 	if (le32_to_cpu(img->version) != KVASER_PCIEFD_CFG_SYS_VER) {
41226ad340eSHenning Colliander 		dev_err(&pcie->pci->dev,
41326ad340eSHenning Colliander 			"Config flash corrupted, version number is wrong\n");
41426ad340eSHenning Colliander 		return -ENODEV;
41526ad340eSHenning Colliander 	}
41626ad340eSHenning Colliander 
41726ad340eSHenning Colliander 	if (le32_to_cpu(img->magic) != KVASER_PCIEFD_CFG_MAGIC) {
41826ad340eSHenning Colliander 		dev_err(&pcie->pci->dev,
41926ad340eSHenning Colliander 			"Config flash corrupted, magic number is wrong\n");
42026ad340eSHenning Colliander 		return -ENODEV;
42126ad340eSHenning Colliander 	}
42226ad340eSHenning Colliander 
42326ad340eSHenning Colliander 	crc = ~crc32_be(0xffffffff, crc_buff, sizeof(img->params));
42426ad340eSHenning Colliander 	if (le32_to_cpu(img->crc) != crc) {
42526ad340eSHenning Colliander 		dev_err(&pcie->pci->dev,
42626ad340eSHenning Colliander 			"Stored CRC does not match flash image contents\n");
42726ad340eSHenning Colliander 		return -EIO;
42826ad340eSHenning Colliander 	}
42926ad340eSHenning Colliander 
43026ad340eSHenning Colliander 	return 0;
43126ad340eSHenning Colliander }
43226ad340eSHenning Colliander 
43326ad340eSHenning Colliander static void kvaser_pciefd_cfg_read_params(struct kvaser_pciefd *pcie,
43426ad340eSHenning Colliander 					  struct kvaser_pciefd_cfg_img *img)
43526ad340eSHenning Colliander {
43626ad340eSHenning Colliander 	struct kvaser_pciefd_cfg_param *param;
43726ad340eSHenning Colliander 
43826ad340eSHenning Colliander 	param = &img->params[KVASER_PCIEFD_CFG_PARAM_NR_CHAN];
43926ad340eSHenning Colliander 	memcpy(&pcie->nr_channels, param->data, le32_to_cpu(param->len));
44026ad340eSHenning Colliander }
44126ad340eSHenning Colliander 
44226ad340eSHenning Colliander static int kvaser_pciefd_read_cfg(struct kvaser_pciefd *pcie)
44326ad340eSHenning Colliander {
44426ad340eSHenning Colliander 	int res;
44526ad340eSHenning Colliander 	struct kvaser_pciefd_cfg_img *img;
44626ad340eSHenning Colliander 
44726ad340eSHenning Colliander 	/* Read electronic signature */
44826ad340eSHenning Colliander 	u8 cmd[] = {KVASER_PCIEFD_FLASH_RES_CMD, 0, 0, 0};
44926ad340eSHenning Colliander 
45026ad340eSHenning Colliander 	res = kvaser_pciefd_spi_cmd(pcie, cmd, ARRAY_SIZE(cmd), cmd, 1);
45126ad340eSHenning Colliander 	if (res)
45226ad340eSHenning Colliander 		return -EIO;
45326ad340eSHenning Colliander 
45426ad340eSHenning Colliander 	img = kmalloc(KVASER_PCIEFD_CFG_IMG_SZ, GFP_KERNEL);
45526ad340eSHenning Colliander 	if (!img)
45626ad340eSHenning Colliander 		return -ENOMEM;
45726ad340eSHenning Colliander 
45826ad340eSHenning Colliander 	if (cmd[0] != KVASER_PCIEFD_FLASH_ID_EPCS16) {
45926ad340eSHenning Colliander 		dev_err(&pcie->pci->dev,
46026ad340eSHenning Colliander 			"Flash id is 0x%x instead of expected EPCS16 (0x%x)\n",
46126ad340eSHenning Colliander 			cmd[0], KVASER_PCIEFD_FLASH_ID_EPCS16);
46226ad340eSHenning Colliander 
46326ad340eSHenning Colliander 		res = -ENODEV;
46426ad340eSHenning Colliander 		goto image_free;
46526ad340eSHenning Colliander 	}
46626ad340eSHenning Colliander 
46726ad340eSHenning Colliander 	cmd[0] = KVASER_PCIEFD_FLASH_STATUS_CMD;
46826ad340eSHenning Colliander 	res = kvaser_pciefd_spi_cmd(pcie, cmd, 1, cmd, 1);
46926ad340eSHenning Colliander 	if (res) {
47026ad340eSHenning Colliander 		goto image_free;
47126ad340eSHenning Colliander 	} else if (cmd[0] & 1) {
47226ad340eSHenning Colliander 		res = -EIO;
47326ad340eSHenning Colliander 		/* No write is ever done, the WIP should never be set */
47426ad340eSHenning Colliander 		dev_err(&pcie->pci->dev, "Unexpected WIP bit set in flash\n");
47526ad340eSHenning Colliander 		goto image_free;
47626ad340eSHenning Colliander 	}
47726ad340eSHenning Colliander 
47826ad340eSHenning Colliander 	res = kvaser_pciefd_cfg_read_and_verify(pcie, img);
47926ad340eSHenning Colliander 	if (res) {
48026ad340eSHenning Colliander 		res = -EIO;
48126ad340eSHenning Colliander 		goto image_free;
48226ad340eSHenning Colliander 	}
48326ad340eSHenning Colliander 
48426ad340eSHenning Colliander 	kvaser_pciefd_cfg_read_params(pcie, img);
48526ad340eSHenning Colliander 
48626ad340eSHenning Colliander image_free:
48726ad340eSHenning Colliander 	kfree(img);
48826ad340eSHenning Colliander 	return res;
48926ad340eSHenning Colliander }
49026ad340eSHenning Colliander 
49126ad340eSHenning Colliander static void kvaser_pciefd_request_status(struct kvaser_pciefd_can *can)
49226ad340eSHenning Colliander {
49326ad340eSHenning Colliander 	u32 cmd;
49426ad340eSHenning Colliander 
49526ad340eSHenning Colliander 	cmd = KVASER_PCIEFD_KCAN_CMD_SRQ;
49626ad340eSHenning Colliander 	cmd |= ++can->cmd_seq << KVASER_PCIEFD_KCAN_CMD_SEQ_SHIFT;
49726ad340eSHenning Colliander 	iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG);
49826ad340eSHenning Colliander }
49926ad340eSHenning Colliander 
50026ad340eSHenning Colliander static void kvaser_pciefd_enable_err_gen(struct kvaser_pciefd_can *can)
50126ad340eSHenning Colliander {
50226ad340eSHenning Colliander 	u32 mode;
50326ad340eSHenning Colliander 	unsigned long irq;
50426ad340eSHenning Colliander 
50526ad340eSHenning Colliander 	spin_lock_irqsave(&can->lock, irq);
50626ad340eSHenning Colliander 	mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
50726ad340eSHenning Colliander 	if (!(mode & KVASER_PCIEFD_KCAN_MODE_EPEN)) {
50826ad340eSHenning Colliander 		mode |= KVASER_PCIEFD_KCAN_MODE_EPEN;
50926ad340eSHenning Colliander 		iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
51026ad340eSHenning Colliander 	}
51126ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->lock, irq);
51226ad340eSHenning Colliander }
51326ad340eSHenning Colliander 
51426ad340eSHenning Colliander static void kvaser_pciefd_disable_err_gen(struct kvaser_pciefd_can *can)
51526ad340eSHenning Colliander {
51626ad340eSHenning Colliander 	u32 mode;
51726ad340eSHenning Colliander 	unsigned long irq;
51826ad340eSHenning Colliander 
51926ad340eSHenning Colliander 	spin_lock_irqsave(&can->lock, irq);
52026ad340eSHenning Colliander 	mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
52126ad340eSHenning Colliander 	mode &= ~KVASER_PCIEFD_KCAN_MODE_EPEN;
52226ad340eSHenning Colliander 	iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
52326ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->lock, irq);
52426ad340eSHenning Colliander }
52526ad340eSHenning Colliander 
52626ad340eSHenning Colliander static int kvaser_pciefd_set_tx_irq(struct kvaser_pciefd_can *can)
52726ad340eSHenning Colliander {
52826ad340eSHenning Colliander 	u32 msk;
52926ad340eSHenning Colliander 
53026ad340eSHenning Colliander 	msk = KVASER_PCIEFD_KCAN_IRQ_TE | KVASER_PCIEFD_KCAN_IRQ_ROF |
53126ad340eSHenning Colliander 	      KVASER_PCIEFD_KCAN_IRQ_TOF | KVASER_PCIEFD_KCAN_IRQ_ABD |
53226ad340eSHenning Colliander 	      KVASER_PCIEFD_KCAN_IRQ_TAE | KVASER_PCIEFD_KCAN_IRQ_TAL |
53326ad340eSHenning Colliander 	      KVASER_PCIEFD_KCAN_IRQ_FDIC | KVASER_PCIEFD_KCAN_IRQ_BPP |
534*262d7a52SJimmy Assarsson 	      KVASER_PCIEFD_KCAN_IRQ_TAR;
53526ad340eSHenning Colliander 
53626ad340eSHenning Colliander 	iowrite32(msk, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
53726ad340eSHenning Colliander 
53826ad340eSHenning Colliander 	return 0;
53926ad340eSHenning Colliander }
54026ad340eSHenning Colliander 
54126ad340eSHenning Colliander static void kvaser_pciefd_setup_controller(struct kvaser_pciefd_can *can)
54226ad340eSHenning Colliander {
54326ad340eSHenning Colliander 	u32 mode;
54426ad340eSHenning Colliander 	unsigned long irq;
54526ad340eSHenning Colliander 
54626ad340eSHenning Colliander 	spin_lock_irqsave(&can->lock, irq);
54726ad340eSHenning Colliander 
54826ad340eSHenning Colliander 	mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
54926ad340eSHenning Colliander 	if (can->can.ctrlmode & CAN_CTRLMODE_FD) {
55026ad340eSHenning Colliander 		mode &= ~KVASER_PCIEFD_KCAN_MODE_CCM;
55126ad340eSHenning Colliander 		if (can->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)
55226ad340eSHenning Colliander 			mode |= KVASER_PCIEFD_KCAN_MODE_NIFDEN;
55326ad340eSHenning Colliander 		else
55426ad340eSHenning Colliander 			mode &= ~KVASER_PCIEFD_KCAN_MODE_NIFDEN;
55526ad340eSHenning Colliander 	} else {
55626ad340eSHenning Colliander 		mode |= KVASER_PCIEFD_KCAN_MODE_CCM;
55726ad340eSHenning Colliander 		mode &= ~KVASER_PCIEFD_KCAN_MODE_NIFDEN;
55826ad340eSHenning Colliander 	}
55926ad340eSHenning Colliander 
56026ad340eSHenning Colliander 	if (can->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
56126ad340eSHenning Colliander 		mode |= KVASER_PCIEFD_KCAN_MODE_LOM;
562bf7ac55eSJimmy Assarsson 	else
563bf7ac55eSJimmy Assarsson 		mode &= ~KVASER_PCIEFD_KCAN_MODE_LOM;
56426ad340eSHenning Colliander 
56526ad340eSHenning Colliander 	mode |= KVASER_PCIEFD_KCAN_MODE_EEN;
56626ad340eSHenning Colliander 	mode |= KVASER_PCIEFD_KCAN_MODE_EPEN;
56726ad340eSHenning Colliander 	/* Use ACK packet type */
56826ad340eSHenning Colliander 	mode &= ~KVASER_PCIEFD_KCAN_MODE_APT;
56926ad340eSHenning Colliander 	mode &= ~KVASER_PCIEFD_KCAN_MODE_RM;
57026ad340eSHenning Colliander 	iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
57126ad340eSHenning Colliander 
57226ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->lock, irq);
57326ad340eSHenning Colliander }
57426ad340eSHenning Colliander 
57526ad340eSHenning Colliander static void kvaser_pciefd_start_controller_flush(struct kvaser_pciefd_can *can)
57626ad340eSHenning Colliander {
57726ad340eSHenning Colliander 	u32 status;
57826ad340eSHenning Colliander 	unsigned long irq;
57926ad340eSHenning Colliander 
58026ad340eSHenning Colliander 	spin_lock_irqsave(&can->lock, irq);
58126ad340eSHenning Colliander 	iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
582*262d7a52SJimmy Assarsson 	iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
58326ad340eSHenning Colliander 		  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
58426ad340eSHenning Colliander 
58526ad340eSHenning Colliander 	status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG);
58626ad340eSHenning Colliander 	if (status & KVASER_PCIEFD_KCAN_STAT_IDLE) {
58726ad340eSHenning Colliander 		u32 cmd;
58826ad340eSHenning Colliander 
58926ad340eSHenning Colliander 		/* If controller is already idle, run abort, flush and reset */
59026ad340eSHenning Colliander 		cmd = KVASER_PCIEFD_KCAN_CMD_AT;
59126ad340eSHenning Colliander 		cmd |= ++can->cmd_seq << KVASER_PCIEFD_KCAN_CMD_SEQ_SHIFT;
59226ad340eSHenning Colliander 		iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG);
59326ad340eSHenning Colliander 	} else if (!(status & KVASER_PCIEFD_KCAN_STAT_RMR)) {
59426ad340eSHenning Colliander 		u32 mode;
59526ad340eSHenning Colliander 
59626ad340eSHenning Colliander 		/* Put controller in reset mode */
59726ad340eSHenning Colliander 		mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
59826ad340eSHenning Colliander 		mode |= KVASER_PCIEFD_KCAN_MODE_RM;
59926ad340eSHenning Colliander 		iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
60026ad340eSHenning Colliander 	}
60126ad340eSHenning Colliander 
60226ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->lock, irq);
60326ad340eSHenning Colliander }
60426ad340eSHenning Colliander 
60526ad340eSHenning Colliander static int kvaser_pciefd_bus_on(struct kvaser_pciefd_can *can)
60626ad340eSHenning Colliander {
60726ad340eSHenning Colliander 	u32 mode;
60826ad340eSHenning Colliander 	unsigned long irq;
60926ad340eSHenning Colliander 
61026ad340eSHenning Colliander 	del_timer(&can->bec_poll_timer);
61126ad340eSHenning Colliander 
61226ad340eSHenning Colliander 	if (!completion_done(&can->flush_comp))
61326ad340eSHenning Colliander 		kvaser_pciefd_start_controller_flush(can);
61426ad340eSHenning Colliander 
61526ad340eSHenning Colliander 	if (!wait_for_completion_timeout(&can->flush_comp,
61626ad340eSHenning Colliander 					 KVASER_PCIEFD_WAIT_TIMEOUT)) {
61726ad340eSHenning Colliander 		netdev_err(can->can.dev, "Timeout during bus on flush\n");
61826ad340eSHenning Colliander 		return -ETIMEDOUT;
61926ad340eSHenning Colliander 	}
62026ad340eSHenning Colliander 
62126ad340eSHenning Colliander 	spin_lock_irqsave(&can->lock, irq);
62226ad340eSHenning Colliander 	iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
62326ad340eSHenning Colliander 	iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
62426ad340eSHenning Colliander 
625*262d7a52SJimmy Assarsson 	iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
62626ad340eSHenning Colliander 		  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
62726ad340eSHenning Colliander 
62826ad340eSHenning Colliander 	mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
62926ad340eSHenning Colliander 	mode &= ~KVASER_PCIEFD_KCAN_MODE_RM;
63026ad340eSHenning Colliander 	iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
63126ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->lock, irq);
63226ad340eSHenning Colliander 
63326ad340eSHenning Colliander 	if (!wait_for_completion_timeout(&can->start_comp,
63426ad340eSHenning Colliander 					 KVASER_PCIEFD_WAIT_TIMEOUT)) {
63526ad340eSHenning Colliander 		netdev_err(can->can.dev, "Timeout during bus on reset\n");
63626ad340eSHenning Colliander 		return -ETIMEDOUT;
63726ad340eSHenning Colliander 	}
63826ad340eSHenning Colliander 	/* Reset interrupt handling */
63926ad340eSHenning Colliander 	iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
64026ad340eSHenning Colliander 	iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
64126ad340eSHenning Colliander 
64226ad340eSHenning Colliander 	kvaser_pciefd_set_tx_irq(can);
64326ad340eSHenning Colliander 	kvaser_pciefd_setup_controller(can);
64426ad340eSHenning Colliander 
64526ad340eSHenning Colliander 	can->can.state = CAN_STATE_ERROR_ACTIVE;
64626ad340eSHenning Colliander 	netif_wake_queue(can->can.dev);
64726ad340eSHenning Colliander 	can->bec.txerr = 0;
64826ad340eSHenning Colliander 	can->bec.rxerr = 0;
64926ad340eSHenning Colliander 	can->err_rep_cnt = 0;
65026ad340eSHenning Colliander 
65126ad340eSHenning Colliander 	return 0;
65226ad340eSHenning Colliander }
65326ad340eSHenning Colliander 
65426ad340eSHenning Colliander static void kvaser_pciefd_pwm_stop(struct kvaser_pciefd_can *can)
65526ad340eSHenning Colliander {
6561910cd88SChrister Beskow 	u8 top;
65726ad340eSHenning Colliander 	u32 pwm_ctrl;
65826ad340eSHenning Colliander 	unsigned long irq;
65926ad340eSHenning Colliander 
66026ad340eSHenning Colliander 	spin_lock_irqsave(&can->lock, irq);
66126ad340eSHenning Colliander 	pwm_ctrl = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG);
66226ad340eSHenning Colliander 	top = (pwm_ctrl >> KVASER_PCIEFD_KCAN_PWM_TOP_SHIFT) & 0xff;
66326ad340eSHenning Colliander 
6641910cd88SChrister Beskow 	/* Set duty cycle to zero */
6651910cd88SChrister Beskow 	pwm_ctrl |= top;
66626ad340eSHenning Colliander 	iowrite32(pwm_ctrl, can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG);
66726ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->lock, irq);
66826ad340eSHenning Colliander }
66926ad340eSHenning Colliander 
67026ad340eSHenning Colliander static void kvaser_pciefd_pwm_start(struct kvaser_pciefd_can *can)
67126ad340eSHenning Colliander {
67226ad340eSHenning Colliander 	int top, trigger;
67326ad340eSHenning Colliander 	u32 pwm_ctrl;
67426ad340eSHenning Colliander 	unsigned long irq;
67526ad340eSHenning Colliander 
67626ad340eSHenning Colliander 	kvaser_pciefd_pwm_stop(can);
67726ad340eSHenning Colliander 	spin_lock_irqsave(&can->lock, irq);
67826ad340eSHenning Colliander 
67926ad340eSHenning Colliander 	/* Set frequency to 500 KHz*/
680ec44dd57SChrister Beskow 	top = can->kv_pcie->bus_freq / (2 * 500000) - 1;
68126ad340eSHenning Colliander 
68226ad340eSHenning Colliander 	pwm_ctrl = top & 0xff;
68326ad340eSHenning Colliander 	pwm_ctrl |= (top & 0xff) << KVASER_PCIEFD_KCAN_PWM_TOP_SHIFT;
68426ad340eSHenning Colliander 	iowrite32(pwm_ctrl, can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG);
68526ad340eSHenning Colliander 
68626ad340eSHenning Colliander 	/* Set duty cycle to 95 */
68726ad340eSHenning Colliander 	trigger = (100 * top - 95 * (top + 1) + 50) / 100;
68826ad340eSHenning Colliander 	pwm_ctrl = trigger & 0xff;
68926ad340eSHenning Colliander 	pwm_ctrl |= (top & 0xff) << KVASER_PCIEFD_KCAN_PWM_TOP_SHIFT;
69026ad340eSHenning Colliander 	iowrite32(pwm_ctrl, can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG);
69126ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->lock, irq);
69226ad340eSHenning Colliander }
69326ad340eSHenning Colliander 
69426ad340eSHenning Colliander static int kvaser_pciefd_open(struct net_device *netdev)
69526ad340eSHenning Colliander {
69626ad340eSHenning Colliander 	int err;
69726ad340eSHenning Colliander 	struct kvaser_pciefd_can *can = netdev_priv(netdev);
69826ad340eSHenning Colliander 
69926ad340eSHenning Colliander 	err = open_candev(netdev);
70026ad340eSHenning Colliander 	if (err)
70126ad340eSHenning Colliander 		return err;
70226ad340eSHenning Colliander 
70326ad340eSHenning Colliander 	err = kvaser_pciefd_bus_on(can);
70413a84cf3SZhang Qilong 	if (err) {
70513a84cf3SZhang Qilong 		close_candev(netdev);
70626ad340eSHenning Colliander 		return err;
70713a84cf3SZhang Qilong 	}
70826ad340eSHenning Colliander 
70926ad340eSHenning Colliander 	return 0;
71026ad340eSHenning Colliander }
71126ad340eSHenning Colliander 
71226ad340eSHenning Colliander static int kvaser_pciefd_stop(struct net_device *netdev)
71326ad340eSHenning Colliander {
71426ad340eSHenning Colliander 	struct kvaser_pciefd_can *can = netdev_priv(netdev);
71526ad340eSHenning Colliander 	int ret = 0;
71626ad340eSHenning Colliander 
71726ad340eSHenning Colliander 	/* Don't interrupt ongoing flush */
71826ad340eSHenning Colliander 	if (!completion_done(&can->flush_comp))
71926ad340eSHenning Colliander 		kvaser_pciefd_start_controller_flush(can);
72026ad340eSHenning Colliander 
72126ad340eSHenning Colliander 	if (!wait_for_completion_timeout(&can->flush_comp,
72226ad340eSHenning Colliander 					 KVASER_PCIEFD_WAIT_TIMEOUT)) {
72326ad340eSHenning Colliander 		netdev_err(can->can.dev, "Timeout during stop\n");
72426ad340eSHenning Colliander 		ret = -ETIMEDOUT;
72526ad340eSHenning Colliander 	} else {
72626ad340eSHenning Colliander 		iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
72726ad340eSHenning Colliander 		del_timer(&can->bec_poll_timer);
72826ad340eSHenning Colliander 	}
729aed0e6caSJimmy Assarsson 	can->can.state = CAN_STATE_STOPPED;
73026ad340eSHenning Colliander 	close_candev(netdev);
73126ad340eSHenning Colliander 
73226ad340eSHenning Colliander 	return ret;
73326ad340eSHenning Colliander }
73426ad340eSHenning Colliander 
73526ad340eSHenning Colliander static int kvaser_pciefd_prepare_tx_packet(struct kvaser_pciefd_tx_packet *p,
73626ad340eSHenning Colliander 					   struct kvaser_pciefd_can *can,
73726ad340eSHenning Colliander 					   struct sk_buff *skb)
73826ad340eSHenning Colliander {
73926ad340eSHenning Colliander 	struct canfd_frame *cf = (struct canfd_frame *)skb->data;
74026ad340eSHenning Colliander 	int packet_size;
74126ad340eSHenning Colliander 	int seq = can->echo_idx;
74226ad340eSHenning Colliander 
74326ad340eSHenning Colliander 	memset(p, 0, sizeof(*p));
74426ad340eSHenning Colliander 
74526ad340eSHenning Colliander 	if (can->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
74626ad340eSHenning Colliander 		p->header[1] |= KVASER_PCIEFD_TPACKET_SMS;
74726ad340eSHenning Colliander 
74826ad340eSHenning Colliander 	if (cf->can_id & CAN_RTR_FLAG)
74926ad340eSHenning Colliander 		p->header[0] |= KVASER_PCIEFD_RPACKET_RTR;
75026ad340eSHenning Colliander 
75126ad340eSHenning Colliander 	if (cf->can_id & CAN_EFF_FLAG)
75226ad340eSHenning Colliander 		p->header[0] |= KVASER_PCIEFD_RPACKET_IDE;
75326ad340eSHenning Colliander 
75426ad340eSHenning Colliander 	p->header[0] |= cf->can_id & CAN_EFF_MASK;
7553ab4ce0dSOliver Hartkopp 	p->header[1] |= can_fd_len2dlc(cf->len) << KVASER_PCIEFD_RPACKET_DLC_SHIFT;
75626ad340eSHenning Colliander 	p->header[1] |= KVASER_PCIEFD_TPACKET_AREQ;
75726ad340eSHenning Colliander 
75826ad340eSHenning Colliander 	if (can_is_canfd_skb(skb)) {
75926ad340eSHenning Colliander 		p->header[1] |= KVASER_PCIEFD_RPACKET_FDF;
76026ad340eSHenning Colliander 		if (cf->flags & CANFD_BRS)
76126ad340eSHenning Colliander 			p->header[1] |= KVASER_PCIEFD_RPACKET_BRS;
76226ad340eSHenning Colliander 		if (cf->flags & CANFD_ESI)
76326ad340eSHenning Colliander 			p->header[1] |= KVASER_PCIEFD_RPACKET_ESI;
76426ad340eSHenning Colliander 	}
76526ad340eSHenning Colliander 
76626ad340eSHenning Colliander 	p->header[1] |= seq & KVASER_PCIEFD_PACKET_SEQ_MSK;
76726ad340eSHenning Colliander 
76826ad340eSHenning Colliander 	packet_size = cf->len;
76926ad340eSHenning Colliander 	memcpy(p->data, cf->data, packet_size);
77026ad340eSHenning Colliander 
77126ad340eSHenning Colliander 	return DIV_ROUND_UP(packet_size, 4);
77226ad340eSHenning Colliander }
77326ad340eSHenning Colliander 
77426ad340eSHenning Colliander static netdev_tx_t kvaser_pciefd_start_xmit(struct sk_buff *skb,
77526ad340eSHenning Colliander 					    struct net_device *netdev)
77626ad340eSHenning Colliander {
77726ad340eSHenning Colliander 	struct kvaser_pciefd_can *can = netdev_priv(netdev);
77826ad340eSHenning Colliander 	unsigned long irq_flags;
77926ad340eSHenning Colliander 	struct kvaser_pciefd_tx_packet packet;
78026ad340eSHenning Colliander 	int nwords;
78126ad340eSHenning Colliander 	u8 count;
78226ad340eSHenning Colliander 
783ae64438bSOliver Hartkopp 	if (can_dev_dropped_skb(netdev, skb))
78426ad340eSHenning Colliander 		return NETDEV_TX_OK;
78526ad340eSHenning Colliander 
78626ad340eSHenning Colliander 	nwords = kvaser_pciefd_prepare_tx_packet(&packet, can, skb);
78726ad340eSHenning Colliander 
78826ad340eSHenning Colliander 	spin_lock_irqsave(&can->echo_lock, irq_flags);
78926ad340eSHenning Colliander 
79026ad340eSHenning Colliander 	/* Prepare and save echo skb in internal slot */
7911dcb6e57SVincent Mailhol 	can_put_echo_skb(skb, netdev, can->echo_idx, 0);
79226ad340eSHenning Colliander 
79326ad340eSHenning Colliander 	/* Move echo index to the next slot */
79426ad340eSHenning Colliander 	can->echo_idx = (can->echo_idx + 1) % can->can.echo_skb_max;
79526ad340eSHenning Colliander 
79626ad340eSHenning Colliander 	/* Write header to fifo */
79726ad340eSHenning Colliander 	iowrite32(packet.header[0],
79826ad340eSHenning Colliander 		  can->reg_base + KVASER_PCIEFD_KCAN_FIFO_REG);
79926ad340eSHenning Colliander 	iowrite32(packet.header[1],
80026ad340eSHenning Colliander 		  can->reg_base + KVASER_PCIEFD_KCAN_FIFO_REG);
80126ad340eSHenning Colliander 
80226ad340eSHenning Colliander 	if (nwords) {
80326ad340eSHenning Colliander 		u32 data_last = ((u32 *)packet.data)[nwords - 1];
80426ad340eSHenning Colliander 
80526ad340eSHenning Colliander 		/* Write data to fifo, except last word */
80626ad340eSHenning Colliander 		iowrite32_rep(can->reg_base +
80726ad340eSHenning Colliander 			      KVASER_PCIEFD_KCAN_FIFO_REG, packet.data,
80826ad340eSHenning Colliander 			      nwords - 1);
80926ad340eSHenning Colliander 		/* Write last word to end of fifo */
81026ad340eSHenning Colliander 		__raw_writel(data_last, can->reg_base +
81126ad340eSHenning Colliander 			     KVASER_PCIEFD_KCAN_FIFO_LAST_REG);
81226ad340eSHenning Colliander 	} else {
81326ad340eSHenning Colliander 		/* Complete write to fifo */
81426ad340eSHenning Colliander 		__raw_writel(0, can->reg_base +
81526ad340eSHenning Colliander 			     KVASER_PCIEFD_KCAN_FIFO_LAST_REG);
81626ad340eSHenning Colliander 	}
81726ad340eSHenning Colliander 
81826ad340eSHenning Colliander 	count = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_TX_NPACKETS_REG);
81926ad340eSHenning Colliander 	/* No room for a new message, stop the queue until at least one
82026ad340eSHenning Colliander 	 * successful transmit
82126ad340eSHenning Colliander 	 */
82226ad340eSHenning Colliander 	if (count >= KVASER_PCIEFD_CAN_TX_MAX_COUNT ||
82326ad340eSHenning Colliander 	    can->can.echo_skb[can->echo_idx])
82426ad340eSHenning Colliander 		netif_stop_queue(netdev);
82526ad340eSHenning Colliander 
82626ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->echo_lock, irq_flags);
82726ad340eSHenning Colliander 
82826ad340eSHenning Colliander 	return NETDEV_TX_OK;
82926ad340eSHenning Colliander }
83026ad340eSHenning Colliander 
83126ad340eSHenning Colliander static int kvaser_pciefd_set_bittiming(struct kvaser_pciefd_can *can, bool data)
83226ad340eSHenning Colliander {
83326ad340eSHenning Colliander 	u32 mode, test, btrn;
83426ad340eSHenning Colliander 	unsigned long irq_flags;
83526ad340eSHenning Colliander 	int ret;
83626ad340eSHenning Colliander 	struct can_bittiming *bt;
83726ad340eSHenning Colliander 
83826ad340eSHenning Colliander 	if (data)
83926ad340eSHenning Colliander 		bt = &can->can.data_bittiming;
84026ad340eSHenning Colliander 	else
84126ad340eSHenning Colliander 		bt = &can->can.bittiming;
84226ad340eSHenning Colliander 
84326ad340eSHenning Colliander 	btrn = ((bt->phase_seg2 - 1) & 0x1f) <<
84426ad340eSHenning Colliander 	       KVASER_PCIEFD_KCAN_BTRN_TSEG2_SHIFT |
84526ad340eSHenning Colliander 	       (((bt->prop_seg + bt->phase_seg1) - 1) & 0x1ff) <<
84626ad340eSHenning Colliander 	       KVASER_PCIEFD_KCAN_BTRN_TSEG1_SHIFT |
84726ad340eSHenning Colliander 	       ((bt->sjw - 1) & 0xf) << KVASER_PCIEFD_KCAN_BTRN_SJW_SHIFT |
84826ad340eSHenning Colliander 	       ((bt->brp - 1) & 0x1fff);
84926ad340eSHenning Colliander 
85026ad340eSHenning Colliander 	spin_lock_irqsave(&can->lock, irq_flags);
85126ad340eSHenning Colliander 	mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
85226ad340eSHenning Colliander 
85326ad340eSHenning Colliander 	/* Put the circuit in reset mode */
85426ad340eSHenning Colliander 	iowrite32(mode | KVASER_PCIEFD_KCAN_MODE_RM,
85526ad340eSHenning Colliander 		  can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
85626ad340eSHenning Colliander 
85726ad340eSHenning Colliander 	/* Can only set bittiming if in reset mode */
85826ad340eSHenning Colliander 	ret = readl_poll_timeout(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG,
85926ad340eSHenning Colliander 				 test, test & KVASER_PCIEFD_KCAN_MODE_RM,
86026ad340eSHenning Colliander 				 0, 10);
86126ad340eSHenning Colliander 
86226ad340eSHenning Colliander 	if (ret) {
86326ad340eSHenning Colliander 		spin_unlock_irqrestore(&can->lock, irq_flags);
86426ad340eSHenning Colliander 		return -EBUSY;
86526ad340eSHenning Colliander 	}
86626ad340eSHenning Colliander 
86726ad340eSHenning Colliander 	if (data)
86826ad340eSHenning Colliander 		iowrite32(btrn, can->reg_base + KVASER_PCIEFD_KCAN_BTRD_REG);
86926ad340eSHenning Colliander 	else
87026ad340eSHenning Colliander 		iowrite32(btrn, can->reg_base + KVASER_PCIEFD_KCAN_BTRN_REG);
87126ad340eSHenning Colliander 
87226ad340eSHenning Colliander 	/* Restore previous reset mode status */
87326ad340eSHenning Colliander 	iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
87426ad340eSHenning Colliander 
87526ad340eSHenning Colliander 	spin_unlock_irqrestore(&can->lock, irq_flags);
87626ad340eSHenning Colliander 	return 0;
87726ad340eSHenning Colliander }
87826ad340eSHenning Colliander 
87926ad340eSHenning Colliander static int kvaser_pciefd_set_nominal_bittiming(struct net_device *ndev)
88026ad340eSHenning Colliander {
88126ad340eSHenning Colliander 	return kvaser_pciefd_set_bittiming(netdev_priv(ndev), false);
88226ad340eSHenning Colliander }
88326ad340eSHenning Colliander 
88426ad340eSHenning Colliander static int kvaser_pciefd_set_data_bittiming(struct net_device *ndev)
88526ad340eSHenning Colliander {
88626ad340eSHenning Colliander 	return kvaser_pciefd_set_bittiming(netdev_priv(ndev), true);
88726ad340eSHenning Colliander }
88826ad340eSHenning Colliander 
88926ad340eSHenning Colliander static int kvaser_pciefd_set_mode(struct net_device *ndev, enum can_mode mode)
89026ad340eSHenning Colliander {
89126ad340eSHenning Colliander 	struct kvaser_pciefd_can *can = netdev_priv(ndev);
89226ad340eSHenning Colliander 	int ret = 0;
89326ad340eSHenning Colliander 
89426ad340eSHenning Colliander 	switch (mode) {
89526ad340eSHenning Colliander 	case CAN_MODE_START:
89626ad340eSHenning Colliander 		if (!can->can.restart_ms)
89726ad340eSHenning Colliander 			ret = kvaser_pciefd_bus_on(can);
89826ad340eSHenning Colliander 		break;
89926ad340eSHenning Colliander 	default:
90026ad340eSHenning Colliander 		return -EOPNOTSUPP;
90126ad340eSHenning Colliander 	}
90226ad340eSHenning Colliander 
90326ad340eSHenning Colliander 	return ret;
90426ad340eSHenning Colliander }
90526ad340eSHenning Colliander 
90626ad340eSHenning Colliander static int kvaser_pciefd_get_berr_counter(const struct net_device *ndev,
90726ad340eSHenning Colliander 					  struct can_berr_counter *bec)
90826ad340eSHenning Colliander {
90926ad340eSHenning Colliander 	struct kvaser_pciefd_can *can = netdev_priv(ndev);
91026ad340eSHenning Colliander 
91126ad340eSHenning Colliander 	bec->rxerr = can->bec.rxerr;
91226ad340eSHenning Colliander 	bec->txerr = can->bec.txerr;
91326ad340eSHenning Colliander 	return 0;
91426ad340eSHenning Colliander }
91526ad340eSHenning Colliander 
91626ad340eSHenning Colliander static void kvaser_pciefd_bec_poll_timer(struct timer_list *data)
91726ad340eSHenning Colliander {
91826ad340eSHenning Colliander 	struct kvaser_pciefd_can *can = from_timer(can, data, bec_poll_timer);
91926ad340eSHenning Colliander 
92026ad340eSHenning Colliander 	kvaser_pciefd_enable_err_gen(can);
92126ad340eSHenning Colliander 	kvaser_pciefd_request_status(can);
92226ad340eSHenning Colliander 	can->err_rep_cnt = 0;
92326ad340eSHenning Colliander }
92426ad340eSHenning Colliander 
92526ad340eSHenning Colliander static const struct net_device_ops kvaser_pciefd_netdev_ops = {
92626ad340eSHenning Colliander 	.ndo_open = kvaser_pciefd_open,
92726ad340eSHenning Colliander 	.ndo_stop = kvaser_pciefd_stop,
928fa5cc7e1SVincent Mailhol 	.ndo_eth_ioctl = can_eth_ioctl_hwts,
92926ad340eSHenning Colliander 	.ndo_start_xmit = kvaser_pciefd_start_xmit,
93026ad340eSHenning Colliander 	.ndo_change_mtu = can_change_mtu,
93126ad340eSHenning Colliander };
93226ad340eSHenning Colliander 
933fa5cc7e1SVincent Mailhol static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {
934fa5cc7e1SVincent Mailhol 	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
935fa5cc7e1SVincent Mailhol };
936fa5cc7e1SVincent Mailhol 
93726ad340eSHenning Colliander static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
93826ad340eSHenning Colliander {
93926ad340eSHenning Colliander 	int i;
94026ad340eSHenning Colliander 
94126ad340eSHenning Colliander 	for (i = 0; i < pcie->nr_channels; i++) {
94226ad340eSHenning Colliander 		struct net_device *netdev;
94326ad340eSHenning Colliander 		struct kvaser_pciefd_can *can;
94426ad340eSHenning Colliander 		u32 status, tx_npackets;
94526ad340eSHenning Colliander 
94626ad340eSHenning Colliander 		netdev = alloc_candev(sizeof(struct kvaser_pciefd_can),
94726ad340eSHenning Colliander 				      KVASER_PCIEFD_CAN_TX_MAX_COUNT);
94826ad340eSHenning Colliander 		if (!netdev)
94926ad340eSHenning Colliander 			return -ENOMEM;
95026ad340eSHenning Colliander 
95126ad340eSHenning Colliander 		can = netdev_priv(netdev);
95226ad340eSHenning Colliander 		netdev->netdev_ops = &kvaser_pciefd_netdev_ops;
953fa5cc7e1SVincent Mailhol 		netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops;
95426ad340eSHenning Colliander 		can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE +
95526ad340eSHenning Colliander 				i * KVASER_PCIEFD_KCAN_BASE_OFFSET;
95626ad340eSHenning Colliander 
95726ad340eSHenning Colliander 		can->kv_pcie = pcie;
95826ad340eSHenning Colliander 		can->cmd_seq = 0;
95926ad340eSHenning Colliander 		can->err_rep_cnt = 0;
96026ad340eSHenning Colliander 		can->bec.txerr = 0;
96126ad340eSHenning Colliander 		can->bec.rxerr = 0;
96226ad340eSHenning Colliander 
96326ad340eSHenning Colliander 		init_completion(&can->start_comp);
96426ad340eSHenning Colliander 		init_completion(&can->flush_comp);
96526ad340eSHenning Colliander 		timer_setup(&can->bec_poll_timer, kvaser_pciefd_bec_poll_timer,
96626ad340eSHenning Colliander 			    0);
96726ad340eSHenning Colliander 
9687c6e6bceSJimmy Assarsson 		/* Disable Bus load reporting */
9697c6e6bceSJimmy Assarsson 		iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_BUS_LOAD_REG);
9707c6e6bceSJimmy Assarsson 
97126ad340eSHenning Colliander 		tx_npackets = ioread32(can->reg_base +
97226ad340eSHenning Colliander 				       KVASER_PCIEFD_KCAN_TX_NPACKETS_REG);
97326ad340eSHenning Colliander 		if (((tx_npackets >> KVASER_PCIEFD_KCAN_TX_NPACKETS_MAX_SHIFT) &
97426ad340eSHenning Colliander 		      0xff) < KVASER_PCIEFD_CAN_TX_MAX_COUNT) {
97526ad340eSHenning Colliander 			dev_err(&pcie->pci->dev,
97626ad340eSHenning Colliander 				"Max Tx count is smaller than expected\n");
97726ad340eSHenning Colliander 
97826ad340eSHenning Colliander 			free_candev(netdev);
97926ad340eSHenning Colliander 			return -ENODEV;
98026ad340eSHenning Colliander 		}
98126ad340eSHenning Colliander 
98226ad340eSHenning Colliander 		can->can.clock.freq = pcie->freq;
98326ad340eSHenning Colliander 		can->can.echo_skb_max = KVASER_PCIEFD_CAN_TX_MAX_COUNT;
98426ad340eSHenning Colliander 		can->echo_idx = 0;
98526ad340eSHenning Colliander 		spin_lock_init(&can->echo_lock);
98626ad340eSHenning Colliander 		spin_lock_init(&can->lock);
98726ad340eSHenning Colliander 		can->can.bittiming_const = &kvaser_pciefd_bittiming_const;
98826ad340eSHenning Colliander 		can->can.data_bittiming_const = &kvaser_pciefd_bittiming_const;
98926ad340eSHenning Colliander 
99026ad340eSHenning Colliander 		can->can.do_set_bittiming = kvaser_pciefd_set_nominal_bittiming;
99126ad340eSHenning Colliander 		can->can.do_set_data_bittiming =
99226ad340eSHenning Colliander 			kvaser_pciefd_set_data_bittiming;
99326ad340eSHenning Colliander 
99426ad340eSHenning Colliander 		can->can.do_set_mode = kvaser_pciefd_set_mode;
99526ad340eSHenning Colliander 		can->can.do_get_berr_counter = kvaser_pciefd_get_berr_counter;
99626ad340eSHenning Colliander 
99726ad340eSHenning Colliander 		can->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
99826ad340eSHenning Colliander 					      CAN_CTRLMODE_FD |
99926ad340eSHenning Colliander 					      CAN_CTRLMODE_FD_NON_ISO;
100026ad340eSHenning Colliander 
100126ad340eSHenning Colliander 		status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG);
100226ad340eSHenning Colliander 		if (!(status & KVASER_PCIEFD_KCAN_STAT_FD)) {
100326ad340eSHenning Colliander 			dev_err(&pcie->pci->dev,
100426ad340eSHenning Colliander 				"CAN FD not supported as expected %d\n", i);
100526ad340eSHenning Colliander 
100626ad340eSHenning Colliander 			free_candev(netdev);
100726ad340eSHenning Colliander 			return -ENODEV;
100826ad340eSHenning Colliander 		}
100926ad340eSHenning Colliander 
101026ad340eSHenning Colliander 		if (status & KVASER_PCIEFD_KCAN_STAT_CAP)
101126ad340eSHenning Colliander 			can->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;
101226ad340eSHenning Colliander 
101326ad340eSHenning Colliander 		netdev->flags |= IFF_ECHO;
101426ad340eSHenning Colliander 
101526ad340eSHenning Colliander 		SET_NETDEV_DEV(netdev, &pcie->pci->dev);
101626ad340eSHenning Colliander 
101726ad340eSHenning Colliander 		iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
1018*262d7a52SJimmy Assarsson 		iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
101926ad340eSHenning Colliander 			  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
102026ad340eSHenning Colliander 
102126ad340eSHenning Colliander 		pcie->can[i] = can;
102226ad340eSHenning Colliander 		kvaser_pciefd_pwm_start(can);
102326ad340eSHenning Colliander 	}
102426ad340eSHenning Colliander 
102526ad340eSHenning Colliander 	return 0;
102626ad340eSHenning Colliander }
102726ad340eSHenning Colliander 
102826ad340eSHenning Colliander static int kvaser_pciefd_reg_candev(struct kvaser_pciefd *pcie)
102926ad340eSHenning Colliander {
103026ad340eSHenning Colliander 	int i;
103126ad340eSHenning Colliander 
103226ad340eSHenning Colliander 	for (i = 0; i < pcie->nr_channels; i++) {
103326ad340eSHenning Colliander 		int err = register_candev(pcie->can[i]->can.dev);
103426ad340eSHenning Colliander 
103526ad340eSHenning Colliander 		if (err) {
103626ad340eSHenning Colliander 			int j;
103726ad340eSHenning Colliander 
103826ad340eSHenning Colliander 			/* Unregister all successfully registered devices. */
103926ad340eSHenning Colliander 			for (j = 0; j < i; j++)
104026ad340eSHenning Colliander 				unregister_candev(pcie->can[j]->can.dev);
104126ad340eSHenning Colliander 			return err;
104226ad340eSHenning Colliander 		}
104326ad340eSHenning Colliander 	}
104426ad340eSHenning Colliander 
104526ad340eSHenning Colliander 	return 0;
104626ad340eSHenning Colliander }
104726ad340eSHenning Colliander 
104826ad340eSHenning Colliander static void kvaser_pciefd_write_dma_map(struct kvaser_pciefd *pcie,
104926ad340eSHenning Colliander 					dma_addr_t addr, int offset)
105026ad340eSHenning Colliander {
105126ad340eSHenning Colliander 	u32 word1, word2;
105226ad340eSHenning Colliander 
105326ad340eSHenning Colliander #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
105426ad340eSHenning Colliander 	word1 = addr | KVASER_PCIEFD_64BIT_DMA_BIT;
105526ad340eSHenning Colliander 	word2 = addr >> 32;
105626ad340eSHenning Colliander #else
105726ad340eSHenning Colliander 	word1 = addr;
105826ad340eSHenning Colliander 	word2 = 0;
105926ad340eSHenning Colliander #endif
106026ad340eSHenning Colliander 	iowrite32(word1, pcie->reg_base + offset);
106126ad340eSHenning Colliander 	iowrite32(word2, pcie->reg_base + offset + 4);
106226ad340eSHenning Colliander }
106326ad340eSHenning Colliander 
106426ad340eSHenning Colliander static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)
106526ad340eSHenning Colliander {
106626ad340eSHenning Colliander 	int i;
106726ad340eSHenning Colliander 	u32 srb_status;
1068c589557dSJimmy Assarsson 	u32 srb_packet_count;
106926ad340eSHenning Colliander 	dma_addr_t dma_addr[KVASER_PCIEFD_DMA_COUNT];
107026ad340eSHenning Colliander 
107126ad340eSHenning Colliander 	/* Disable the DMA */
107226ad340eSHenning Colliander 	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG);
107326ad340eSHenning Colliander 	for (i = 0; i < KVASER_PCIEFD_DMA_COUNT; i++) {
107426ad340eSHenning Colliander 		unsigned int offset = KVASER_PCIEFD_DMA_MAP_BASE + 8 * i;
107526ad340eSHenning Colliander 
107626ad340eSHenning Colliander 		pcie->dma_data[i] =
107726ad340eSHenning Colliander 			dmam_alloc_coherent(&pcie->pci->dev,
107826ad340eSHenning Colliander 					    KVASER_PCIEFD_DMA_SIZE,
107926ad340eSHenning Colliander 					    &dma_addr[i],
108026ad340eSHenning Colliander 					    GFP_KERNEL);
108126ad340eSHenning Colliander 
108226ad340eSHenning Colliander 		if (!pcie->dma_data[i] || !dma_addr[i]) {
108326ad340eSHenning Colliander 			dev_err(&pcie->pci->dev, "Rx dma_alloc(%u) failure\n",
108426ad340eSHenning Colliander 				KVASER_PCIEFD_DMA_SIZE);
108526ad340eSHenning Colliander 			return -ENOMEM;
108626ad340eSHenning Colliander 		}
108726ad340eSHenning Colliander 
108826ad340eSHenning Colliander 		kvaser_pciefd_write_dma_map(pcie, dma_addr[i], offset);
108926ad340eSHenning Colliander 	}
109026ad340eSHenning Colliander 
109126ad340eSHenning Colliander 	/* Reset Rx FIFO, and both DMA buffers */
109226ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_SRB_CMD_FOR | KVASER_PCIEFD_SRB_CMD_RDB0 |
109326ad340eSHenning Colliander 		  KVASER_PCIEFD_SRB_CMD_RDB1,
109426ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
109526ad340eSHenning Colliander 
1096c589557dSJimmy Assarsson 	/* Empty Rx FIFO */
1097c589557dSJimmy Assarsson 	srb_packet_count = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG) &
1098c589557dSJimmy Assarsson 			   KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK;
1099c589557dSJimmy Assarsson 	while (srb_packet_count) {
1100c589557dSJimmy Assarsson 		/* Drop current packet in FIFO */
1101c589557dSJimmy Assarsson 		ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_FIFO_LAST_REG);
1102c589557dSJimmy Assarsson 		srb_packet_count--;
1103c589557dSJimmy Assarsson 	}
1104c589557dSJimmy Assarsson 
110526ad340eSHenning Colliander 	srb_status = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_STAT_REG);
110626ad340eSHenning Colliander 	if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DI)) {
110726ad340eSHenning Colliander 		dev_err(&pcie->pci->dev, "DMA not idle before enabling\n");
110826ad340eSHenning Colliander 		return -EIO;
110926ad340eSHenning Colliander 	}
111026ad340eSHenning Colliander 
111126ad340eSHenning Colliander 	/* Enable the DMA */
111226ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE,
111326ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG);
111426ad340eSHenning Colliander 
111526ad340eSHenning Colliander 	return 0;
111626ad340eSHenning Colliander }
111726ad340eSHenning Colliander 
111826ad340eSHenning Colliander static int kvaser_pciefd_setup_board(struct kvaser_pciefd *pcie)
111926ad340eSHenning Colliander {
112026ad340eSHenning Colliander 	u32 sysid, srb_status, build;
112126ad340eSHenning Colliander 	u8 sysid_nr_chan;
112226ad340eSHenning Colliander 	int ret;
112326ad340eSHenning Colliander 
112426ad340eSHenning Colliander 	ret = kvaser_pciefd_read_cfg(pcie);
112526ad340eSHenning Colliander 	if (ret)
112626ad340eSHenning Colliander 		return ret;
112726ad340eSHenning Colliander 
112826ad340eSHenning Colliander 	sysid = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_VERSION_REG);
112926ad340eSHenning Colliander 	sysid_nr_chan = (sysid >> KVASER_PCIEFD_SYSID_NRCHAN_SHIFT) & 0xff;
113026ad340eSHenning Colliander 	if (pcie->nr_channels != sysid_nr_chan) {
113126ad340eSHenning Colliander 		dev_err(&pcie->pci->dev,
113226ad340eSHenning Colliander 			"Number of channels does not match: %u vs %u\n",
113326ad340eSHenning Colliander 			pcie->nr_channels,
113426ad340eSHenning Colliander 			sysid_nr_chan);
113526ad340eSHenning Colliander 		return -ENODEV;
113626ad340eSHenning Colliander 	}
113726ad340eSHenning Colliander 
113826ad340eSHenning Colliander 	if (pcie->nr_channels > KVASER_PCIEFD_MAX_CAN_CHANNELS)
113926ad340eSHenning Colliander 		pcie->nr_channels = KVASER_PCIEFD_MAX_CAN_CHANNELS;
114026ad340eSHenning Colliander 
114126ad340eSHenning Colliander 	build = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_BUILD_REG);
114226ad340eSHenning Colliander 	dev_dbg(&pcie->pci->dev, "Version %u.%u.%u\n",
114326ad340eSHenning Colliander 		(sysid >> KVASER_PCIEFD_SYSID_MAJOR_VER_SHIFT) & 0xff,
114426ad340eSHenning Colliander 		sysid & 0xff,
114526ad340eSHenning Colliander 		(build >> KVASER_PCIEFD_SYSID_BUILD_VER_SHIFT) & 0x7fff);
114626ad340eSHenning Colliander 
114726ad340eSHenning Colliander 	srb_status = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_STAT_REG);
114826ad340eSHenning Colliander 	if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DMA)) {
114926ad340eSHenning Colliander 		dev_err(&pcie->pci->dev,
115026ad340eSHenning Colliander 			"Hardware without DMA is not supported\n");
115126ad340eSHenning Colliander 		return -ENODEV;
115226ad340eSHenning Colliander 	}
115326ad340eSHenning Colliander 
1154ec44dd57SChrister Beskow 	pcie->bus_freq = ioread32(pcie->reg_base +
1155ec44dd57SChrister Beskow 				  KVASER_PCIEFD_SYSID_BUSFREQ_REG);
115626ad340eSHenning Colliander 	pcie->freq = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_CANFREQ_REG);
115726ad340eSHenning Colliander 	pcie->freq_to_ticks_div = pcie->freq / 1000000;
115826ad340eSHenning Colliander 	if (pcie->freq_to_ticks_div == 0)
115926ad340eSHenning Colliander 		pcie->freq_to_ticks_div = 1;
116026ad340eSHenning Colliander 
116126ad340eSHenning Colliander 	/* Turn off all loopback functionality */
116226ad340eSHenning Colliander 	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_LOOP_REG);
116326ad340eSHenning Colliander 	return ret;
116426ad340eSHenning Colliander }
116526ad340eSHenning Colliander 
116626ad340eSHenning Colliander static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,
116726ad340eSHenning Colliander 					    struct kvaser_pciefd_rx_packet *p,
116826ad340eSHenning Colliander 					    __le32 *data)
116926ad340eSHenning Colliander {
117026ad340eSHenning Colliander 	struct sk_buff *skb;
117126ad340eSHenning Colliander 	struct canfd_frame *cf;
117226ad340eSHenning Colliander 	struct can_priv *priv;
117326ad340eSHenning Colliander 	struct net_device_stats *stats;
117426ad340eSHenning Colliander 	struct skb_shared_hwtstamps *shhwtstamps;
117526ad340eSHenning Colliander 	u8 ch_id = (p->header[1] >> KVASER_PCIEFD_PACKET_CHID_SHIFT) & 0x7;
117626ad340eSHenning Colliander 
117726ad340eSHenning Colliander 	if (ch_id >= pcie->nr_channels)
117826ad340eSHenning Colliander 		return -EIO;
117926ad340eSHenning Colliander 
118026ad340eSHenning Colliander 	priv = &pcie->can[ch_id]->can;
118126ad340eSHenning Colliander 	stats = &priv->dev->stats;
118226ad340eSHenning Colliander 
118326ad340eSHenning Colliander 	if (p->header[1] & KVASER_PCIEFD_RPACKET_FDF) {
118426ad340eSHenning Colliander 		skb = alloc_canfd_skb(priv->dev, &cf);
118526ad340eSHenning Colliander 		if (!skb) {
118626ad340eSHenning Colliander 			stats->rx_dropped++;
118726ad340eSHenning Colliander 			return -ENOMEM;
118826ad340eSHenning Colliander 		}
118926ad340eSHenning Colliander 
119026ad340eSHenning Colliander 		if (p->header[1] & KVASER_PCIEFD_RPACKET_BRS)
119126ad340eSHenning Colliander 			cf->flags |= CANFD_BRS;
119226ad340eSHenning Colliander 
119326ad340eSHenning Colliander 		if (p->header[1] & KVASER_PCIEFD_RPACKET_ESI)
119426ad340eSHenning Colliander 			cf->flags |= CANFD_ESI;
119526ad340eSHenning Colliander 	} else {
119626ad340eSHenning Colliander 		skb = alloc_can_skb(priv->dev, (struct can_frame **)&cf);
119726ad340eSHenning Colliander 		if (!skb) {
119826ad340eSHenning Colliander 			stats->rx_dropped++;
119926ad340eSHenning Colliander 			return -ENOMEM;
120026ad340eSHenning Colliander 		}
120126ad340eSHenning Colliander 	}
120226ad340eSHenning Colliander 
120326ad340eSHenning Colliander 	cf->can_id = p->header[0] & CAN_EFF_MASK;
120426ad340eSHenning Colliander 	if (p->header[0] & KVASER_PCIEFD_RPACKET_IDE)
120526ad340eSHenning Colliander 		cf->can_id |= CAN_EFF_FLAG;
120626ad340eSHenning Colliander 
12073ab4ce0dSOliver Hartkopp 	cf->len = can_fd_dlc2len(p->header[1] >> KVASER_PCIEFD_RPACKET_DLC_SHIFT);
120826ad340eSHenning Colliander 
12098e674ca7SVincent Mailhol 	if (p->header[0] & KVASER_PCIEFD_RPACKET_RTR) {
121026ad340eSHenning Colliander 		cf->can_id |= CAN_RTR_FLAG;
12118e674ca7SVincent Mailhol 	} else {
121226ad340eSHenning Colliander 		memcpy(cf->data, data, cf->len);
121326ad340eSHenning Colliander 
12148e674ca7SVincent Mailhol 		stats->rx_bytes += cf->len;
12158e674ca7SVincent Mailhol 	}
12168e674ca7SVincent Mailhol 	stats->rx_packets++;
12178e674ca7SVincent Mailhol 
121826ad340eSHenning Colliander 	shhwtstamps = skb_hwtstamps(skb);
121926ad340eSHenning Colliander 
122026ad340eSHenning Colliander 	shhwtstamps->hwtstamp =
122126ad340eSHenning Colliander 		ns_to_ktime(div_u64(p->timestamp * 1000,
122226ad340eSHenning Colliander 				    pcie->freq_to_ticks_div));
122326ad340eSHenning Colliander 
122426ad340eSHenning Colliander 	return netif_rx(skb);
122526ad340eSHenning Colliander }
122626ad340eSHenning Colliander 
122726ad340eSHenning Colliander static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
122826ad340eSHenning Colliander 				       struct can_frame *cf,
122926ad340eSHenning Colliander 				       enum can_state new_state,
123026ad340eSHenning Colliander 				       enum can_state tx_state,
123126ad340eSHenning Colliander 				       enum can_state rx_state)
123226ad340eSHenning Colliander {
123326ad340eSHenning Colliander 	can_change_state(can->can.dev, cf, tx_state, rx_state);
123426ad340eSHenning Colliander 
123526ad340eSHenning Colliander 	if (new_state == CAN_STATE_BUS_OFF) {
123626ad340eSHenning Colliander 		struct net_device *ndev = can->can.dev;
123726ad340eSHenning Colliander 		unsigned long irq_flags;
123826ad340eSHenning Colliander 
123926ad340eSHenning Colliander 		spin_lock_irqsave(&can->lock, irq_flags);
124026ad340eSHenning Colliander 		netif_stop_queue(can->can.dev);
124126ad340eSHenning Colliander 		spin_unlock_irqrestore(&can->lock, irq_flags);
124226ad340eSHenning Colliander 
124326ad340eSHenning Colliander 		/* Prevent CAN controller from auto recover from bus off */
124426ad340eSHenning Colliander 		if (!can->can.restart_ms) {
124526ad340eSHenning Colliander 			kvaser_pciefd_start_controller_flush(can);
124626ad340eSHenning Colliander 			can_bus_off(ndev);
124726ad340eSHenning Colliander 		}
124826ad340eSHenning Colliander 	}
124926ad340eSHenning Colliander }
125026ad340eSHenning Colliander 
125126ad340eSHenning Colliander static void kvaser_pciefd_packet_to_state(struct kvaser_pciefd_rx_packet *p,
125226ad340eSHenning Colliander 					  struct can_berr_counter *bec,
125326ad340eSHenning Colliander 					  enum can_state *new_state,
125426ad340eSHenning Colliander 					  enum can_state *tx_state,
125526ad340eSHenning Colliander 					  enum can_state *rx_state)
125626ad340eSHenning Colliander {
125726ad340eSHenning Colliander 	if (p->header[0] & KVASER_PCIEFD_SPACK_BOFF ||
125826ad340eSHenning Colliander 	    p->header[0] & KVASER_PCIEFD_SPACK_IRM)
125926ad340eSHenning Colliander 		*new_state = CAN_STATE_BUS_OFF;
126026ad340eSHenning Colliander 	else if (bec->txerr >= 255 ||  bec->rxerr >= 255)
126126ad340eSHenning Colliander 		*new_state = CAN_STATE_BUS_OFF;
126226ad340eSHenning Colliander 	else if (p->header[1] & KVASER_PCIEFD_SPACK_EPLR)
126326ad340eSHenning Colliander 		*new_state = CAN_STATE_ERROR_PASSIVE;
126426ad340eSHenning Colliander 	else if (bec->txerr >= 128 || bec->rxerr >= 128)
126526ad340eSHenning Colliander 		*new_state = CAN_STATE_ERROR_PASSIVE;
126626ad340eSHenning Colliander 	else if (p->header[1] & KVASER_PCIEFD_SPACK_EWLR)
126726ad340eSHenning Colliander 		*new_state = CAN_STATE_ERROR_WARNING;
126826ad340eSHenning Colliander 	else if (bec->txerr >= 96 || bec->rxerr >= 96)
126926ad340eSHenning Colliander 		*new_state = CAN_STATE_ERROR_WARNING;
127026ad340eSHenning Colliander 	else
127126ad340eSHenning Colliander 		*new_state = CAN_STATE_ERROR_ACTIVE;
127226ad340eSHenning Colliander 
127326ad340eSHenning Colliander 	*tx_state = bec->txerr >= bec->rxerr ? *new_state : 0;
127426ad340eSHenning Colliander 	*rx_state = bec->txerr <= bec->rxerr ? *new_state : 0;
127526ad340eSHenning Colliander }
127626ad340eSHenning Colliander 
127726ad340eSHenning Colliander static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
127826ad340eSHenning Colliander 					struct kvaser_pciefd_rx_packet *p)
127926ad340eSHenning Colliander {
128026ad340eSHenning Colliander 	struct can_berr_counter bec;
128126ad340eSHenning Colliander 	enum can_state old_state, new_state, tx_state, rx_state;
128226ad340eSHenning Colliander 	struct net_device *ndev = can->can.dev;
128326ad340eSHenning Colliander 	struct sk_buff *skb;
128426ad340eSHenning Colliander 	struct can_frame *cf = NULL;
128526ad340eSHenning Colliander 	struct skb_shared_hwtstamps *shhwtstamps;
128626ad340eSHenning Colliander 	struct net_device_stats *stats = &ndev->stats;
128726ad340eSHenning Colliander 
128826ad340eSHenning Colliander 	old_state = can->can.state;
128926ad340eSHenning Colliander 
129026ad340eSHenning Colliander 	bec.txerr = p->header[0] & 0xff;
129126ad340eSHenning Colliander 	bec.rxerr = (p->header[0] >> KVASER_PCIEFD_SPACK_RXERR_SHIFT) & 0xff;
129226ad340eSHenning Colliander 
129326ad340eSHenning Colliander 	kvaser_pciefd_packet_to_state(p, &bec, &new_state, &tx_state,
129426ad340eSHenning Colliander 				      &rx_state);
129526ad340eSHenning Colliander 
129626ad340eSHenning Colliander 	skb = alloc_can_err_skb(ndev, &cf);
129726ad340eSHenning Colliander 
129826ad340eSHenning Colliander 	if (new_state != old_state) {
129926ad340eSHenning Colliander 		kvaser_pciefd_change_state(can, cf, new_state, tx_state,
130026ad340eSHenning Colliander 					   rx_state);
130126ad340eSHenning Colliander 
130226ad340eSHenning Colliander 		if (old_state == CAN_STATE_BUS_OFF &&
130326ad340eSHenning Colliander 		    new_state == CAN_STATE_ERROR_ACTIVE &&
130426ad340eSHenning Colliander 		    can->can.restart_ms) {
130526ad340eSHenning Colliander 			can->can.can_stats.restarts++;
130626ad340eSHenning Colliander 			if (skb)
130726ad340eSHenning Colliander 				cf->can_id |= CAN_ERR_RESTARTED;
130826ad340eSHenning Colliander 		}
130926ad340eSHenning Colliander 	}
131026ad340eSHenning Colliander 
131126ad340eSHenning Colliander 	can->err_rep_cnt++;
131226ad340eSHenning Colliander 	can->can.can_stats.bus_error++;
131336aea60fSJimmy Assarsson 	if (p->header[1] & KVASER_PCIEFD_EPACK_DIR_TX)
131436aea60fSJimmy Assarsson 		stats->tx_errors++;
131536aea60fSJimmy Assarsson 	else
131626ad340eSHenning Colliander 		stats->rx_errors++;
131726ad340eSHenning Colliander 
131826ad340eSHenning Colliander 	can->bec.txerr = bec.txerr;
131926ad340eSHenning Colliander 	can->bec.rxerr = bec.rxerr;
132026ad340eSHenning Colliander 
132126ad340eSHenning Colliander 	if (!skb) {
132226ad340eSHenning Colliander 		stats->rx_dropped++;
132326ad340eSHenning Colliander 		return -ENOMEM;
132426ad340eSHenning Colliander 	}
132526ad340eSHenning Colliander 
132626ad340eSHenning Colliander 	shhwtstamps = skb_hwtstamps(skb);
132726ad340eSHenning Colliander 	shhwtstamps->hwtstamp =
132826ad340eSHenning Colliander 		ns_to_ktime(div_u64(p->timestamp * 1000,
132926ad340eSHenning Colliander 				    can->kv_pcie->freq_to_ticks_div));
13303e5c291cSVincent Mailhol 	cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
133126ad340eSHenning Colliander 
133226ad340eSHenning Colliander 	cf->data[6] = bec.txerr;
133326ad340eSHenning Colliander 	cf->data[7] = bec.rxerr;
133426ad340eSHenning Colliander 
133526ad340eSHenning Colliander 	netif_rx(skb);
133626ad340eSHenning Colliander 	return 0;
133726ad340eSHenning Colliander }
133826ad340eSHenning Colliander 
133926ad340eSHenning Colliander static int kvaser_pciefd_handle_error_packet(struct kvaser_pciefd *pcie,
134026ad340eSHenning Colliander 					     struct kvaser_pciefd_rx_packet *p)
134126ad340eSHenning Colliander {
134226ad340eSHenning Colliander 	struct kvaser_pciefd_can *can;
134326ad340eSHenning Colliander 	u8 ch_id = (p->header[1] >> KVASER_PCIEFD_PACKET_CHID_SHIFT) & 0x7;
134426ad340eSHenning Colliander 
134526ad340eSHenning Colliander 	if (ch_id >= pcie->nr_channels)
134626ad340eSHenning Colliander 		return -EIO;
134726ad340eSHenning Colliander 
134826ad340eSHenning Colliander 	can = pcie->can[ch_id];
134926ad340eSHenning Colliander 
135026ad340eSHenning Colliander 	kvaser_pciefd_rx_error_frame(can, p);
135126ad340eSHenning Colliander 	if (can->err_rep_cnt >= KVASER_PCIEFD_MAX_ERR_REP)
135226ad340eSHenning Colliander 		/* Do not report more errors, until bec_poll_timer expires */
135326ad340eSHenning Colliander 		kvaser_pciefd_disable_err_gen(can);
135426ad340eSHenning Colliander 	/* Start polling the error counters */
135526ad340eSHenning Colliander 	mod_timer(&can->bec_poll_timer, KVASER_PCIEFD_BEC_POLL_FREQ);
135626ad340eSHenning Colliander 	return 0;
135726ad340eSHenning Colliander }
135826ad340eSHenning Colliander 
135926ad340eSHenning Colliander static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
136026ad340eSHenning Colliander 					    struct kvaser_pciefd_rx_packet *p)
136126ad340eSHenning Colliander {
136226ad340eSHenning Colliander 	struct can_berr_counter bec;
136326ad340eSHenning Colliander 	enum can_state old_state, new_state, tx_state, rx_state;
136426ad340eSHenning Colliander 
136526ad340eSHenning Colliander 	old_state = can->can.state;
136626ad340eSHenning Colliander 
136726ad340eSHenning Colliander 	bec.txerr = p->header[0] & 0xff;
136826ad340eSHenning Colliander 	bec.rxerr = (p->header[0] >> KVASER_PCIEFD_SPACK_RXERR_SHIFT) & 0xff;
136926ad340eSHenning Colliander 
137026ad340eSHenning Colliander 	kvaser_pciefd_packet_to_state(p, &bec, &new_state, &tx_state,
137126ad340eSHenning Colliander 				      &rx_state);
137226ad340eSHenning Colliander 
137326ad340eSHenning Colliander 	if (new_state != old_state) {
137426ad340eSHenning Colliander 		struct net_device *ndev = can->can.dev;
137526ad340eSHenning Colliander 		struct sk_buff *skb;
137626ad340eSHenning Colliander 		struct can_frame *cf;
137726ad340eSHenning Colliander 		struct skb_shared_hwtstamps *shhwtstamps;
137826ad340eSHenning Colliander 
137926ad340eSHenning Colliander 		skb = alloc_can_err_skb(ndev, &cf);
138026ad340eSHenning Colliander 		if (!skb) {
138126ad340eSHenning Colliander 			struct net_device_stats *stats = &ndev->stats;
138226ad340eSHenning Colliander 
138326ad340eSHenning Colliander 			stats->rx_dropped++;
138426ad340eSHenning Colliander 			return -ENOMEM;
138526ad340eSHenning Colliander 		}
138626ad340eSHenning Colliander 
138726ad340eSHenning Colliander 		kvaser_pciefd_change_state(can, cf, new_state, tx_state,
138826ad340eSHenning Colliander 					   rx_state);
138926ad340eSHenning Colliander 
139026ad340eSHenning Colliander 		if (old_state == CAN_STATE_BUS_OFF &&
139126ad340eSHenning Colliander 		    new_state == CAN_STATE_ERROR_ACTIVE &&
139226ad340eSHenning Colliander 		    can->can.restart_ms) {
139326ad340eSHenning Colliander 			can->can.can_stats.restarts++;
139426ad340eSHenning Colliander 			cf->can_id |= CAN_ERR_RESTARTED;
139526ad340eSHenning Colliander 		}
139626ad340eSHenning Colliander 
139726ad340eSHenning Colliander 		shhwtstamps = skb_hwtstamps(skb);
139826ad340eSHenning Colliander 		shhwtstamps->hwtstamp =
139926ad340eSHenning Colliander 			ns_to_ktime(div_u64(p->timestamp * 1000,
140026ad340eSHenning Colliander 					    can->kv_pcie->freq_to_ticks_div));
140126ad340eSHenning Colliander 
140226ad340eSHenning Colliander 		cf->data[6] = bec.txerr;
140326ad340eSHenning Colliander 		cf->data[7] = bec.rxerr;
140426ad340eSHenning Colliander 
140526ad340eSHenning Colliander 		netif_rx(skb);
140626ad340eSHenning Colliander 	}
140726ad340eSHenning Colliander 	can->bec.txerr = bec.txerr;
140826ad340eSHenning Colliander 	can->bec.rxerr = bec.rxerr;
140926ad340eSHenning Colliander 	/* Check if we need to poll the error counters */
141026ad340eSHenning Colliander 	if (bec.txerr || bec.rxerr)
141126ad340eSHenning Colliander 		mod_timer(&can->bec_poll_timer, KVASER_PCIEFD_BEC_POLL_FREQ);
141226ad340eSHenning Colliander 
141326ad340eSHenning Colliander 	return 0;
141426ad340eSHenning Colliander }
141526ad340eSHenning Colliander 
141626ad340eSHenning Colliander static int kvaser_pciefd_handle_status_packet(struct kvaser_pciefd *pcie,
141726ad340eSHenning Colliander 					      struct kvaser_pciefd_rx_packet *p)
141826ad340eSHenning Colliander {
141926ad340eSHenning Colliander 	struct kvaser_pciefd_can *can;
142026ad340eSHenning Colliander 	u8 cmdseq;
142126ad340eSHenning Colliander 	u32 status;
142226ad340eSHenning Colliander 	u8 ch_id = (p->header[1] >> KVASER_PCIEFD_PACKET_CHID_SHIFT) & 0x7;
142326ad340eSHenning Colliander 
142426ad340eSHenning Colliander 	if (ch_id >= pcie->nr_channels)
142526ad340eSHenning Colliander 		return -EIO;
142626ad340eSHenning Colliander 
142726ad340eSHenning Colliander 	can = pcie->can[ch_id];
142826ad340eSHenning Colliander 
142926ad340eSHenning Colliander 	status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG);
143026ad340eSHenning Colliander 	cmdseq = (status >> KVASER_PCIEFD_KCAN_STAT_SEQNO_SHIFT) & 0xff;
143126ad340eSHenning Colliander 
143226ad340eSHenning Colliander 	/* Reset done, start abort and flush */
143326ad340eSHenning Colliander 	if (p->header[0] & KVASER_PCIEFD_SPACK_IRM &&
143426ad340eSHenning Colliander 	    p->header[0] & KVASER_PCIEFD_SPACK_RMCD &&
143526ad340eSHenning Colliander 	    p->header[1] & KVASER_PCIEFD_SPACK_AUTO &&
143626ad340eSHenning Colliander 	    cmdseq == (p->header[1] & KVASER_PCIEFD_PACKET_SEQ_MSK) &&
143726ad340eSHenning Colliander 	    status & KVASER_PCIEFD_KCAN_STAT_IDLE) {
143826ad340eSHenning Colliander 		u32 cmd;
143926ad340eSHenning Colliander 
144026ad340eSHenning Colliander 		iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
144126ad340eSHenning Colliander 			  can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
144226ad340eSHenning Colliander 		cmd = KVASER_PCIEFD_KCAN_CMD_AT;
144326ad340eSHenning Colliander 		cmd |= ++can->cmd_seq << KVASER_PCIEFD_KCAN_CMD_SEQ_SHIFT;
144426ad340eSHenning Colliander 		iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG);
144526ad340eSHenning Colliander 	} else if (p->header[0] & KVASER_PCIEFD_SPACK_IDET &&
144626ad340eSHenning Colliander 		   p->header[0] & KVASER_PCIEFD_SPACK_IRM &&
144726ad340eSHenning Colliander 		   cmdseq == (p->header[1] & KVASER_PCIEFD_PACKET_SEQ_MSK) &&
144826ad340eSHenning Colliander 		   status & KVASER_PCIEFD_KCAN_STAT_IDLE) {
144926ad340eSHenning Colliander 		/* Reset detected, send end of flush if no packet are in FIFO */
145026ad340eSHenning Colliander 		u8 count = ioread32(can->reg_base +
145126ad340eSHenning Colliander 				    KVASER_PCIEFD_KCAN_TX_NPACKETS_REG) & 0xff;
145226ad340eSHenning Colliander 
145326ad340eSHenning Colliander 		if (!count)
145426ad340eSHenning Colliander 			iowrite32(KVASER_PCIEFD_KCAN_CTRL_EFLUSH,
145526ad340eSHenning Colliander 				  can->reg_base + KVASER_PCIEFD_KCAN_CTRL_REG);
145626ad340eSHenning Colliander 	} else if (!(p->header[1] & KVASER_PCIEFD_SPACK_AUTO) &&
145726ad340eSHenning Colliander 		   cmdseq == (p->header[1] & KVASER_PCIEFD_PACKET_SEQ_MSK)) {
145826ad340eSHenning Colliander 		/* Response to status request received */
145926ad340eSHenning Colliander 		kvaser_pciefd_handle_status_resp(can, p);
146026ad340eSHenning Colliander 		if (can->can.state != CAN_STATE_BUS_OFF &&
146126ad340eSHenning Colliander 		    can->can.state != CAN_STATE_ERROR_ACTIVE) {
146226ad340eSHenning Colliander 			mod_timer(&can->bec_poll_timer,
146326ad340eSHenning Colliander 				  KVASER_PCIEFD_BEC_POLL_FREQ);
146426ad340eSHenning Colliander 		}
146526ad340eSHenning Colliander 	} else if (p->header[0] & KVASER_PCIEFD_SPACK_RMCD &&
146626ad340eSHenning Colliander 		   !(status & KVASER_PCIEFD_KCAN_STAT_BUS_OFF_MSK)) {
146726ad340eSHenning Colliander 		/* Reset to bus on detected */
146826ad340eSHenning Colliander 		if (!completion_done(&can->start_comp))
146926ad340eSHenning Colliander 			complete(&can->start_comp);
147026ad340eSHenning Colliander 	}
147126ad340eSHenning Colliander 
147226ad340eSHenning Colliander 	return 0;
147326ad340eSHenning Colliander }
147426ad340eSHenning Colliander 
147526ad340eSHenning Colliander static int kvaser_pciefd_handle_eack_packet(struct kvaser_pciefd *pcie,
147626ad340eSHenning Colliander 					    struct kvaser_pciefd_rx_packet *p)
147726ad340eSHenning Colliander {
147826ad340eSHenning Colliander 	struct kvaser_pciefd_can *can;
147926ad340eSHenning Colliander 	u8 ch_id = (p->header[1] >> KVASER_PCIEFD_PACKET_CHID_SHIFT) & 0x7;
148026ad340eSHenning Colliander 
148126ad340eSHenning Colliander 	if (ch_id >= pcie->nr_channels)
148226ad340eSHenning Colliander 		return -EIO;
148326ad340eSHenning Colliander 
148426ad340eSHenning Colliander 	can = pcie->can[ch_id];
148526ad340eSHenning Colliander 
148626ad340eSHenning Colliander 	/* If this is the last flushed packet, send end of flush */
148726ad340eSHenning Colliander 	if (p->header[0] & KVASER_PCIEFD_APACKET_FLU) {
148826ad340eSHenning Colliander 		u8 count = ioread32(can->reg_base +
148926ad340eSHenning Colliander 				    KVASER_PCIEFD_KCAN_TX_NPACKETS_REG) & 0xff;
149026ad340eSHenning Colliander 
149126ad340eSHenning Colliander 		if (count == 0)
149226ad340eSHenning Colliander 			iowrite32(KVASER_PCIEFD_KCAN_CTRL_EFLUSH,
149326ad340eSHenning Colliander 				  can->reg_base + KVASER_PCIEFD_KCAN_CTRL_REG);
149426ad340eSHenning Colliander 	} else {
149526ad340eSHenning Colliander 		int echo_idx = p->header[0] & KVASER_PCIEFD_PACKET_SEQ_MSK;
14969420e1d4SMarc Kleine-Budde 		int dlc = can_get_echo_skb(can->can.dev, echo_idx, NULL);
149726ad340eSHenning Colliander 		struct net_device_stats *stats = &can->can.dev->stats;
149826ad340eSHenning Colliander 
149926ad340eSHenning Colliander 		stats->tx_bytes += dlc;
150026ad340eSHenning Colliander 		stats->tx_packets++;
150126ad340eSHenning Colliander 
150226ad340eSHenning Colliander 		if (netif_queue_stopped(can->can.dev))
150326ad340eSHenning Colliander 			netif_wake_queue(can->can.dev);
150426ad340eSHenning Colliander 	}
150526ad340eSHenning Colliander 
150626ad340eSHenning Colliander 	return 0;
150726ad340eSHenning Colliander }
150826ad340eSHenning Colliander 
150926ad340eSHenning Colliander static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can,
151026ad340eSHenning Colliander 					     struct kvaser_pciefd_rx_packet *p)
151126ad340eSHenning Colliander {
151226ad340eSHenning Colliander 	struct sk_buff *skb;
151326ad340eSHenning Colliander 	struct net_device_stats *stats = &can->can.dev->stats;
151426ad340eSHenning Colliander 	struct can_frame *cf;
151526ad340eSHenning Colliander 
151626ad340eSHenning Colliander 	skb = alloc_can_err_skb(can->can.dev, &cf);
151726ad340eSHenning Colliander 
151826ad340eSHenning Colliander 	stats->tx_errors++;
151926ad340eSHenning Colliander 	if (p->header[0] & KVASER_PCIEFD_APACKET_ABL) {
152026ad340eSHenning Colliander 		if (skb)
152126ad340eSHenning Colliander 			cf->can_id |= CAN_ERR_LOSTARB;
152226ad340eSHenning Colliander 		can->can.can_stats.arbitration_lost++;
152326ad340eSHenning Colliander 	} else if (skb) {
152426ad340eSHenning Colliander 		cf->can_id |= CAN_ERR_ACK;
152526ad340eSHenning Colliander 	}
152626ad340eSHenning Colliander 
152726ad340eSHenning Colliander 	if (skb) {
152826ad340eSHenning Colliander 		cf->can_id |= CAN_ERR_BUSERROR;
152926ad340eSHenning Colliander 		netif_rx(skb);
153026ad340eSHenning Colliander 	} else {
153126ad340eSHenning Colliander 		stats->rx_dropped++;
153226ad340eSHenning Colliander 		netdev_warn(can->can.dev, "No memory left for err_skb\n");
153326ad340eSHenning Colliander 	}
153426ad340eSHenning Colliander }
153526ad340eSHenning Colliander 
153626ad340eSHenning Colliander static int kvaser_pciefd_handle_ack_packet(struct kvaser_pciefd *pcie,
153726ad340eSHenning Colliander 					   struct kvaser_pciefd_rx_packet *p)
153826ad340eSHenning Colliander {
153926ad340eSHenning Colliander 	struct kvaser_pciefd_can *can;
154026ad340eSHenning Colliander 	bool one_shot_fail = false;
154126ad340eSHenning Colliander 	u8 ch_id = (p->header[1] >> KVASER_PCIEFD_PACKET_CHID_SHIFT) & 0x7;
154226ad340eSHenning Colliander 
154326ad340eSHenning Colliander 	if (ch_id >= pcie->nr_channels)
154426ad340eSHenning Colliander 		return -EIO;
154526ad340eSHenning Colliander 
154626ad340eSHenning Colliander 	can = pcie->can[ch_id];
154726ad340eSHenning Colliander 	/* Ignore control packet ACK */
154826ad340eSHenning Colliander 	if (p->header[0] & KVASER_PCIEFD_APACKET_CT)
154926ad340eSHenning Colliander 		return 0;
155026ad340eSHenning Colliander 
155126ad340eSHenning Colliander 	if (p->header[0] & KVASER_PCIEFD_APACKET_NACK) {
155226ad340eSHenning Colliander 		kvaser_pciefd_handle_nack_packet(can, p);
155326ad340eSHenning Colliander 		one_shot_fail = true;
155426ad340eSHenning Colliander 	}
155526ad340eSHenning Colliander 
155626ad340eSHenning Colliander 	if (p->header[0] & KVASER_PCIEFD_APACKET_FLU) {
155726ad340eSHenning Colliander 		netdev_dbg(can->can.dev, "Packet was flushed\n");
155826ad340eSHenning Colliander 	} else {
155926ad340eSHenning Colliander 		int echo_idx = p->header[0] & KVASER_PCIEFD_PACKET_SEQ_MSK;
15609420e1d4SMarc Kleine-Budde 		int dlc = can_get_echo_skb(can->can.dev, echo_idx, NULL);
156126ad340eSHenning Colliander 		u8 count = ioread32(can->reg_base +
156226ad340eSHenning Colliander 				    KVASER_PCIEFD_KCAN_TX_NPACKETS_REG) & 0xff;
156326ad340eSHenning Colliander 
156426ad340eSHenning Colliander 		if (count < KVASER_PCIEFD_CAN_TX_MAX_COUNT &&
156526ad340eSHenning Colliander 		    netif_queue_stopped(can->can.dev))
156626ad340eSHenning Colliander 			netif_wake_queue(can->can.dev);
156726ad340eSHenning Colliander 
156826ad340eSHenning Colliander 		if (!one_shot_fail) {
156926ad340eSHenning Colliander 			struct net_device_stats *stats = &can->can.dev->stats;
157026ad340eSHenning Colliander 
157126ad340eSHenning Colliander 			stats->tx_bytes += dlc;
157226ad340eSHenning Colliander 			stats->tx_packets++;
157326ad340eSHenning Colliander 		}
157426ad340eSHenning Colliander 	}
157526ad340eSHenning Colliander 
157626ad340eSHenning Colliander 	return 0;
157726ad340eSHenning Colliander }
157826ad340eSHenning Colliander 
157926ad340eSHenning Colliander static int kvaser_pciefd_handle_eflush_packet(struct kvaser_pciefd *pcie,
158026ad340eSHenning Colliander 					      struct kvaser_pciefd_rx_packet *p)
158126ad340eSHenning Colliander {
158226ad340eSHenning Colliander 	struct kvaser_pciefd_can *can;
158326ad340eSHenning Colliander 	u8 ch_id = (p->header[1] >> KVASER_PCIEFD_PACKET_CHID_SHIFT) & 0x7;
158426ad340eSHenning Colliander 
158526ad340eSHenning Colliander 	if (ch_id >= pcie->nr_channels)
158626ad340eSHenning Colliander 		return -EIO;
158726ad340eSHenning Colliander 
158826ad340eSHenning Colliander 	can = pcie->can[ch_id];
158926ad340eSHenning Colliander 
159026ad340eSHenning Colliander 	if (!completion_done(&can->flush_comp))
159126ad340eSHenning Colliander 		complete(&can->flush_comp);
159226ad340eSHenning Colliander 
159326ad340eSHenning Colliander 	return 0;
159426ad340eSHenning Colliander }
159526ad340eSHenning Colliander 
159626ad340eSHenning Colliander static int kvaser_pciefd_read_packet(struct kvaser_pciefd *pcie, int *start_pos,
159726ad340eSHenning Colliander 				     int dma_buf)
159826ad340eSHenning Colliander {
159926ad340eSHenning Colliander 	__le32 *buffer = pcie->dma_data[dma_buf];
160026ad340eSHenning Colliander 	__le64 timestamp;
160126ad340eSHenning Colliander 	struct kvaser_pciefd_rx_packet packet;
160226ad340eSHenning Colliander 	struct kvaser_pciefd_rx_packet *p = &packet;
160326ad340eSHenning Colliander 	u8 type;
160426ad340eSHenning Colliander 	int pos = *start_pos;
160526ad340eSHenning Colliander 	int size;
160626ad340eSHenning Colliander 	int ret = 0;
160726ad340eSHenning Colliander 
160826ad340eSHenning Colliander 	size = le32_to_cpu(buffer[pos++]);
160926ad340eSHenning Colliander 	if (!size) {
161026ad340eSHenning Colliander 		*start_pos = 0;
161126ad340eSHenning Colliander 		return 0;
161226ad340eSHenning Colliander 	}
161326ad340eSHenning Colliander 
161426ad340eSHenning Colliander 	p->header[0] = le32_to_cpu(buffer[pos++]);
161526ad340eSHenning Colliander 	p->header[1] = le32_to_cpu(buffer[pos++]);
161626ad340eSHenning Colliander 
161726ad340eSHenning Colliander 	/* Read 64-bit timestamp */
161826ad340eSHenning Colliander 	memcpy(&timestamp, &buffer[pos], sizeof(__le64));
161926ad340eSHenning Colliander 	pos += 2;
162026ad340eSHenning Colliander 	p->timestamp = le64_to_cpu(timestamp);
162126ad340eSHenning Colliander 
162226ad340eSHenning Colliander 	type = (p->header[1] >> KVASER_PCIEFD_PACKET_TYPE_SHIFT) & 0xf;
162326ad340eSHenning Colliander 	switch (type) {
162426ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_DATA:
162526ad340eSHenning Colliander 		ret = kvaser_pciefd_handle_data_packet(pcie, p, &buffer[pos]);
162626ad340eSHenning Colliander 		if (!(p->header[0] & KVASER_PCIEFD_RPACKET_RTR)) {
162726ad340eSHenning Colliander 			u8 data_len;
162826ad340eSHenning Colliander 
16293ab4ce0dSOliver Hartkopp 			data_len = can_fd_dlc2len(p->header[1] >>
163026ad340eSHenning Colliander 					       KVASER_PCIEFD_RPACKET_DLC_SHIFT);
163126ad340eSHenning Colliander 			pos += DIV_ROUND_UP(data_len, 4);
163226ad340eSHenning Colliander 		}
163326ad340eSHenning Colliander 		break;
163426ad340eSHenning Colliander 
163526ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_ACK:
163626ad340eSHenning Colliander 		ret = kvaser_pciefd_handle_ack_packet(pcie, p);
163726ad340eSHenning Colliander 		break;
163826ad340eSHenning Colliander 
163926ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_STATUS:
164026ad340eSHenning Colliander 		ret = kvaser_pciefd_handle_status_packet(pcie, p);
164126ad340eSHenning Colliander 		break;
164226ad340eSHenning Colliander 
164326ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_ERROR:
164426ad340eSHenning Colliander 		ret = kvaser_pciefd_handle_error_packet(pcie, p);
164526ad340eSHenning Colliander 		break;
164626ad340eSHenning Colliander 
164726ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_EFRAME_ACK:
164826ad340eSHenning Colliander 		ret = kvaser_pciefd_handle_eack_packet(pcie, p);
164926ad340eSHenning Colliander 		break;
165026ad340eSHenning Colliander 
165126ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_EFLUSH_ACK:
165226ad340eSHenning Colliander 		ret = kvaser_pciefd_handle_eflush_packet(pcie, p);
165326ad340eSHenning Colliander 		break;
165426ad340eSHenning Colliander 
165526ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_ACK_DATA:
165626ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_BUS_LOAD:
165726ad340eSHenning Colliander 	case KVASER_PCIEFD_PACK_TYPE_TXRQ:
165826ad340eSHenning Colliander 		dev_info(&pcie->pci->dev,
165926ad340eSHenning Colliander 			 "Received unexpected packet type 0x%08X\n", type);
166026ad340eSHenning Colliander 		break;
166126ad340eSHenning Colliander 
166226ad340eSHenning Colliander 	default:
166326ad340eSHenning Colliander 		dev_err(&pcie->pci->dev, "Unknown packet type 0x%08X\n", type);
166426ad340eSHenning Colliander 		ret = -EIO;
166526ad340eSHenning Colliander 		break;
166626ad340eSHenning Colliander 	}
166726ad340eSHenning Colliander 
166826ad340eSHenning Colliander 	if (ret)
166926ad340eSHenning Colliander 		return ret;
167026ad340eSHenning Colliander 
167126ad340eSHenning Colliander 	/* Position does not point to the end of the package,
167226ad340eSHenning Colliander 	 * corrupted packet size?
167326ad340eSHenning Colliander 	 */
167426ad340eSHenning Colliander 	if ((*start_pos + size) != pos)
167526ad340eSHenning Colliander 		return -EIO;
167626ad340eSHenning Colliander 
167726ad340eSHenning Colliander 	/* Point to the next packet header, if any */
167826ad340eSHenning Colliander 	*start_pos = pos;
167926ad340eSHenning Colliander 
168026ad340eSHenning Colliander 	return ret;
168126ad340eSHenning Colliander }
168226ad340eSHenning Colliander 
168326ad340eSHenning Colliander static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf)
168426ad340eSHenning Colliander {
168526ad340eSHenning Colliander 	int pos = 0;
168626ad340eSHenning Colliander 	int res = 0;
168726ad340eSHenning Colliander 
168826ad340eSHenning Colliander 	do {
168926ad340eSHenning Colliander 		res = kvaser_pciefd_read_packet(pcie, &pos, dma_buf);
169026ad340eSHenning Colliander 	} while (!res && pos > 0 && pos < KVASER_PCIEFD_DMA_SIZE);
169126ad340eSHenning Colliander 
169226ad340eSHenning Colliander 	return res;
169326ad340eSHenning Colliander }
169426ad340eSHenning Colliander 
169526ad340eSHenning Colliander static int kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
169626ad340eSHenning Colliander {
169726ad340eSHenning Colliander 	u32 irq;
169826ad340eSHenning Colliander 
169926ad340eSHenning Colliander 	irq = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG);
170026ad340eSHenning Colliander 	if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) {
170126ad340eSHenning Colliander 		kvaser_pciefd_read_buffer(pcie, 0);
170226ad340eSHenning Colliander 		/* Reset DMA buffer 0 */
170326ad340eSHenning Colliander 		iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
170426ad340eSHenning Colliander 			  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
170526ad340eSHenning Colliander 	}
170626ad340eSHenning Colliander 
170726ad340eSHenning Colliander 	if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) {
170826ad340eSHenning Colliander 		kvaser_pciefd_read_buffer(pcie, 1);
170926ad340eSHenning Colliander 		/* Reset DMA buffer 1 */
171026ad340eSHenning Colliander 		iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
171126ad340eSHenning Colliander 			  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
171226ad340eSHenning Colliander 	}
171326ad340eSHenning Colliander 
171426ad340eSHenning Colliander 	if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 ||
171526ad340eSHenning Colliander 	    irq & KVASER_PCIEFD_SRB_IRQ_DOF1 ||
171626ad340eSHenning Colliander 	    irq & KVASER_PCIEFD_SRB_IRQ_DUF0 ||
171726ad340eSHenning Colliander 	    irq & KVASER_PCIEFD_SRB_IRQ_DUF1)
171826ad340eSHenning Colliander 		dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq);
171926ad340eSHenning Colliander 
172026ad340eSHenning Colliander 	iowrite32(irq, pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG);
172126ad340eSHenning Colliander 	return 0;
172226ad340eSHenning Colliander }
172326ad340eSHenning Colliander 
172426ad340eSHenning Colliander static int kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
172526ad340eSHenning Colliander {
172626ad340eSHenning Colliander 	u32 irq = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
172726ad340eSHenning Colliander 
172826ad340eSHenning Colliander 	if (irq & KVASER_PCIEFD_KCAN_IRQ_TOF)
172926ad340eSHenning Colliander 		netdev_err(can->can.dev, "Tx FIFO overflow\n");
173026ad340eSHenning Colliander 
173126ad340eSHenning Colliander 	if (irq & KVASER_PCIEFD_KCAN_IRQ_BPP)
173226ad340eSHenning Colliander 		netdev_err(can->can.dev,
173326ad340eSHenning Colliander 			   "Fail to change bittiming, when not in reset mode\n");
173426ad340eSHenning Colliander 
173526ad340eSHenning Colliander 	if (irq & KVASER_PCIEFD_KCAN_IRQ_FDIC)
173626ad340eSHenning Colliander 		netdev_err(can->can.dev, "CAN FD frame in CAN mode\n");
173726ad340eSHenning Colliander 
173826ad340eSHenning Colliander 	if (irq & KVASER_PCIEFD_KCAN_IRQ_ROF)
173926ad340eSHenning Colliander 		netdev_err(can->can.dev, "Rx FIFO overflow\n");
174026ad340eSHenning Colliander 
174126ad340eSHenning Colliander 	iowrite32(irq, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
174226ad340eSHenning Colliander 	return 0;
174326ad340eSHenning Colliander }
174426ad340eSHenning Colliander 
174526ad340eSHenning Colliander static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)
174626ad340eSHenning Colliander {
174726ad340eSHenning Colliander 	struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;
174826ad340eSHenning Colliander 	u32 board_irq;
174926ad340eSHenning Colliander 	int i;
175026ad340eSHenning Colliander 
175126ad340eSHenning Colliander 	board_irq = ioread32(pcie->reg_base + KVASER_PCIEFD_IRQ_REG);
175226ad340eSHenning Colliander 
175326ad340eSHenning Colliander 	if (!(board_irq & KVASER_PCIEFD_IRQ_ALL_MSK))
175426ad340eSHenning Colliander 		return IRQ_NONE;
175526ad340eSHenning Colliander 
175626ad340eSHenning Colliander 	if (board_irq & KVASER_PCIEFD_IRQ_SRB)
175726ad340eSHenning Colliander 		kvaser_pciefd_receive_irq(pcie);
175826ad340eSHenning Colliander 
175926ad340eSHenning Colliander 	for (i = 0; i < pcie->nr_channels; i++) {
176026ad340eSHenning Colliander 		if (!pcie->can[i]) {
176126ad340eSHenning Colliander 			dev_err(&pcie->pci->dev,
176226ad340eSHenning Colliander 				"IRQ mask points to unallocated controller\n");
176326ad340eSHenning Colliander 			break;
176426ad340eSHenning Colliander 		}
176526ad340eSHenning Colliander 
176626ad340eSHenning Colliander 		/* Check that mask matches channel (i) IRQ mask */
176726ad340eSHenning Colliander 		if (board_irq & (1 << i))
176826ad340eSHenning Colliander 			kvaser_pciefd_transmit_irq(pcie->can[i]);
176926ad340eSHenning Colliander 	}
177026ad340eSHenning Colliander 
177126ad340eSHenning Colliander 	iowrite32(board_irq, pcie->reg_base + KVASER_PCIEFD_IRQ_REG);
177226ad340eSHenning Colliander 	return IRQ_HANDLED;
177326ad340eSHenning Colliander }
177426ad340eSHenning Colliander 
177526ad340eSHenning Colliander static void kvaser_pciefd_teardown_can_ctrls(struct kvaser_pciefd *pcie)
177626ad340eSHenning Colliander {
177726ad340eSHenning Colliander 	int i;
177826ad340eSHenning Colliander 	struct kvaser_pciefd_can *can;
177926ad340eSHenning Colliander 
178026ad340eSHenning Colliander 	for (i = 0; i < pcie->nr_channels; i++) {
178126ad340eSHenning Colliander 		can = pcie->can[i];
178226ad340eSHenning Colliander 		if (can) {
178326ad340eSHenning Colliander 			iowrite32(0,
178426ad340eSHenning Colliander 				  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
178526ad340eSHenning Colliander 			kvaser_pciefd_pwm_stop(can);
178626ad340eSHenning Colliander 			free_candev(can->can.dev);
178726ad340eSHenning Colliander 		}
178826ad340eSHenning Colliander 	}
178926ad340eSHenning Colliander }
179026ad340eSHenning Colliander 
179126ad340eSHenning Colliander static int kvaser_pciefd_probe(struct pci_dev *pdev,
179226ad340eSHenning Colliander 			       const struct pci_device_id *id)
179326ad340eSHenning Colliander {
179426ad340eSHenning Colliander 	int err;
179526ad340eSHenning Colliander 	struct kvaser_pciefd *pcie;
179626ad340eSHenning Colliander 
179726ad340eSHenning Colliander 	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
179826ad340eSHenning Colliander 	if (!pcie)
179926ad340eSHenning Colliander 		return -ENOMEM;
180026ad340eSHenning Colliander 
180126ad340eSHenning Colliander 	pci_set_drvdata(pdev, pcie);
180226ad340eSHenning Colliander 	pcie->pci = pdev;
180326ad340eSHenning Colliander 
180426ad340eSHenning Colliander 	err = pci_enable_device(pdev);
180526ad340eSHenning Colliander 	if (err)
180626ad340eSHenning Colliander 		return err;
180726ad340eSHenning Colliander 
180826ad340eSHenning Colliander 	err = pci_request_regions(pdev, KVASER_PCIEFD_DRV_NAME);
180926ad340eSHenning Colliander 	if (err)
181026ad340eSHenning Colliander 		goto err_disable_pci;
181126ad340eSHenning Colliander 
181226ad340eSHenning Colliander 	pcie->reg_base = pci_iomap(pdev, 0, 0);
181326ad340eSHenning Colliander 	if (!pcie->reg_base) {
181426ad340eSHenning Colliander 		err = -ENOMEM;
181526ad340eSHenning Colliander 		goto err_release_regions;
181626ad340eSHenning Colliander 	}
181726ad340eSHenning Colliander 
181826ad340eSHenning Colliander 	err = kvaser_pciefd_setup_board(pcie);
181926ad340eSHenning Colliander 	if (err)
182026ad340eSHenning Colliander 		goto err_pci_iounmap;
182126ad340eSHenning Colliander 
182226ad340eSHenning Colliander 	err = kvaser_pciefd_setup_dma(pcie);
182326ad340eSHenning Colliander 	if (err)
182426ad340eSHenning Colliander 		goto err_pci_iounmap;
182526ad340eSHenning Colliander 
182626ad340eSHenning Colliander 	pci_set_master(pdev);
182726ad340eSHenning Colliander 
182826ad340eSHenning Colliander 	err = kvaser_pciefd_setup_can_ctrls(pcie);
182926ad340eSHenning Colliander 	if (err)
183026ad340eSHenning Colliander 		goto err_teardown_can_ctrls;
183126ad340eSHenning Colliander 
183284762d8dSJimmy Assarsson 	err = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler,
183384762d8dSJimmy Assarsson 			  IRQF_SHARED, KVASER_PCIEFD_DRV_NAME, pcie);
183484762d8dSJimmy Assarsson 	if (err)
183584762d8dSJimmy Assarsson 		goto err_teardown_can_ctrls;
183684762d8dSJimmy Assarsson 
183726ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1,
183826ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG);
183926ad340eSHenning Colliander 
184026ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1 |
184126ad340eSHenning Colliander 		  KVASER_PCIEFD_SRB_IRQ_DOF0 | KVASER_PCIEFD_SRB_IRQ_DOF1 |
184226ad340eSHenning Colliander 		  KVASER_PCIEFD_SRB_IRQ_DUF0 | KVASER_PCIEFD_SRB_IRQ_DUF1,
184326ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_SRB_IEN_REG);
184426ad340eSHenning Colliander 
184526ad340eSHenning Colliander 	/* Reset IRQ handling, expected to be off before */
184626ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_IRQ_ALL_MSK,
184726ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_IRQ_REG);
184826ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_IRQ_ALL_MSK,
184926ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_IEN_REG);
185026ad340eSHenning Colliander 
185126ad340eSHenning Colliander 	/* Ready the DMA buffers */
185226ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
185326ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
185426ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
185526ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
185626ad340eSHenning Colliander 
185726ad340eSHenning Colliander 	err = kvaser_pciefd_reg_candev(pcie);
185826ad340eSHenning Colliander 	if (err)
185926ad340eSHenning Colliander 		goto err_free_irq;
186026ad340eSHenning Colliander 
186126ad340eSHenning Colliander 	return 0;
186226ad340eSHenning Colliander 
186326ad340eSHenning Colliander err_free_irq:
186426ad340eSHenning Colliander 	free_irq(pcie->pci->irq, pcie);
186526ad340eSHenning Colliander 
186626ad340eSHenning Colliander err_teardown_can_ctrls:
186726ad340eSHenning Colliander 	kvaser_pciefd_teardown_can_ctrls(pcie);
186826ad340eSHenning Colliander 	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG);
186926ad340eSHenning Colliander 	pci_clear_master(pdev);
187026ad340eSHenning Colliander 
187126ad340eSHenning Colliander err_pci_iounmap:
187226ad340eSHenning Colliander 	pci_iounmap(pdev, pcie->reg_base);
187326ad340eSHenning Colliander 
187426ad340eSHenning Colliander err_release_regions:
187526ad340eSHenning Colliander 	pci_release_regions(pdev);
187626ad340eSHenning Colliander 
187726ad340eSHenning Colliander err_disable_pci:
187826ad340eSHenning Colliander 	pci_disable_device(pdev);
187926ad340eSHenning Colliander 
188026ad340eSHenning Colliander 	return err;
188126ad340eSHenning Colliander }
188226ad340eSHenning Colliander 
188326ad340eSHenning Colliander static void kvaser_pciefd_remove_all_ctrls(struct kvaser_pciefd *pcie)
188426ad340eSHenning Colliander {
188526ad340eSHenning Colliander 	struct kvaser_pciefd_can *can;
188626ad340eSHenning Colliander 	int i;
188726ad340eSHenning Colliander 
188826ad340eSHenning Colliander 	for (i = 0; i < pcie->nr_channels; i++) {
188926ad340eSHenning Colliander 		can = pcie->can[i];
189026ad340eSHenning Colliander 		if (can) {
189126ad340eSHenning Colliander 			iowrite32(0,
189226ad340eSHenning Colliander 				  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
189326ad340eSHenning Colliander 			unregister_candev(can->can.dev);
189426ad340eSHenning Colliander 			del_timer(&can->bec_poll_timer);
189526ad340eSHenning Colliander 			kvaser_pciefd_pwm_stop(can);
189626ad340eSHenning Colliander 			free_candev(can->can.dev);
189726ad340eSHenning Colliander 		}
189826ad340eSHenning Colliander 	}
189926ad340eSHenning Colliander }
190026ad340eSHenning Colliander 
190126ad340eSHenning Colliander static void kvaser_pciefd_remove(struct pci_dev *pdev)
190226ad340eSHenning Colliander {
190326ad340eSHenning Colliander 	struct kvaser_pciefd *pcie = pci_get_drvdata(pdev);
190426ad340eSHenning Colliander 
190526ad340eSHenning Colliander 	kvaser_pciefd_remove_all_ctrls(pcie);
190626ad340eSHenning Colliander 
190726ad340eSHenning Colliander 	/* Turn off IRQ generation */
190826ad340eSHenning Colliander 	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG);
190926ad340eSHenning Colliander 	iowrite32(KVASER_PCIEFD_IRQ_ALL_MSK,
191026ad340eSHenning Colliander 		  pcie->reg_base + KVASER_PCIEFD_IRQ_REG);
191126ad340eSHenning Colliander 	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_IEN_REG);
191226ad340eSHenning Colliander 
191326ad340eSHenning Colliander 	free_irq(pcie->pci->irq, pcie);
191426ad340eSHenning Colliander 
191526ad340eSHenning Colliander 	pci_iounmap(pdev, pcie->reg_base);
191626ad340eSHenning Colliander 	pci_release_regions(pdev);
191726ad340eSHenning Colliander 	pci_disable_device(pdev);
191826ad340eSHenning Colliander }
191926ad340eSHenning Colliander 
192026ad340eSHenning Colliander static struct pci_driver kvaser_pciefd = {
192126ad340eSHenning Colliander 	.name = KVASER_PCIEFD_DRV_NAME,
192226ad340eSHenning Colliander 	.id_table = kvaser_pciefd_id_table,
192326ad340eSHenning Colliander 	.probe = kvaser_pciefd_probe,
192426ad340eSHenning Colliander 	.remove = kvaser_pciefd_remove,
192526ad340eSHenning Colliander };
192626ad340eSHenning Colliander 
192726ad340eSHenning Colliander module_pci_driver(kvaser_pciefd)
1928