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 */ 726ad340eSHenning Colliander 8*954fb212SJimmy Assarsson #include <linux/bitfield.h> 91b83d0baSJimmy Assarsson #include <linux/can/dev.h> 101b83d0baSJimmy Assarsson #include <linux/device.h> 111b83d0baSJimmy Assarsson #include <linux/ethtool.h> 121b83d0baSJimmy Assarsson #include <linux/iopoll.h> 1326ad340eSHenning Colliander #include <linux/kernel.h> 14c496adafSJimmy Assarsson #include <linux/minmax.h> 1526ad340eSHenning Colliander #include <linux/module.h> 1626ad340eSHenning Colliander #include <linux/netdevice.h> 171b83d0baSJimmy Assarsson #include <linux/pci.h> 181b83d0baSJimmy Assarsson #include <linux/timer.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)) 282c470dbbSJimmy Assarsson #define KVASER_PCIEFD_MAX_ERR_REP 256U 292c470dbbSJimmy Assarsson #define KVASER_PCIEFD_CAN_TX_MAX_COUNT 17U 30*954fb212SJimmy Assarsson #define KVASER_PCIEFD_MAX_CAN_CHANNELS 4UL 312c470dbbSJimmy Assarsson #define KVASER_PCIEFD_DMA_COUNT 2U 3226ad340eSHenning Colliander 332c470dbbSJimmy Assarsson #define KVASER_PCIEFD_DMA_SIZE (4U * 1024U) 3426ad340eSHenning Colliander 3526ad340eSHenning Colliander #define KVASER_PCIEFD_VENDOR 0x1a07 36488c07b4SJimmy Assarsson #define KVASER_PCIEFD_4HS_DEVICE_ID 0x000d 37488c07b4SJimmy Assarsson #define KVASER_PCIEFD_2HS_V2_DEVICE_ID 0x000e 38488c07b4SJimmy Assarsson #define KVASER_PCIEFD_HS_V2_DEVICE_ID 0x000f 39488c07b4SJimmy Assarsson #define KVASER_PCIEFD_MINIPCIE_HS_V2_DEVICE_ID 0x0010 40488c07b4SJimmy Assarsson #define KVASER_PCIEFD_MINIPCIE_2HS_V2_DEVICE_ID 0x0011 4126ad340eSHenning Colliander 4226ad340eSHenning Colliander /* PCIe IRQ registers */ 4326ad340eSHenning Colliander #define KVASER_PCIEFD_IRQ_REG 0x40 4426ad340eSHenning Colliander #define KVASER_PCIEFD_IEN_REG 0x50 4569335013SJimmy Assarsson /* DMA address translation map register base */ 4626ad340eSHenning Colliander #define KVASER_PCIEFD_DMA_MAP_BASE 0x1000 4726ad340eSHenning Colliander /* Loopback control register */ 4826ad340eSHenning Colliander #define KVASER_PCIEFD_LOOP_REG 0x1f000 4926ad340eSHenning Colliander /* System identification and information registers */ 5026ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_BASE 0x1f020 5126ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_VERSION_REG (KVASER_PCIEFD_SYSID_BASE + 0x8) 5226ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_CANFREQ_REG (KVASER_PCIEFD_SYSID_BASE + 0xc) 53ec44dd57SChrister Beskow #define KVASER_PCIEFD_SYSID_BUSFREQ_REG (KVASER_PCIEFD_SYSID_BASE + 0x10) 5426ad340eSHenning Colliander #define KVASER_PCIEFD_SYSID_BUILD_REG (KVASER_PCIEFD_SYSID_BASE + 0x14) 5526ad340eSHenning Colliander /* Shared receive buffer registers */ 5626ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_BASE 0x1f200 57c589557dSJimmy Assarsson #define KVASER_PCIEFD_SRB_FIFO_LAST_REG (KVASER_PCIEFD_SRB_BASE + 0x1f4) 5826ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CMD_REG (KVASER_PCIEFD_SRB_BASE + 0x200) 5926ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IEN_REG (KVASER_PCIEFD_SRB_BASE + 0x204) 6026ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_REG (KVASER_PCIEFD_SRB_BASE + 0x20c) 6126ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_STAT_REG (KVASER_PCIEFD_SRB_BASE + 0x210) 62c589557dSJimmy Assarsson #define KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG (KVASER_PCIEFD_SRB_BASE + 0x214) 6326ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CTRL_REG (KVASER_PCIEFD_SRB_BASE + 0x218) 6469335013SJimmy Assarsson /* Kvaser KCAN CAN controller registers */ 6569335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN0_BASE 0x10000 6669335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_BASE_OFFSET 0x1000 6769335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_FIFO_REG 0x100 6869335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_FIFO_LAST_REG 0x180 6969335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_CTRL_REG 0x2c0 7069335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_CMD_REG 0x400 7169335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IEN_REG 0x408 7269335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_REG 0x410 7369335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_TX_NPACKETS_REG 0x414 7469335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_STAT_REG 0x418 7569335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_MODE_REG 0x41c 7669335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_BTRN_REG 0x420 7769335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_BUS_LOAD_REG 0x424 7869335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_BTRD_REG 0x428 7969335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_PWM_REG 0x430 8026ad340eSHenning Colliander 8169335013SJimmy Assarsson /* PCI interrupt fields */ 8226ad340eSHenning Colliander #define KVASER_PCIEFD_IRQ_SRB BIT(4) 83*954fb212SJimmy Assarsson #define KVASER_PCIEFD_IRQ_ALL_MASK GENMASK(4, 0) 8426ad340eSHenning Colliander 8569335013SJimmy Assarsson /* Enable 64-bit DMA address translation */ 8669335013SJimmy Assarsson #define KVASER_PCIEFD_64BIT_DMA_BIT BIT(0) 8769335013SJimmy Assarsson 8869335013SJimmy Assarsson /* System build information fields */ 89*954fb212SJimmy Assarsson #define KVASER_PCIEFD_SYSID_VERSION_NR_CHAN_MASK GENMASK(31, 24) 90*954fb212SJimmy Assarsson #define KVASER_PCIEFD_SYSID_VERSION_MAJOR_MASK GENMASK(23, 16) 91*954fb212SJimmy Assarsson #define KVASER_PCIEFD_SYSID_VERSION_MINOR_MASK GENMASK(7, 0) 92*954fb212SJimmy Assarsson #define KVASER_PCIEFD_SYSID_BUILD_SEQ_MASK GENMASK(15, 1) 9326ad340eSHenning Colliander 9426ad340eSHenning Colliander /* Reset DMA buffer 0, 1 and FIFO offset */ 9526ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CMD_RDB1 BIT(5) 9669335013SJimmy Assarsson #define KVASER_PCIEFD_SRB_CMD_RDB0 BIT(4) 9726ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CMD_FOR BIT(0) 9826ad340eSHenning Colliander 9926ad340eSHenning Colliander /* DMA underflow, buffer 0 and 1 */ 10026ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_IRQ_DUF1 BIT(13) 10169335013SJimmy Assarsson #define KVASER_PCIEFD_SRB_IRQ_DUF0 BIT(12) 10269335013SJimmy Assarsson /* DMA overflow, buffer 0 and 1 */ 10369335013SJimmy Assarsson #define KVASER_PCIEFD_SRB_IRQ_DOF1 BIT(11) 10469335013SJimmy Assarsson #define KVASER_PCIEFD_SRB_IRQ_DOF0 BIT(10) 10569335013SJimmy Assarsson /* DMA packet done, buffer 0 and 1 */ 10669335013SJimmy Assarsson #define KVASER_PCIEFD_SRB_IRQ_DPD1 BIT(9) 10769335013SJimmy Assarsson #define KVASER_PCIEFD_SRB_IRQ_DPD0 BIT(8) 10826ad340eSHenning Colliander 10969335013SJimmy Assarsson /* Got DMA support */ 11069335013SJimmy Assarsson #define KVASER_PCIEFD_SRB_STAT_DMA BIT(24) 11126ad340eSHenning Colliander /* DMA idle */ 11226ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_STAT_DI BIT(15) 11326ad340eSHenning Colliander 114c589557dSJimmy Assarsson /* SRB current packet level */ 115*954fb212SJimmy Assarsson #define KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK GENMASK(7, 0) 116c589557dSJimmy Assarsson 11726ad340eSHenning Colliander /* DMA Enable */ 11826ad340eSHenning Colliander #define KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE BIT(0) 11926ad340eSHenning Colliander 12069335013SJimmy Assarsson /* KCAN CTRL packet types */ 121*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_CTRL_TYPE_MASK GENMASK(31, 29) 122*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_CTRL_TYPE_EFLUSH 0x4 123*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_CTRL_TYPE_EFRAME 0x5 12426ad340eSHenning Colliander 12569335013SJimmy Assarsson /* Command sequence number */ 126*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_CMD_SEQ_MASK GENMASK(23, 16) 12726ad340eSHenning Colliander /* Abort, flush and reset */ 12826ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_CMD_AT BIT(1) 12969335013SJimmy Assarsson /* Request status packet */ 13069335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_CMD_SRQ BIT(0) 13126ad340eSHenning Colliander 13226ad340eSHenning Colliander /* Transmitter unaligned */ 13326ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_IRQ_TAL BIT(17) 13469335013SJimmy Assarsson /* Tx FIFO empty */ 13569335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_TE BIT(16) 13669335013SJimmy Assarsson /* Tx FIFO overflow */ 13769335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_TOF BIT(15) 13869335013SJimmy Assarsson /* Tx buffer flush done */ 13969335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_TFD BIT(14) 14069335013SJimmy Assarsson /* Abort done */ 14169335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_ABD BIT(13) 14269335013SJimmy Assarsson /* Rx FIFO overflow */ 14369335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_ROF BIT(5) 14469335013SJimmy Assarsson /* FDF bit when controller is in classic CAN mode */ 14569335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_FDIC BIT(3) 14669335013SJimmy Assarsson /* Bus parameter protection error */ 14769335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_BPP BIT(2) 14869335013SJimmy Assarsson /* Tx FIFO unaligned end */ 14969335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_TAE BIT(1) 15069335013SJimmy Assarsson /* Tx FIFO unaligned read */ 15169335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_IRQ_TAR BIT(0) 15226ad340eSHenning Colliander 15369335013SJimmy Assarsson /* Tx FIFO size */ 154*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_TX_NR_PACKETS_MAX_MASK GENMASK(23, 16) 155*954fb212SJimmy Assarsson /* Tx FIFO current packet level */ 156*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_TX_NR_PACKETS_CURRENT_MASK GENMASK(7, 0) 15726ad340eSHenning Colliander 15869335013SJimmy Assarsson /* Current status packet sequence number */ 159*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_STAT_SEQNO_MASK GENMASK(31, 24) 16026ad340eSHenning Colliander /* Controller got CAN FD capability */ 16126ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_FD BIT(19) 16269335013SJimmy Assarsson /* Controller got one-shot capability */ 16369335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_STAT_CAP BIT(16) 16469335013SJimmy Assarsson /* Controller in reset mode */ 16569335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_STAT_IRM BIT(15) 16669335013SJimmy Assarsson /* Reset mode request */ 16769335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_STAT_RMR BIT(14) 16869335013SJimmy Assarsson /* Bus off */ 16969335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_STAT_BOFF BIT(11) 17069335013SJimmy Assarsson /* Idle state. Controller in reset mode and no abort or flush pending */ 17169335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_STAT_IDLE BIT(10) 17269335013SJimmy Assarsson /* Abort request */ 17369335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_STAT_AR BIT(7) 17469335013SJimmy Assarsson /* Controller is bus off */ 17526ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_STAT_BUS_OFF_MSK (KVASER_PCIEFD_KCAN_STAT_AR | \ 17626ad340eSHenning Colliander KVASER_PCIEFD_KCAN_STAT_BOFF | KVASER_PCIEFD_KCAN_STAT_RMR | \ 17726ad340eSHenning Colliander KVASER_PCIEFD_KCAN_STAT_IRM) 17826ad340eSHenning Colliander 17926ad340eSHenning Colliander /* Classic CAN mode */ 18026ad340eSHenning Colliander #define KVASER_PCIEFD_KCAN_MODE_CCM BIT(31) 18169335013SJimmy Assarsson /* Active error flag enable. Clear to force error passive */ 18269335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_MODE_EEN BIT(23) 18369335013SJimmy Assarsson /* Acknowledgment packet type */ 18469335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_MODE_APT BIT(20) 18569335013SJimmy Assarsson /* CAN FD non-ISO */ 18669335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_MODE_NIFDEN BIT(15) 18769335013SJimmy Assarsson /* Error packet enable */ 18869335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_MODE_EPEN BIT(12) 18969335013SJimmy Assarsson /* Listen only mode */ 19069335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_MODE_LOM BIT(9) 19169335013SJimmy Assarsson /* Reset mode */ 19269335013SJimmy Assarsson #define KVASER_PCIEFD_KCAN_MODE_RM BIT(8) 19326ad340eSHenning Colliander 19469335013SJimmy Assarsson /* BTRN and BTRD fields */ 195*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_BTRN_TSEG2_MASK GENMASK(30, 26) 196*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_BTRN_TSEG1_MASK GENMASK(25, 17) 197*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_BTRN_SJW_MASK GENMASK(16, 13) 198*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_BTRN_BRP_MASK GENMASK(12, 0) 19926ad340eSHenning Colliander 20069335013SJimmy Assarsson /* PWM Control fields */ 201*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_PWM_TOP_MASK GENMASK(23, 16) 202*954fb212SJimmy Assarsson #define KVASER_PCIEFD_KCAN_PWM_TRIGGER_MASK GENMASK(7, 0) 20326ad340eSHenning Colliander 20469335013SJimmy Assarsson /* KCAN packet type IDs */ 20526ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_DATA 0 20626ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_ACK 1 20726ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_TXRQ 2 20826ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_ERROR 3 20926ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_EFLUSH_ACK 4 21026ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_EFRAME_ACK 5 21126ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_ACK_DATA 6 21226ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_STATUS 8 21326ad340eSHenning Colliander #define KVASER_PCIEFD_PACK_TYPE_BUS_LOAD 9 21426ad340eSHenning Colliander 21569335013SJimmy Assarsson /* Common KCAN packet definitions, second word */ 216*954fb212SJimmy Assarsson #define KVASER_PCIEFD_PACKET_TYPE_MASK GENMASK(31, 28) 217*954fb212SJimmy Assarsson #define KVASER_PCIEFD_PACKET_CHID_MASK GENMASK(27, 25) 218*954fb212SJimmy Assarsson #define KVASER_PCIEFD_PACKET_SEQ_MASK GENMASK(7, 0) 21926ad340eSHenning Colliander 22069335013SJimmy Assarsson /* KCAN Transmit/Receive data packet, first word */ 22126ad340eSHenning Colliander #define KVASER_PCIEFD_RPACKET_IDE BIT(30) 22226ad340eSHenning Colliander #define KVASER_PCIEFD_RPACKET_RTR BIT(29) 223*954fb212SJimmy Assarsson #define KVASER_PCIEFD_RPACKET_ID_MASK GENMASK(28, 0) 22469335013SJimmy Assarsson /* KCAN Transmit data packet, second word */ 22526ad340eSHenning Colliander #define KVASER_PCIEFD_TPACKET_AREQ BIT(31) 22669335013SJimmy Assarsson #define KVASER_PCIEFD_TPACKET_SMS BIT(16) 22769335013SJimmy Assarsson /* KCAN Transmit/Receive data packet, second word */ 22869335013SJimmy Assarsson #define KVASER_PCIEFD_RPACKET_FDF BIT(15) 22969335013SJimmy Assarsson #define KVASER_PCIEFD_RPACKET_BRS BIT(14) 23069335013SJimmy Assarsson #define KVASER_PCIEFD_RPACKET_ESI BIT(13) 231*954fb212SJimmy Assarsson #define KVASER_PCIEFD_RPACKET_DLC_MASK GENMASK(11, 8) 23226ad340eSHenning Colliander 23369335013SJimmy Assarsson /* KCAN Transmit acknowledge packet, first word */ 23426ad340eSHenning Colliander #define KVASER_PCIEFD_APACKET_NACK BIT(11) 23569335013SJimmy Assarsson #define KVASER_PCIEFD_APACKET_ABL BIT(10) 23669335013SJimmy Assarsson #define KVASER_PCIEFD_APACKET_CT BIT(9) 23769335013SJimmy Assarsson #define KVASER_PCIEFD_APACKET_FLU BIT(8) 23826ad340eSHenning Colliander 23969335013SJimmy Assarsson /* KCAN Status packet, first word */ 24026ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_RMCD BIT(22) 24169335013SJimmy Assarsson #define KVASER_PCIEFD_SPACK_IRM BIT(21) 24269335013SJimmy Assarsson #define KVASER_PCIEFD_SPACK_IDET BIT(20) 24369335013SJimmy Assarsson #define KVASER_PCIEFD_SPACK_BOFF BIT(16) 244*954fb212SJimmy Assarsson #define KVASER_PCIEFD_SPACK_RXERR_MASK GENMASK(15, 8) 245*954fb212SJimmy Assarsson #define KVASER_PCIEFD_SPACK_TXERR_MASK GENMASK(7, 0) 24669335013SJimmy Assarsson /* KCAN Status packet, second word */ 24726ad340eSHenning Colliander #define KVASER_PCIEFD_SPACK_EPLR BIT(24) 24869335013SJimmy Assarsson #define KVASER_PCIEFD_SPACK_EWLR BIT(23) 24969335013SJimmy Assarsson #define KVASER_PCIEFD_SPACK_AUTO BIT(21) 25026ad340eSHenning Colliander 25169335013SJimmy Assarsson /* KCAN Error detected packet, second word */ 25236aea60fSJimmy Assarsson #define KVASER_PCIEFD_EPACK_DIR_TX BIT(0) 25336aea60fSJimmy Assarsson 25426ad340eSHenning Colliander struct kvaser_pciefd; 25526ad340eSHenning Colliander 25626ad340eSHenning Colliander struct kvaser_pciefd_can { 25726ad340eSHenning Colliander struct can_priv can; 25826ad340eSHenning Colliander struct kvaser_pciefd *kv_pcie; 25926ad340eSHenning Colliander void __iomem *reg_base; 26026ad340eSHenning Colliander struct can_berr_counter bec; 26126ad340eSHenning Colliander u8 cmd_seq; 26226ad340eSHenning Colliander int err_rep_cnt; 26326ad340eSHenning Colliander int echo_idx; 26426ad340eSHenning Colliander spinlock_t lock; /* Locks sensitive registers (e.g. MODE) */ 26526ad340eSHenning Colliander spinlock_t echo_lock; /* Locks the message echo buffer */ 26626ad340eSHenning Colliander struct timer_list bec_poll_timer; 26726ad340eSHenning Colliander struct completion start_comp, flush_comp; 26826ad340eSHenning Colliander }; 26926ad340eSHenning Colliander 27026ad340eSHenning Colliander struct kvaser_pciefd { 27126ad340eSHenning Colliander struct pci_dev *pci; 27226ad340eSHenning Colliander void __iomem *reg_base; 27326ad340eSHenning Colliander struct kvaser_pciefd_can *can[KVASER_PCIEFD_MAX_CAN_CHANNELS]; 27426ad340eSHenning Colliander void *dma_data[KVASER_PCIEFD_DMA_COUNT]; 27526ad340eSHenning Colliander u8 nr_channels; 276ec44dd57SChrister Beskow u32 bus_freq; 27726ad340eSHenning Colliander u32 freq; 27826ad340eSHenning Colliander u32 freq_to_ticks_div; 27926ad340eSHenning Colliander }; 28026ad340eSHenning Colliander 28126ad340eSHenning Colliander struct kvaser_pciefd_rx_packet { 28226ad340eSHenning Colliander u32 header[2]; 28326ad340eSHenning Colliander u64 timestamp; 28426ad340eSHenning Colliander }; 28526ad340eSHenning Colliander 28626ad340eSHenning Colliander struct kvaser_pciefd_tx_packet { 28726ad340eSHenning Colliander u32 header[2]; 28826ad340eSHenning Colliander u8 data[64]; 28926ad340eSHenning Colliander }; 29026ad340eSHenning Colliander 29126ad340eSHenning Colliander static const struct can_bittiming_const kvaser_pciefd_bittiming_const = { 29226ad340eSHenning Colliander .name = KVASER_PCIEFD_DRV_NAME, 29326ad340eSHenning Colliander .tseg1_min = 1, 294470e14c0SJimmy Assarsson .tseg1_max = 512, 29526ad340eSHenning Colliander .tseg2_min = 1, 29626ad340eSHenning Colliander .tseg2_max = 32, 29726ad340eSHenning Colliander .sjw_max = 16, 29826ad340eSHenning Colliander .brp_min = 1, 299470e14c0SJimmy Assarsson .brp_max = 8192, 30026ad340eSHenning Colliander .brp_inc = 1, 30126ad340eSHenning Colliander }; 30226ad340eSHenning Colliander 30326ad340eSHenning Colliander static struct pci_device_id kvaser_pciefd_id_table[] = { 304488c07b4SJimmy Assarsson { 305488c07b4SJimmy Assarsson PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_4HS_DEVICE_ID), 306488c07b4SJimmy Assarsson }, 307488c07b4SJimmy Assarsson { 308488c07b4SJimmy Assarsson PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_2HS_V2_DEVICE_ID), 309488c07b4SJimmy Assarsson }, 310488c07b4SJimmy Assarsson { 311488c07b4SJimmy Assarsson PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_HS_V2_DEVICE_ID), 312488c07b4SJimmy Assarsson }, 313488c07b4SJimmy Assarsson { 314488c07b4SJimmy Assarsson PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_HS_V2_DEVICE_ID), 315488c07b4SJimmy Assarsson }, 316488c07b4SJimmy Assarsson { 317488c07b4SJimmy Assarsson PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_2HS_V2_DEVICE_ID), 318488c07b4SJimmy Assarsson }, 319488c07b4SJimmy Assarsson { 320488c07b4SJimmy Assarsson 0, 321488c07b4SJimmy Assarsson }, 32226ad340eSHenning Colliander }; 32326ad340eSHenning Colliander MODULE_DEVICE_TABLE(pci, kvaser_pciefd_id_table); 32426ad340eSHenning Colliander 32526ad340eSHenning Colliander static void kvaser_pciefd_request_status(struct kvaser_pciefd_can *can) 32626ad340eSHenning Colliander { 32726ad340eSHenning Colliander u32 cmd; 32826ad340eSHenning Colliander 32926ad340eSHenning Colliander cmd = KVASER_PCIEFD_KCAN_CMD_SRQ; 330*954fb212SJimmy Assarsson cmd |= FIELD_PREP(KVASER_PCIEFD_KCAN_CMD_SEQ_MASK, ++can->cmd_seq); 33126ad340eSHenning Colliander iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG); 33226ad340eSHenning Colliander } 33326ad340eSHenning Colliander 33426ad340eSHenning Colliander static void kvaser_pciefd_enable_err_gen(struct kvaser_pciefd_can *can) 33526ad340eSHenning Colliander { 33626ad340eSHenning Colliander u32 mode; 33726ad340eSHenning Colliander unsigned long irq; 33826ad340eSHenning Colliander 33926ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq); 34026ad340eSHenning Colliander mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 34126ad340eSHenning Colliander if (!(mode & KVASER_PCIEFD_KCAN_MODE_EPEN)) { 34226ad340eSHenning Colliander mode |= KVASER_PCIEFD_KCAN_MODE_EPEN; 34326ad340eSHenning Colliander iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 34426ad340eSHenning Colliander } 34526ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq); 34626ad340eSHenning Colliander } 34726ad340eSHenning Colliander 34826ad340eSHenning Colliander static void kvaser_pciefd_disable_err_gen(struct kvaser_pciefd_can *can) 34926ad340eSHenning Colliander { 35026ad340eSHenning Colliander u32 mode; 35126ad340eSHenning Colliander unsigned long irq; 35226ad340eSHenning Colliander 35326ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq); 35426ad340eSHenning Colliander mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 35526ad340eSHenning Colliander mode &= ~KVASER_PCIEFD_KCAN_MODE_EPEN; 35626ad340eSHenning Colliander iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 35726ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq); 35826ad340eSHenning Colliander } 35926ad340eSHenning Colliander 36024aecf55SJimmy Assarsson static void kvaser_pciefd_set_tx_irq(struct kvaser_pciefd_can *can) 36126ad340eSHenning Colliander { 36226ad340eSHenning Colliander u32 msk; 36326ad340eSHenning Colliander 36426ad340eSHenning Colliander msk = KVASER_PCIEFD_KCAN_IRQ_TE | KVASER_PCIEFD_KCAN_IRQ_ROF | 36526ad340eSHenning Colliander KVASER_PCIEFD_KCAN_IRQ_TOF | KVASER_PCIEFD_KCAN_IRQ_ABD | 36626ad340eSHenning Colliander KVASER_PCIEFD_KCAN_IRQ_TAE | KVASER_PCIEFD_KCAN_IRQ_TAL | 36726ad340eSHenning Colliander KVASER_PCIEFD_KCAN_IRQ_FDIC | KVASER_PCIEFD_KCAN_IRQ_BPP | 368262d7a52SJimmy Assarsson KVASER_PCIEFD_KCAN_IRQ_TAR; 36926ad340eSHenning Colliander 37026ad340eSHenning Colliander iowrite32(msk, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 37126ad340eSHenning Colliander } 37226ad340eSHenning Colliander 3732d55e9f9SJimmy Assarsson static inline void kvaser_pciefd_set_skb_timestamp(const struct kvaser_pciefd *pcie, 3742d55e9f9SJimmy Assarsson struct sk_buff *skb, u64 timestamp) 3752d55e9f9SJimmy Assarsson { 3762d55e9f9SJimmy Assarsson skb_hwtstamps(skb)->hwtstamp = 3772d55e9f9SJimmy Assarsson ns_to_ktime(div_u64(timestamp * 1000, pcie->freq_to_ticks_div)); 3782d55e9f9SJimmy Assarsson } 3792d55e9f9SJimmy Assarsson 38026ad340eSHenning Colliander static void kvaser_pciefd_setup_controller(struct kvaser_pciefd_can *can) 38126ad340eSHenning Colliander { 38226ad340eSHenning Colliander u32 mode; 38326ad340eSHenning Colliander unsigned long irq; 38426ad340eSHenning Colliander 38526ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq); 38626ad340eSHenning Colliander 38726ad340eSHenning Colliander mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 38826ad340eSHenning Colliander if (can->can.ctrlmode & CAN_CTRLMODE_FD) { 38926ad340eSHenning Colliander mode &= ~KVASER_PCIEFD_KCAN_MODE_CCM; 39026ad340eSHenning Colliander if (can->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) 39126ad340eSHenning Colliander mode |= KVASER_PCIEFD_KCAN_MODE_NIFDEN; 39226ad340eSHenning Colliander else 39326ad340eSHenning Colliander mode &= ~KVASER_PCIEFD_KCAN_MODE_NIFDEN; 39426ad340eSHenning Colliander } else { 39526ad340eSHenning Colliander mode |= KVASER_PCIEFD_KCAN_MODE_CCM; 39626ad340eSHenning Colliander mode &= ~KVASER_PCIEFD_KCAN_MODE_NIFDEN; 39726ad340eSHenning Colliander } 39826ad340eSHenning Colliander 39926ad340eSHenning Colliander if (can->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) 40026ad340eSHenning Colliander mode |= KVASER_PCIEFD_KCAN_MODE_LOM; 401bf7ac55eSJimmy Assarsson else 402bf7ac55eSJimmy Assarsson mode &= ~KVASER_PCIEFD_KCAN_MODE_LOM; 40326ad340eSHenning Colliander 40426ad340eSHenning Colliander mode |= KVASER_PCIEFD_KCAN_MODE_EEN; 40526ad340eSHenning Colliander mode |= KVASER_PCIEFD_KCAN_MODE_EPEN; 40626ad340eSHenning Colliander /* Use ACK packet type */ 40726ad340eSHenning Colliander mode &= ~KVASER_PCIEFD_KCAN_MODE_APT; 40826ad340eSHenning Colliander mode &= ~KVASER_PCIEFD_KCAN_MODE_RM; 40926ad340eSHenning Colliander iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 41026ad340eSHenning Colliander 41126ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq); 41226ad340eSHenning Colliander } 41326ad340eSHenning Colliander 41426ad340eSHenning Colliander static void kvaser_pciefd_start_controller_flush(struct kvaser_pciefd_can *can) 41526ad340eSHenning Colliander { 41626ad340eSHenning Colliander u32 status; 41726ad340eSHenning Colliander unsigned long irq; 41826ad340eSHenning Colliander 41926ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq); 42026ad340eSHenning Colliander iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); 421262d7a52SJimmy Assarsson iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD, 42226ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 42326ad340eSHenning Colliander 42426ad340eSHenning Colliander status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG); 42526ad340eSHenning Colliander if (status & KVASER_PCIEFD_KCAN_STAT_IDLE) { 42626ad340eSHenning Colliander u32 cmd; 42726ad340eSHenning Colliander 42826ad340eSHenning Colliander /* If controller is already idle, run abort, flush and reset */ 42926ad340eSHenning Colliander cmd = KVASER_PCIEFD_KCAN_CMD_AT; 430*954fb212SJimmy Assarsson cmd |= FIELD_PREP(KVASER_PCIEFD_KCAN_CMD_SEQ_MASK, ++can->cmd_seq); 43126ad340eSHenning Colliander iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG); 43226ad340eSHenning Colliander } else if (!(status & KVASER_PCIEFD_KCAN_STAT_RMR)) { 43326ad340eSHenning Colliander u32 mode; 43426ad340eSHenning Colliander 43526ad340eSHenning Colliander /* Put controller in reset mode */ 43626ad340eSHenning Colliander mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 43726ad340eSHenning Colliander mode |= KVASER_PCIEFD_KCAN_MODE_RM; 43826ad340eSHenning Colliander iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 43926ad340eSHenning Colliander } 44026ad340eSHenning Colliander 44126ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq); 44226ad340eSHenning Colliander } 44326ad340eSHenning Colliander 44426ad340eSHenning Colliander static int kvaser_pciefd_bus_on(struct kvaser_pciefd_can *can) 44526ad340eSHenning Colliander { 44626ad340eSHenning Colliander u32 mode; 44726ad340eSHenning Colliander unsigned long irq; 44826ad340eSHenning Colliander 44926ad340eSHenning Colliander del_timer(&can->bec_poll_timer); 45026ad340eSHenning Colliander 45126ad340eSHenning Colliander if (!completion_done(&can->flush_comp)) 45226ad340eSHenning Colliander kvaser_pciefd_start_controller_flush(can); 45326ad340eSHenning Colliander 45426ad340eSHenning Colliander if (!wait_for_completion_timeout(&can->flush_comp, 45526ad340eSHenning Colliander KVASER_PCIEFD_WAIT_TIMEOUT)) { 45626ad340eSHenning Colliander netdev_err(can->can.dev, "Timeout during bus on flush\n"); 45726ad340eSHenning Colliander return -ETIMEDOUT; 45826ad340eSHenning Colliander } 45926ad340eSHenning Colliander 46026ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq); 46126ad340eSHenning Colliander iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 46226ad340eSHenning Colliander iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); 46326ad340eSHenning Colliander 464262d7a52SJimmy Assarsson iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD, 46526ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 46626ad340eSHenning Colliander 46726ad340eSHenning Colliander mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 46826ad340eSHenning Colliander mode &= ~KVASER_PCIEFD_KCAN_MODE_RM; 46926ad340eSHenning Colliander iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 47026ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq); 47126ad340eSHenning Colliander 47226ad340eSHenning Colliander if (!wait_for_completion_timeout(&can->start_comp, 47326ad340eSHenning Colliander KVASER_PCIEFD_WAIT_TIMEOUT)) { 47426ad340eSHenning Colliander netdev_err(can->can.dev, "Timeout during bus on reset\n"); 47526ad340eSHenning Colliander return -ETIMEDOUT; 47626ad340eSHenning Colliander } 47726ad340eSHenning Colliander /* Reset interrupt handling */ 47826ad340eSHenning Colliander iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 47926ad340eSHenning Colliander iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); 48026ad340eSHenning Colliander 48126ad340eSHenning Colliander kvaser_pciefd_set_tx_irq(can); 48226ad340eSHenning Colliander kvaser_pciefd_setup_controller(can); 48326ad340eSHenning Colliander 48426ad340eSHenning Colliander can->can.state = CAN_STATE_ERROR_ACTIVE; 48526ad340eSHenning Colliander netif_wake_queue(can->can.dev); 48626ad340eSHenning Colliander can->bec.txerr = 0; 48726ad340eSHenning Colliander can->bec.rxerr = 0; 48826ad340eSHenning Colliander can->err_rep_cnt = 0; 48926ad340eSHenning Colliander 49026ad340eSHenning Colliander return 0; 49126ad340eSHenning Colliander } 49226ad340eSHenning Colliander 49326ad340eSHenning Colliander static void kvaser_pciefd_pwm_stop(struct kvaser_pciefd_can *can) 49426ad340eSHenning Colliander { 4951910cd88SChrister Beskow u8 top; 49626ad340eSHenning Colliander u32 pwm_ctrl; 49726ad340eSHenning Colliander unsigned long irq; 49826ad340eSHenning Colliander 49926ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq); 50026ad340eSHenning Colliander pwm_ctrl = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG); 501*954fb212SJimmy Assarsson top = FIELD_GET(KVASER_PCIEFD_KCAN_PWM_TOP_MASK, pwm_ctrl); 50226ad340eSHenning Colliander 5031910cd88SChrister Beskow /* Set duty cycle to zero */ 504*954fb212SJimmy Assarsson pwm_ctrl |= FIELD_PREP(KVASER_PCIEFD_KCAN_PWM_TRIGGER_MASK, top); 50526ad340eSHenning Colliander iowrite32(pwm_ctrl, can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG); 50626ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq); 50726ad340eSHenning Colliander } 50826ad340eSHenning Colliander 50926ad340eSHenning Colliander static void kvaser_pciefd_pwm_start(struct kvaser_pciefd_can *can) 51026ad340eSHenning Colliander { 51126ad340eSHenning Colliander int top, trigger; 51226ad340eSHenning Colliander u32 pwm_ctrl; 51326ad340eSHenning Colliander unsigned long irq; 51426ad340eSHenning Colliander 51526ad340eSHenning Colliander kvaser_pciefd_pwm_stop(can); 51626ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq); 51726ad340eSHenning Colliander 51826ad340eSHenning Colliander /* Set frequency to 500 KHz*/ 519ec44dd57SChrister Beskow top = can->kv_pcie->bus_freq / (2 * 500000) - 1; 52026ad340eSHenning Colliander 521*954fb212SJimmy Assarsson pwm_ctrl = FIELD_PREP(KVASER_PCIEFD_KCAN_PWM_TRIGGER_MASK, top); 522*954fb212SJimmy Assarsson pwm_ctrl |= FIELD_PREP(KVASER_PCIEFD_KCAN_PWM_TOP_MASK, top); 52326ad340eSHenning Colliander iowrite32(pwm_ctrl, can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG); 52426ad340eSHenning Colliander 52526ad340eSHenning Colliander /* Set duty cycle to 95 */ 52626ad340eSHenning Colliander trigger = (100 * top - 95 * (top + 1) + 50) / 100; 527*954fb212SJimmy Assarsson pwm_ctrl = FIELD_PREP(KVASER_PCIEFD_KCAN_PWM_TRIGGER_MASK, trigger); 528*954fb212SJimmy Assarsson pwm_ctrl |= FIELD_PREP(KVASER_PCIEFD_KCAN_PWM_TOP_MASK, top); 52926ad340eSHenning Colliander iowrite32(pwm_ctrl, can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG); 53026ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq); 53126ad340eSHenning Colliander } 53226ad340eSHenning Colliander 53326ad340eSHenning Colliander static int kvaser_pciefd_open(struct net_device *netdev) 53426ad340eSHenning Colliander { 53526ad340eSHenning Colliander int err; 53626ad340eSHenning Colliander struct kvaser_pciefd_can *can = netdev_priv(netdev); 53726ad340eSHenning Colliander 53826ad340eSHenning Colliander err = open_candev(netdev); 53926ad340eSHenning Colliander if (err) 54026ad340eSHenning Colliander return err; 54126ad340eSHenning Colliander 54226ad340eSHenning Colliander err = kvaser_pciefd_bus_on(can); 54313a84cf3SZhang Qilong if (err) { 54413a84cf3SZhang Qilong close_candev(netdev); 54526ad340eSHenning Colliander return err; 54613a84cf3SZhang Qilong } 54726ad340eSHenning Colliander 54826ad340eSHenning Colliander return 0; 54926ad340eSHenning Colliander } 55026ad340eSHenning Colliander 55126ad340eSHenning Colliander static int kvaser_pciefd_stop(struct net_device *netdev) 55226ad340eSHenning Colliander { 55326ad340eSHenning Colliander struct kvaser_pciefd_can *can = netdev_priv(netdev); 55426ad340eSHenning Colliander int ret = 0; 55526ad340eSHenning Colliander 55626ad340eSHenning Colliander /* Don't interrupt ongoing flush */ 55726ad340eSHenning Colliander if (!completion_done(&can->flush_comp)) 55826ad340eSHenning Colliander kvaser_pciefd_start_controller_flush(can); 55926ad340eSHenning Colliander 56026ad340eSHenning Colliander if (!wait_for_completion_timeout(&can->flush_comp, 56126ad340eSHenning Colliander KVASER_PCIEFD_WAIT_TIMEOUT)) { 56226ad340eSHenning Colliander netdev_err(can->can.dev, "Timeout during stop\n"); 56326ad340eSHenning Colliander ret = -ETIMEDOUT; 56426ad340eSHenning Colliander } else { 56526ad340eSHenning Colliander iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 56626ad340eSHenning Colliander del_timer(&can->bec_poll_timer); 56726ad340eSHenning Colliander } 568aed0e6caSJimmy Assarsson can->can.state = CAN_STATE_STOPPED; 56926ad340eSHenning Colliander close_candev(netdev); 57026ad340eSHenning Colliander 57126ad340eSHenning Colliander return ret; 57226ad340eSHenning Colliander } 57326ad340eSHenning Colliander 57426ad340eSHenning Colliander static int kvaser_pciefd_prepare_tx_packet(struct kvaser_pciefd_tx_packet *p, 57526ad340eSHenning Colliander struct kvaser_pciefd_can *can, 57626ad340eSHenning Colliander struct sk_buff *skb) 57726ad340eSHenning Colliander { 57826ad340eSHenning Colliander struct canfd_frame *cf = (struct canfd_frame *)skb->data; 57926ad340eSHenning Colliander int packet_size; 58026ad340eSHenning Colliander int seq = can->echo_idx; 58126ad340eSHenning Colliander 58226ad340eSHenning Colliander memset(p, 0, sizeof(*p)); 58326ad340eSHenning Colliander 58426ad340eSHenning Colliander if (can->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) 58526ad340eSHenning Colliander p->header[1] |= KVASER_PCIEFD_TPACKET_SMS; 58626ad340eSHenning Colliander 58726ad340eSHenning Colliander if (cf->can_id & CAN_RTR_FLAG) 58826ad340eSHenning Colliander p->header[0] |= KVASER_PCIEFD_RPACKET_RTR; 58926ad340eSHenning Colliander 59026ad340eSHenning Colliander if (cf->can_id & CAN_EFF_FLAG) 59126ad340eSHenning Colliander p->header[0] |= KVASER_PCIEFD_RPACKET_IDE; 59226ad340eSHenning Colliander 593*954fb212SJimmy Assarsson p->header[0] |= FIELD_PREP(KVASER_PCIEFD_RPACKET_ID_MASK, cf->can_id); 594*954fb212SJimmy Assarsson p->header[1] |= FIELD_PREP(KVASER_PCIEFD_RPACKET_DLC_MASK, can_fd_len2dlc(cf->len)); 59526ad340eSHenning Colliander p->header[1] |= KVASER_PCIEFD_TPACKET_AREQ; 59626ad340eSHenning Colliander 59726ad340eSHenning Colliander if (can_is_canfd_skb(skb)) { 59826ad340eSHenning Colliander p->header[1] |= KVASER_PCIEFD_RPACKET_FDF; 59926ad340eSHenning Colliander if (cf->flags & CANFD_BRS) 60026ad340eSHenning Colliander p->header[1] |= KVASER_PCIEFD_RPACKET_BRS; 60126ad340eSHenning Colliander if (cf->flags & CANFD_ESI) 60226ad340eSHenning Colliander p->header[1] |= KVASER_PCIEFD_RPACKET_ESI; 60326ad340eSHenning Colliander } 60426ad340eSHenning Colliander 605*954fb212SJimmy Assarsson p->header[1] |= FIELD_PREP(KVASER_PCIEFD_PACKET_SEQ_MASK, seq); 60626ad340eSHenning Colliander 60726ad340eSHenning Colliander packet_size = cf->len; 60826ad340eSHenning Colliander memcpy(p->data, cf->data, packet_size); 60926ad340eSHenning Colliander 61026ad340eSHenning Colliander return DIV_ROUND_UP(packet_size, 4); 61126ad340eSHenning Colliander } 61226ad340eSHenning Colliander 61326ad340eSHenning Colliander static netdev_tx_t kvaser_pciefd_start_xmit(struct sk_buff *skb, 61426ad340eSHenning Colliander struct net_device *netdev) 61526ad340eSHenning Colliander { 61626ad340eSHenning Colliander struct kvaser_pciefd_can *can = netdev_priv(netdev); 61726ad340eSHenning Colliander unsigned long irq_flags; 61826ad340eSHenning Colliander struct kvaser_pciefd_tx_packet packet; 61926ad340eSHenning Colliander int nwords; 62026ad340eSHenning Colliander u8 count; 62126ad340eSHenning Colliander 622ae64438bSOliver Hartkopp if (can_dev_dropped_skb(netdev, skb)) 62326ad340eSHenning Colliander return NETDEV_TX_OK; 62426ad340eSHenning Colliander 62526ad340eSHenning Colliander nwords = kvaser_pciefd_prepare_tx_packet(&packet, can, skb); 62626ad340eSHenning Colliander 62726ad340eSHenning Colliander spin_lock_irqsave(&can->echo_lock, irq_flags); 62826ad340eSHenning Colliander 62926ad340eSHenning Colliander /* Prepare and save echo skb in internal slot */ 6301dcb6e57SVincent Mailhol can_put_echo_skb(skb, netdev, can->echo_idx, 0); 63126ad340eSHenning Colliander 63226ad340eSHenning Colliander /* Move echo index to the next slot */ 63326ad340eSHenning Colliander can->echo_idx = (can->echo_idx + 1) % can->can.echo_skb_max; 63426ad340eSHenning Colliander 63526ad340eSHenning Colliander /* Write header to fifo */ 63626ad340eSHenning Colliander iowrite32(packet.header[0], 63726ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_FIFO_REG); 63826ad340eSHenning Colliander iowrite32(packet.header[1], 63926ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_FIFO_REG); 64026ad340eSHenning Colliander 64126ad340eSHenning Colliander if (nwords) { 64226ad340eSHenning Colliander u32 data_last = ((u32 *)packet.data)[nwords - 1]; 64326ad340eSHenning Colliander 64426ad340eSHenning Colliander /* Write data to fifo, except last word */ 64526ad340eSHenning Colliander iowrite32_rep(can->reg_base + 64626ad340eSHenning Colliander KVASER_PCIEFD_KCAN_FIFO_REG, packet.data, 64726ad340eSHenning Colliander nwords - 1); 64826ad340eSHenning Colliander /* Write last word to end of fifo */ 64926ad340eSHenning Colliander __raw_writel(data_last, can->reg_base + 65026ad340eSHenning Colliander KVASER_PCIEFD_KCAN_FIFO_LAST_REG); 65126ad340eSHenning Colliander } else { 65226ad340eSHenning Colliander /* Complete write to fifo */ 65326ad340eSHenning Colliander __raw_writel(0, can->reg_base + 65426ad340eSHenning Colliander KVASER_PCIEFD_KCAN_FIFO_LAST_REG); 65526ad340eSHenning Colliander } 65626ad340eSHenning Colliander 657*954fb212SJimmy Assarsson count = FIELD_GET(KVASER_PCIEFD_KCAN_TX_NR_PACKETS_CURRENT_MASK, 658*954fb212SJimmy Assarsson ioread32(can->reg_base + KVASER_PCIEFD_KCAN_TX_NPACKETS_REG)); 65926ad340eSHenning Colliander /* No room for a new message, stop the queue until at least one 66026ad340eSHenning Colliander * successful transmit 66126ad340eSHenning Colliander */ 66226ad340eSHenning Colliander if (count >= KVASER_PCIEFD_CAN_TX_MAX_COUNT || 66326ad340eSHenning Colliander can->can.echo_skb[can->echo_idx]) 66426ad340eSHenning Colliander netif_stop_queue(netdev); 66526ad340eSHenning Colliander 66626ad340eSHenning Colliander spin_unlock_irqrestore(&can->echo_lock, irq_flags); 66726ad340eSHenning Colliander 66826ad340eSHenning Colliander return NETDEV_TX_OK; 66926ad340eSHenning Colliander } 67026ad340eSHenning Colliander 67126ad340eSHenning Colliander static int kvaser_pciefd_set_bittiming(struct kvaser_pciefd_can *can, bool data) 67226ad340eSHenning Colliander { 67326ad340eSHenning Colliander u32 mode, test, btrn; 67426ad340eSHenning Colliander unsigned long irq_flags; 67526ad340eSHenning Colliander int ret; 67626ad340eSHenning Colliander struct can_bittiming *bt; 67726ad340eSHenning Colliander 67826ad340eSHenning Colliander if (data) 67926ad340eSHenning Colliander bt = &can->can.data_bittiming; 68026ad340eSHenning Colliander else 68126ad340eSHenning Colliander bt = &can->can.bittiming; 68226ad340eSHenning Colliander 683*954fb212SJimmy Assarsson btrn = FIELD_PREP(KVASER_PCIEFD_KCAN_BTRN_TSEG2_MASK, bt->phase_seg2 - 1) | 684*954fb212SJimmy Assarsson FIELD_PREP(KVASER_PCIEFD_KCAN_BTRN_TSEG1_MASK, bt->prop_seg + bt->phase_seg1 - 1) | 685*954fb212SJimmy Assarsson FIELD_PREP(KVASER_PCIEFD_KCAN_BTRN_SJW_MASK, bt->sjw - 1) | 686*954fb212SJimmy Assarsson FIELD_PREP(KVASER_PCIEFD_KCAN_BTRN_BRP_MASK, bt->brp - 1); 68726ad340eSHenning Colliander 68826ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq_flags); 68926ad340eSHenning Colliander mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 69026ad340eSHenning Colliander 69126ad340eSHenning Colliander /* Put the circuit in reset mode */ 69226ad340eSHenning Colliander iowrite32(mode | KVASER_PCIEFD_KCAN_MODE_RM, 69326ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 69426ad340eSHenning Colliander 69526ad340eSHenning Colliander /* Can only set bittiming if in reset mode */ 69626ad340eSHenning Colliander ret = readl_poll_timeout(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG, 69726ad340eSHenning Colliander test, test & KVASER_PCIEFD_KCAN_MODE_RM, 69826ad340eSHenning Colliander 0, 10); 69926ad340eSHenning Colliander 70026ad340eSHenning Colliander if (ret) { 70126ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq_flags); 70226ad340eSHenning Colliander return -EBUSY; 70326ad340eSHenning Colliander } 70426ad340eSHenning Colliander 70526ad340eSHenning Colliander if (data) 70626ad340eSHenning Colliander iowrite32(btrn, can->reg_base + KVASER_PCIEFD_KCAN_BTRD_REG); 70726ad340eSHenning Colliander else 70826ad340eSHenning Colliander iowrite32(btrn, can->reg_base + KVASER_PCIEFD_KCAN_BTRN_REG); 70926ad340eSHenning Colliander 71026ad340eSHenning Colliander /* Restore previous reset mode status */ 71126ad340eSHenning Colliander iowrite32(mode, can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); 71226ad340eSHenning Colliander 71326ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq_flags); 71426ad340eSHenning Colliander return 0; 71526ad340eSHenning Colliander } 71626ad340eSHenning Colliander 71726ad340eSHenning Colliander static int kvaser_pciefd_set_nominal_bittiming(struct net_device *ndev) 71826ad340eSHenning Colliander { 71926ad340eSHenning Colliander return kvaser_pciefd_set_bittiming(netdev_priv(ndev), false); 72026ad340eSHenning Colliander } 72126ad340eSHenning Colliander 72226ad340eSHenning Colliander static int kvaser_pciefd_set_data_bittiming(struct net_device *ndev) 72326ad340eSHenning Colliander { 72426ad340eSHenning Colliander return kvaser_pciefd_set_bittiming(netdev_priv(ndev), true); 72526ad340eSHenning Colliander } 72626ad340eSHenning Colliander 72726ad340eSHenning Colliander static int kvaser_pciefd_set_mode(struct net_device *ndev, enum can_mode mode) 72826ad340eSHenning Colliander { 72926ad340eSHenning Colliander struct kvaser_pciefd_can *can = netdev_priv(ndev); 73026ad340eSHenning Colliander int ret = 0; 73126ad340eSHenning Colliander 73226ad340eSHenning Colliander switch (mode) { 73326ad340eSHenning Colliander case CAN_MODE_START: 73426ad340eSHenning Colliander if (!can->can.restart_ms) 73526ad340eSHenning Colliander ret = kvaser_pciefd_bus_on(can); 73626ad340eSHenning Colliander break; 73726ad340eSHenning Colliander default: 73826ad340eSHenning Colliander return -EOPNOTSUPP; 73926ad340eSHenning Colliander } 74026ad340eSHenning Colliander 74126ad340eSHenning Colliander return ret; 74226ad340eSHenning Colliander } 74326ad340eSHenning Colliander 74426ad340eSHenning Colliander static int kvaser_pciefd_get_berr_counter(const struct net_device *ndev, 74526ad340eSHenning Colliander struct can_berr_counter *bec) 74626ad340eSHenning Colliander { 74726ad340eSHenning Colliander struct kvaser_pciefd_can *can = netdev_priv(ndev); 74826ad340eSHenning Colliander 74926ad340eSHenning Colliander bec->rxerr = can->bec.rxerr; 75026ad340eSHenning Colliander bec->txerr = can->bec.txerr; 75126ad340eSHenning Colliander return 0; 75226ad340eSHenning Colliander } 75326ad340eSHenning Colliander 75426ad340eSHenning Colliander static void kvaser_pciefd_bec_poll_timer(struct timer_list *data) 75526ad340eSHenning Colliander { 75626ad340eSHenning Colliander struct kvaser_pciefd_can *can = from_timer(can, data, bec_poll_timer); 75726ad340eSHenning Colliander 75826ad340eSHenning Colliander kvaser_pciefd_enable_err_gen(can); 75926ad340eSHenning Colliander kvaser_pciefd_request_status(can); 76026ad340eSHenning Colliander can->err_rep_cnt = 0; 76126ad340eSHenning Colliander } 76226ad340eSHenning Colliander 76326ad340eSHenning Colliander static const struct net_device_ops kvaser_pciefd_netdev_ops = { 76426ad340eSHenning Colliander .ndo_open = kvaser_pciefd_open, 76526ad340eSHenning Colliander .ndo_stop = kvaser_pciefd_stop, 766fa5cc7e1SVincent Mailhol .ndo_eth_ioctl = can_eth_ioctl_hwts, 76726ad340eSHenning Colliander .ndo_start_xmit = kvaser_pciefd_start_xmit, 76826ad340eSHenning Colliander .ndo_change_mtu = can_change_mtu, 76926ad340eSHenning Colliander }; 77026ad340eSHenning Colliander 771fa5cc7e1SVincent Mailhol static const struct ethtool_ops kvaser_pciefd_ethtool_ops = { 772fa5cc7e1SVincent Mailhol .get_ts_info = can_ethtool_op_get_ts_info_hwts, 773fa5cc7e1SVincent Mailhol }; 774fa5cc7e1SVincent Mailhol 77526ad340eSHenning Colliander static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) 77626ad340eSHenning Colliander { 77726ad340eSHenning Colliander int i; 77826ad340eSHenning Colliander 77926ad340eSHenning Colliander for (i = 0; i < pcie->nr_channels; i++) { 78026ad340eSHenning Colliander struct net_device *netdev; 78126ad340eSHenning Colliander struct kvaser_pciefd_can *can; 782*954fb212SJimmy Assarsson u32 status, tx_nr_packets_max; 78326ad340eSHenning Colliander 78426ad340eSHenning Colliander netdev = alloc_candev(sizeof(struct kvaser_pciefd_can), 78526ad340eSHenning Colliander KVASER_PCIEFD_CAN_TX_MAX_COUNT); 78626ad340eSHenning Colliander if (!netdev) 78726ad340eSHenning Colliander return -ENOMEM; 78826ad340eSHenning Colliander 78926ad340eSHenning Colliander can = netdev_priv(netdev); 79026ad340eSHenning Colliander netdev->netdev_ops = &kvaser_pciefd_netdev_ops; 791fa5cc7e1SVincent Mailhol netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops; 79226ad340eSHenning Colliander can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE + 79326ad340eSHenning Colliander i * KVASER_PCIEFD_KCAN_BASE_OFFSET; 79426ad340eSHenning Colliander 79526ad340eSHenning Colliander can->kv_pcie = pcie; 79626ad340eSHenning Colliander can->cmd_seq = 0; 79726ad340eSHenning Colliander can->err_rep_cnt = 0; 79826ad340eSHenning Colliander can->bec.txerr = 0; 79926ad340eSHenning Colliander can->bec.rxerr = 0; 80026ad340eSHenning Colliander 80126ad340eSHenning Colliander init_completion(&can->start_comp); 80226ad340eSHenning Colliander init_completion(&can->flush_comp); 80326ad340eSHenning Colliander timer_setup(&can->bec_poll_timer, kvaser_pciefd_bec_poll_timer, 80426ad340eSHenning Colliander 0); 80526ad340eSHenning Colliander 8067c6e6bceSJimmy Assarsson /* Disable Bus load reporting */ 8077c6e6bceSJimmy Assarsson iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_BUS_LOAD_REG); 8087c6e6bceSJimmy Assarsson 809*954fb212SJimmy Assarsson tx_nr_packets_max = 810*954fb212SJimmy Assarsson FIELD_GET(KVASER_PCIEFD_KCAN_TX_NR_PACKETS_MAX_MASK, 811*954fb212SJimmy Assarsson ioread32(can->reg_base + KVASER_PCIEFD_KCAN_TX_NPACKETS_REG)); 812*954fb212SJimmy Assarsson if (tx_nr_packets_max < KVASER_PCIEFD_CAN_TX_MAX_COUNT) { 81326ad340eSHenning Colliander dev_err(&pcie->pci->dev, 81426ad340eSHenning Colliander "Max Tx count is smaller than expected\n"); 81526ad340eSHenning Colliander 81626ad340eSHenning Colliander free_candev(netdev); 81726ad340eSHenning Colliander return -ENODEV; 81826ad340eSHenning Colliander } 81926ad340eSHenning Colliander 82026ad340eSHenning Colliander can->can.clock.freq = pcie->freq; 82126ad340eSHenning Colliander can->can.echo_skb_max = KVASER_PCIEFD_CAN_TX_MAX_COUNT; 82226ad340eSHenning Colliander can->echo_idx = 0; 82326ad340eSHenning Colliander spin_lock_init(&can->echo_lock); 82426ad340eSHenning Colliander spin_lock_init(&can->lock); 82526ad340eSHenning Colliander can->can.bittiming_const = &kvaser_pciefd_bittiming_const; 82626ad340eSHenning Colliander can->can.data_bittiming_const = &kvaser_pciefd_bittiming_const; 82726ad340eSHenning Colliander 82826ad340eSHenning Colliander can->can.do_set_bittiming = kvaser_pciefd_set_nominal_bittiming; 82926ad340eSHenning Colliander can->can.do_set_data_bittiming = 83026ad340eSHenning Colliander kvaser_pciefd_set_data_bittiming; 83126ad340eSHenning Colliander 83226ad340eSHenning Colliander can->can.do_set_mode = kvaser_pciefd_set_mode; 83326ad340eSHenning Colliander can->can.do_get_berr_counter = kvaser_pciefd_get_berr_counter; 83426ad340eSHenning Colliander 83526ad340eSHenning Colliander can->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY | 83626ad340eSHenning Colliander CAN_CTRLMODE_FD | 83726ad340eSHenning Colliander CAN_CTRLMODE_FD_NON_ISO; 83826ad340eSHenning Colliander 83926ad340eSHenning Colliander status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG); 84026ad340eSHenning Colliander if (!(status & KVASER_PCIEFD_KCAN_STAT_FD)) { 84126ad340eSHenning Colliander dev_err(&pcie->pci->dev, 84226ad340eSHenning Colliander "CAN FD not supported as expected %d\n", i); 84326ad340eSHenning Colliander 84426ad340eSHenning Colliander free_candev(netdev); 84526ad340eSHenning Colliander return -ENODEV; 84626ad340eSHenning Colliander } 84726ad340eSHenning Colliander 84826ad340eSHenning Colliander if (status & KVASER_PCIEFD_KCAN_STAT_CAP) 84926ad340eSHenning Colliander can->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT; 85026ad340eSHenning Colliander 85126ad340eSHenning Colliander netdev->flags |= IFF_ECHO; 85226ad340eSHenning Colliander 85326ad340eSHenning Colliander SET_NETDEV_DEV(netdev, &pcie->pci->dev); 85426ad340eSHenning Colliander 85526ad340eSHenning Colliander iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); 856262d7a52SJimmy Assarsson iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD, 85726ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 85826ad340eSHenning Colliander 85926ad340eSHenning Colliander pcie->can[i] = can; 86026ad340eSHenning Colliander kvaser_pciefd_pwm_start(can); 86126ad340eSHenning Colliander } 86226ad340eSHenning Colliander 86326ad340eSHenning Colliander return 0; 86426ad340eSHenning Colliander } 86526ad340eSHenning Colliander 86626ad340eSHenning Colliander static int kvaser_pciefd_reg_candev(struct kvaser_pciefd *pcie) 86726ad340eSHenning Colliander { 86826ad340eSHenning Colliander int i; 86926ad340eSHenning Colliander 87026ad340eSHenning Colliander for (i = 0; i < pcie->nr_channels; i++) { 87126ad340eSHenning Colliander int err = register_candev(pcie->can[i]->can.dev); 87226ad340eSHenning Colliander 87326ad340eSHenning Colliander if (err) { 87426ad340eSHenning Colliander int j; 87526ad340eSHenning Colliander 87626ad340eSHenning Colliander /* Unregister all successfully registered devices. */ 87726ad340eSHenning Colliander for (j = 0; j < i; j++) 87826ad340eSHenning Colliander unregister_candev(pcie->can[j]->can.dev); 87926ad340eSHenning Colliander return err; 88026ad340eSHenning Colliander } 88126ad340eSHenning Colliander } 88226ad340eSHenning Colliander 88326ad340eSHenning Colliander return 0; 88426ad340eSHenning Colliander } 88526ad340eSHenning Colliander 88626ad340eSHenning Colliander static void kvaser_pciefd_write_dma_map(struct kvaser_pciefd *pcie, 88726ad340eSHenning Colliander dma_addr_t addr, int offset) 88826ad340eSHenning Colliander { 88926ad340eSHenning Colliander u32 word1, word2; 89026ad340eSHenning Colliander 89126ad340eSHenning Colliander #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 89226ad340eSHenning Colliander word1 = addr | KVASER_PCIEFD_64BIT_DMA_BIT; 89326ad340eSHenning Colliander word2 = addr >> 32; 89426ad340eSHenning Colliander #else 89526ad340eSHenning Colliander word1 = addr; 89626ad340eSHenning Colliander word2 = 0; 89726ad340eSHenning Colliander #endif 89826ad340eSHenning Colliander iowrite32(word1, pcie->reg_base + offset); 89926ad340eSHenning Colliander iowrite32(word2, pcie->reg_base + offset + 4); 90026ad340eSHenning Colliander } 90126ad340eSHenning Colliander 90226ad340eSHenning Colliander static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie) 90326ad340eSHenning Colliander { 90426ad340eSHenning Colliander int i; 90526ad340eSHenning Colliander u32 srb_status; 906c589557dSJimmy Assarsson u32 srb_packet_count; 90726ad340eSHenning Colliander dma_addr_t dma_addr[KVASER_PCIEFD_DMA_COUNT]; 90826ad340eSHenning Colliander 90926ad340eSHenning Colliander /* Disable the DMA */ 91026ad340eSHenning Colliander iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG); 91126ad340eSHenning Colliander for (i = 0; i < KVASER_PCIEFD_DMA_COUNT; i++) { 91226ad340eSHenning Colliander unsigned int offset = KVASER_PCIEFD_DMA_MAP_BASE + 8 * i; 91326ad340eSHenning Colliander 91426ad340eSHenning Colliander pcie->dma_data[i] = 91526ad340eSHenning Colliander dmam_alloc_coherent(&pcie->pci->dev, 91626ad340eSHenning Colliander KVASER_PCIEFD_DMA_SIZE, 91726ad340eSHenning Colliander &dma_addr[i], 91826ad340eSHenning Colliander GFP_KERNEL); 91926ad340eSHenning Colliander 92026ad340eSHenning Colliander if (!pcie->dma_data[i] || !dma_addr[i]) { 92126ad340eSHenning Colliander dev_err(&pcie->pci->dev, "Rx dma_alloc(%u) failure\n", 92226ad340eSHenning Colliander KVASER_PCIEFD_DMA_SIZE); 92326ad340eSHenning Colliander return -ENOMEM; 92426ad340eSHenning Colliander } 92526ad340eSHenning Colliander 92626ad340eSHenning Colliander kvaser_pciefd_write_dma_map(pcie, dma_addr[i], offset); 92726ad340eSHenning Colliander } 92826ad340eSHenning Colliander 92926ad340eSHenning Colliander /* Reset Rx FIFO, and both DMA buffers */ 93026ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_SRB_CMD_FOR | KVASER_PCIEFD_SRB_CMD_RDB0 | 93126ad340eSHenning Colliander KVASER_PCIEFD_SRB_CMD_RDB1, 93226ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG); 93326ad340eSHenning Colliander 934c589557dSJimmy Assarsson /* Empty Rx FIFO */ 935*954fb212SJimmy Assarsson srb_packet_count = 936*954fb212SJimmy Assarsson FIELD_GET(KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK, 937*954fb212SJimmy Assarsson ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG)); 938c589557dSJimmy Assarsson while (srb_packet_count) { 939c589557dSJimmy Assarsson /* Drop current packet in FIFO */ 940c589557dSJimmy Assarsson ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_FIFO_LAST_REG); 941c589557dSJimmy Assarsson srb_packet_count--; 942c589557dSJimmy Assarsson } 943c589557dSJimmy Assarsson 94426ad340eSHenning Colliander srb_status = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_STAT_REG); 94526ad340eSHenning Colliander if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DI)) { 94626ad340eSHenning Colliander dev_err(&pcie->pci->dev, "DMA not idle before enabling\n"); 94726ad340eSHenning Colliander return -EIO; 94826ad340eSHenning Colliander } 94926ad340eSHenning Colliander 95026ad340eSHenning Colliander /* Enable the DMA */ 95126ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE, 95226ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG); 95326ad340eSHenning Colliander 95426ad340eSHenning Colliander return 0; 95526ad340eSHenning Colliander } 95626ad340eSHenning Colliander 95726ad340eSHenning Colliander static int kvaser_pciefd_setup_board(struct kvaser_pciefd *pcie) 95826ad340eSHenning Colliander { 959*954fb212SJimmy Assarsson u32 version, srb_status, build; 96026ad340eSHenning Colliander 961*954fb212SJimmy Assarsson version = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_VERSION_REG); 962c496adafSJimmy Assarsson pcie->nr_channels = min(KVASER_PCIEFD_MAX_CAN_CHANNELS, 963*954fb212SJimmy Assarsson FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_NR_CHAN_MASK, version)); 96426ad340eSHenning Colliander 96526ad340eSHenning Colliander build = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_BUILD_REG); 966*954fb212SJimmy Assarsson dev_dbg(&pcie->pci->dev, "Version %lu.%lu.%lu\n", 967*954fb212SJimmy Assarsson FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_MAJOR_MASK, version), 968*954fb212SJimmy Assarsson FIELD_GET(KVASER_PCIEFD_SYSID_VERSION_MINOR_MASK, version), 969*954fb212SJimmy Assarsson FIELD_GET(KVASER_PCIEFD_SYSID_BUILD_SEQ_MASK, build)); 97026ad340eSHenning Colliander 97126ad340eSHenning Colliander srb_status = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_STAT_REG); 97226ad340eSHenning Colliander if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DMA)) { 97326ad340eSHenning Colliander dev_err(&pcie->pci->dev, 97426ad340eSHenning Colliander "Hardware without DMA is not supported\n"); 97526ad340eSHenning Colliander return -ENODEV; 97626ad340eSHenning Colliander } 97726ad340eSHenning Colliander 978ec44dd57SChrister Beskow pcie->bus_freq = ioread32(pcie->reg_base + 979ec44dd57SChrister Beskow KVASER_PCIEFD_SYSID_BUSFREQ_REG); 98026ad340eSHenning Colliander pcie->freq = ioread32(pcie->reg_base + KVASER_PCIEFD_SYSID_CANFREQ_REG); 98126ad340eSHenning Colliander pcie->freq_to_ticks_div = pcie->freq / 1000000; 98226ad340eSHenning Colliander if (pcie->freq_to_ticks_div == 0) 98326ad340eSHenning Colliander pcie->freq_to_ticks_div = 1; 98426ad340eSHenning Colliander 98526ad340eSHenning Colliander /* Turn off all loopback functionality */ 98626ad340eSHenning Colliander iowrite32(0, pcie->reg_base + KVASER_PCIEFD_LOOP_REG); 987c496adafSJimmy Assarsson return 0; 98826ad340eSHenning Colliander } 98926ad340eSHenning Colliander 99026ad340eSHenning Colliander static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie, 99126ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p, 99226ad340eSHenning Colliander __le32 *data) 99326ad340eSHenning Colliander { 99426ad340eSHenning Colliander struct sk_buff *skb; 99526ad340eSHenning Colliander struct canfd_frame *cf; 99626ad340eSHenning Colliander struct can_priv *priv; 99726ad340eSHenning Colliander struct net_device_stats *stats; 998*954fb212SJimmy Assarsson u8 ch_id = FIELD_GET(KVASER_PCIEFD_PACKET_CHID_MASK, p->header[1]); 99926ad340eSHenning Colliander 100026ad340eSHenning Colliander if (ch_id >= pcie->nr_channels) 100126ad340eSHenning Colliander return -EIO; 100226ad340eSHenning Colliander 100326ad340eSHenning Colliander priv = &pcie->can[ch_id]->can; 100426ad340eSHenning Colliander stats = &priv->dev->stats; 100526ad340eSHenning Colliander 100626ad340eSHenning Colliander if (p->header[1] & KVASER_PCIEFD_RPACKET_FDF) { 100726ad340eSHenning Colliander skb = alloc_canfd_skb(priv->dev, &cf); 100826ad340eSHenning Colliander if (!skb) { 100926ad340eSHenning Colliander stats->rx_dropped++; 101026ad340eSHenning Colliander return -ENOMEM; 101126ad340eSHenning Colliander } 101226ad340eSHenning Colliander 101326ad340eSHenning Colliander if (p->header[1] & KVASER_PCIEFD_RPACKET_BRS) 101426ad340eSHenning Colliander cf->flags |= CANFD_BRS; 101526ad340eSHenning Colliander 101626ad340eSHenning Colliander if (p->header[1] & KVASER_PCIEFD_RPACKET_ESI) 101726ad340eSHenning Colliander cf->flags |= CANFD_ESI; 101826ad340eSHenning Colliander } else { 101926ad340eSHenning Colliander skb = alloc_can_skb(priv->dev, (struct can_frame **)&cf); 102026ad340eSHenning Colliander if (!skb) { 102126ad340eSHenning Colliander stats->rx_dropped++; 102226ad340eSHenning Colliander return -ENOMEM; 102326ad340eSHenning Colliander } 102426ad340eSHenning Colliander } 102526ad340eSHenning Colliander 1026*954fb212SJimmy Assarsson cf->can_id = FIELD_GET(KVASER_PCIEFD_RPACKET_ID_MASK, p->header[0]); 102726ad340eSHenning Colliander if (p->header[0] & KVASER_PCIEFD_RPACKET_IDE) 102826ad340eSHenning Colliander cf->can_id |= CAN_EFF_FLAG; 102926ad340eSHenning Colliander 1030*954fb212SJimmy Assarsson cf->len = can_fd_dlc2len(FIELD_GET(KVASER_PCIEFD_RPACKET_DLC_MASK, p->header[1])); 103126ad340eSHenning Colliander 10328e674ca7SVincent Mailhol if (p->header[0] & KVASER_PCIEFD_RPACKET_RTR) { 103326ad340eSHenning Colliander cf->can_id |= CAN_RTR_FLAG; 10348e674ca7SVincent Mailhol } else { 103526ad340eSHenning Colliander memcpy(cf->data, data, cf->len); 103626ad340eSHenning Colliander 10378e674ca7SVincent Mailhol stats->rx_bytes += cf->len; 10388e674ca7SVincent Mailhol } 10398e674ca7SVincent Mailhol stats->rx_packets++; 10402d55e9f9SJimmy Assarsson kvaser_pciefd_set_skb_timestamp(pcie, skb, p->timestamp); 104126ad340eSHenning Colliander 104226ad340eSHenning Colliander return netif_rx(skb); 104326ad340eSHenning Colliander } 104426ad340eSHenning Colliander 104526ad340eSHenning Colliander static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can, 104626ad340eSHenning Colliander struct can_frame *cf, 104726ad340eSHenning Colliander enum can_state new_state, 104826ad340eSHenning Colliander enum can_state tx_state, 104926ad340eSHenning Colliander enum can_state rx_state) 105026ad340eSHenning Colliander { 105126ad340eSHenning Colliander can_change_state(can->can.dev, cf, tx_state, rx_state); 105226ad340eSHenning Colliander 105326ad340eSHenning Colliander if (new_state == CAN_STATE_BUS_OFF) { 105426ad340eSHenning Colliander struct net_device *ndev = can->can.dev; 105526ad340eSHenning Colliander unsigned long irq_flags; 105626ad340eSHenning Colliander 105726ad340eSHenning Colliander spin_lock_irqsave(&can->lock, irq_flags); 105826ad340eSHenning Colliander netif_stop_queue(can->can.dev); 105926ad340eSHenning Colliander spin_unlock_irqrestore(&can->lock, irq_flags); 106026ad340eSHenning Colliander 106126ad340eSHenning Colliander /* Prevent CAN controller from auto recover from bus off */ 106226ad340eSHenning Colliander if (!can->can.restart_ms) { 106326ad340eSHenning Colliander kvaser_pciefd_start_controller_flush(can); 106426ad340eSHenning Colliander can_bus_off(ndev); 106526ad340eSHenning Colliander } 106626ad340eSHenning Colliander } 106726ad340eSHenning Colliander } 106826ad340eSHenning Colliander 106926ad340eSHenning Colliander static void kvaser_pciefd_packet_to_state(struct kvaser_pciefd_rx_packet *p, 107026ad340eSHenning Colliander struct can_berr_counter *bec, 107126ad340eSHenning Colliander enum can_state *new_state, 107226ad340eSHenning Colliander enum can_state *tx_state, 107326ad340eSHenning Colliander enum can_state *rx_state) 107426ad340eSHenning Colliander { 107526ad340eSHenning Colliander if (p->header[0] & KVASER_PCIEFD_SPACK_BOFF || 107626ad340eSHenning Colliander p->header[0] & KVASER_PCIEFD_SPACK_IRM) 107726ad340eSHenning Colliander *new_state = CAN_STATE_BUS_OFF; 107826ad340eSHenning Colliander else if (bec->txerr >= 255 || bec->rxerr >= 255) 107926ad340eSHenning Colliander *new_state = CAN_STATE_BUS_OFF; 108026ad340eSHenning Colliander else if (p->header[1] & KVASER_PCIEFD_SPACK_EPLR) 108126ad340eSHenning Colliander *new_state = CAN_STATE_ERROR_PASSIVE; 108226ad340eSHenning Colliander else if (bec->txerr >= 128 || bec->rxerr >= 128) 108326ad340eSHenning Colliander *new_state = CAN_STATE_ERROR_PASSIVE; 108426ad340eSHenning Colliander else if (p->header[1] & KVASER_PCIEFD_SPACK_EWLR) 108526ad340eSHenning Colliander *new_state = CAN_STATE_ERROR_WARNING; 108626ad340eSHenning Colliander else if (bec->txerr >= 96 || bec->rxerr >= 96) 108726ad340eSHenning Colliander *new_state = CAN_STATE_ERROR_WARNING; 108826ad340eSHenning Colliander else 108926ad340eSHenning Colliander *new_state = CAN_STATE_ERROR_ACTIVE; 109026ad340eSHenning Colliander 109126ad340eSHenning Colliander *tx_state = bec->txerr >= bec->rxerr ? *new_state : 0; 109226ad340eSHenning Colliander *rx_state = bec->txerr <= bec->rxerr ? *new_state : 0; 109326ad340eSHenning Colliander } 109426ad340eSHenning Colliander 109526ad340eSHenning Colliander static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can, 109626ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p) 109726ad340eSHenning Colliander { 109826ad340eSHenning Colliander struct can_berr_counter bec; 109926ad340eSHenning Colliander enum can_state old_state, new_state, tx_state, rx_state; 110026ad340eSHenning Colliander struct net_device *ndev = can->can.dev; 110126ad340eSHenning Colliander struct sk_buff *skb; 110226ad340eSHenning Colliander struct can_frame *cf = NULL; 110326ad340eSHenning Colliander struct net_device_stats *stats = &ndev->stats; 110426ad340eSHenning Colliander 110526ad340eSHenning Colliander old_state = can->can.state; 110626ad340eSHenning Colliander 1107*954fb212SJimmy Assarsson bec.txerr = FIELD_GET(KVASER_PCIEFD_SPACK_TXERR_MASK, p->header[0]); 1108*954fb212SJimmy Assarsson bec.rxerr = FIELD_GET(KVASER_PCIEFD_SPACK_RXERR_MASK, p->header[0]); 110926ad340eSHenning Colliander 111026ad340eSHenning Colliander kvaser_pciefd_packet_to_state(p, &bec, &new_state, &tx_state, 111126ad340eSHenning Colliander &rx_state); 111226ad340eSHenning Colliander 111326ad340eSHenning Colliander skb = alloc_can_err_skb(ndev, &cf); 111426ad340eSHenning Colliander 111526ad340eSHenning Colliander if (new_state != old_state) { 111626ad340eSHenning Colliander kvaser_pciefd_change_state(can, cf, new_state, tx_state, 111726ad340eSHenning Colliander rx_state); 111826ad340eSHenning Colliander 111926ad340eSHenning Colliander if (old_state == CAN_STATE_BUS_OFF && 112026ad340eSHenning Colliander new_state == CAN_STATE_ERROR_ACTIVE && 112126ad340eSHenning Colliander can->can.restart_ms) { 112226ad340eSHenning Colliander can->can.can_stats.restarts++; 112326ad340eSHenning Colliander if (skb) 112426ad340eSHenning Colliander cf->can_id |= CAN_ERR_RESTARTED; 112526ad340eSHenning Colliander } 112626ad340eSHenning Colliander } 112726ad340eSHenning Colliander 112826ad340eSHenning Colliander can->err_rep_cnt++; 112926ad340eSHenning Colliander can->can.can_stats.bus_error++; 113036aea60fSJimmy Assarsson if (p->header[1] & KVASER_PCIEFD_EPACK_DIR_TX) 113136aea60fSJimmy Assarsson stats->tx_errors++; 113236aea60fSJimmy Assarsson else 113326ad340eSHenning Colliander stats->rx_errors++; 113426ad340eSHenning Colliander 113526ad340eSHenning Colliander can->bec.txerr = bec.txerr; 113626ad340eSHenning Colliander can->bec.rxerr = bec.rxerr; 113726ad340eSHenning Colliander 113826ad340eSHenning Colliander if (!skb) { 113926ad340eSHenning Colliander stats->rx_dropped++; 114026ad340eSHenning Colliander return -ENOMEM; 114126ad340eSHenning Colliander } 114226ad340eSHenning Colliander 11432d55e9f9SJimmy Assarsson kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp); 11443e5c291cSVincent Mailhol cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT; 114526ad340eSHenning Colliander 114626ad340eSHenning Colliander cf->data[6] = bec.txerr; 114726ad340eSHenning Colliander cf->data[7] = bec.rxerr; 114826ad340eSHenning Colliander 114926ad340eSHenning Colliander netif_rx(skb); 115026ad340eSHenning Colliander return 0; 115126ad340eSHenning Colliander } 115226ad340eSHenning Colliander 115326ad340eSHenning Colliander static int kvaser_pciefd_handle_error_packet(struct kvaser_pciefd *pcie, 115426ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p) 115526ad340eSHenning Colliander { 115626ad340eSHenning Colliander struct kvaser_pciefd_can *can; 1157*954fb212SJimmy Assarsson u8 ch_id = FIELD_GET(KVASER_PCIEFD_PACKET_CHID_MASK, p->header[1]); 115826ad340eSHenning Colliander 115926ad340eSHenning Colliander if (ch_id >= pcie->nr_channels) 116026ad340eSHenning Colliander return -EIO; 116126ad340eSHenning Colliander 116226ad340eSHenning Colliander can = pcie->can[ch_id]; 116326ad340eSHenning Colliander 116426ad340eSHenning Colliander kvaser_pciefd_rx_error_frame(can, p); 116526ad340eSHenning Colliander if (can->err_rep_cnt >= KVASER_PCIEFD_MAX_ERR_REP) 116626ad340eSHenning Colliander /* Do not report more errors, until bec_poll_timer expires */ 116726ad340eSHenning Colliander kvaser_pciefd_disable_err_gen(can); 116826ad340eSHenning Colliander /* Start polling the error counters */ 116926ad340eSHenning Colliander mod_timer(&can->bec_poll_timer, KVASER_PCIEFD_BEC_POLL_FREQ); 117026ad340eSHenning Colliander return 0; 117126ad340eSHenning Colliander } 117226ad340eSHenning Colliander 117326ad340eSHenning Colliander static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can, 117426ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p) 117526ad340eSHenning Colliander { 117626ad340eSHenning Colliander struct can_berr_counter bec; 117726ad340eSHenning Colliander enum can_state old_state, new_state, tx_state, rx_state; 117826ad340eSHenning Colliander 117926ad340eSHenning Colliander old_state = can->can.state; 118026ad340eSHenning Colliander 1181*954fb212SJimmy Assarsson bec.txerr = FIELD_GET(KVASER_PCIEFD_SPACK_TXERR_MASK, p->header[0]); 1182*954fb212SJimmy Assarsson bec.rxerr = FIELD_GET(KVASER_PCIEFD_SPACK_RXERR_MASK, p->header[0]); 118326ad340eSHenning Colliander 118426ad340eSHenning Colliander kvaser_pciefd_packet_to_state(p, &bec, &new_state, &tx_state, 118526ad340eSHenning Colliander &rx_state); 118626ad340eSHenning Colliander 118726ad340eSHenning Colliander if (new_state != old_state) { 118826ad340eSHenning Colliander struct net_device *ndev = can->can.dev; 118926ad340eSHenning Colliander struct sk_buff *skb; 119026ad340eSHenning Colliander struct can_frame *cf; 119126ad340eSHenning Colliander 119226ad340eSHenning Colliander skb = alloc_can_err_skb(ndev, &cf); 119326ad340eSHenning Colliander if (!skb) { 119426ad340eSHenning Colliander struct net_device_stats *stats = &ndev->stats; 119526ad340eSHenning Colliander 119626ad340eSHenning Colliander stats->rx_dropped++; 119726ad340eSHenning Colliander return -ENOMEM; 119826ad340eSHenning Colliander } 119926ad340eSHenning Colliander 120026ad340eSHenning Colliander kvaser_pciefd_change_state(can, cf, new_state, tx_state, 120126ad340eSHenning Colliander rx_state); 120226ad340eSHenning Colliander 120326ad340eSHenning Colliander if (old_state == CAN_STATE_BUS_OFF && 120426ad340eSHenning Colliander new_state == CAN_STATE_ERROR_ACTIVE && 120526ad340eSHenning Colliander can->can.restart_ms) { 120626ad340eSHenning Colliander can->can.can_stats.restarts++; 120726ad340eSHenning Colliander cf->can_id |= CAN_ERR_RESTARTED; 120826ad340eSHenning Colliander } 120926ad340eSHenning Colliander 12102d55e9f9SJimmy Assarsson kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp); 121126ad340eSHenning Colliander 121226ad340eSHenning Colliander cf->data[6] = bec.txerr; 121326ad340eSHenning Colliander cf->data[7] = bec.rxerr; 121426ad340eSHenning Colliander 121526ad340eSHenning Colliander netif_rx(skb); 121626ad340eSHenning Colliander } 121726ad340eSHenning Colliander can->bec.txerr = bec.txerr; 121826ad340eSHenning Colliander can->bec.rxerr = bec.rxerr; 121926ad340eSHenning Colliander /* Check if we need to poll the error counters */ 122026ad340eSHenning Colliander if (bec.txerr || bec.rxerr) 122126ad340eSHenning Colliander mod_timer(&can->bec_poll_timer, KVASER_PCIEFD_BEC_POLL_FREQ); 122226ad340eSHenning Colliander 122326ad340eSHenning Colliander return 0; 122426ad340eSHenning Colliander } 122526ad340eSHenning Colliander 122626ad340eSHenning Colliander static int kvaser_pciefd_handle_status_packet(struct kvaser_pciefd *pcie, 122726ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p) 122826ad340eSHenning Colliander { 122926ad340eSHenning Colliander struct kvaser_pciefd_can *can; 123026ad340eSHenning Colliander u8 cmdseq; 123126ad340eSHenning Colliander u32 status; 1232*954fb212SJimmy Assarsson u8 ch_id = FIELD_GET(KVASER_PCIEFD_PACKET_CHID_MASK, p->header[1]); 123326ad340eSHenning Colliander 123426ad340eSHenning Colliander if (ch_id >= pcie->nr_channels) 123526ad340eSHenning Colliander return -EIO; 123626ad340eSHenning Colliander 123726ad340eSHenning Colliander can = pcie->can[ch_id]; 123826ad340eSHenning Colliander 123926ad340eSHenning Colliander status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG); 1240*954fb212SJimmy Assarsson cmdseq = FIELD_GET(KVASER_PCIEFD_KCAN_STAT_SEQNO_MASK, status); 124126ad340eSHenning Colliander 124226ad340eSHenning Colliander /* Reset done, start abort and flush */ 124326ad340eSHenning Colliander if (p->header[0] & KVASER_PCIEFD_SPACK_IRM && 124426ad340eSHenning Colliander p->header[0] & KVASER_PCIEFD_SPACK_RMCD && 124526ad340eSHenning Colliander p->header[1] & KVASER_PCIEFD_SPACK_AUTO && 1246*954fb212SJimmy Assarsson cmdseq == FIELD_GET(KVASER_PCIEFD_PACKET_SEQ_MASK, p->header[1]) && 124726ad340eSHenning Colliander status & KVASER_PCIEFD_KCAN_STAT_IDLE) { 124826ad340eSHenning Colliander u32 cmd; 124926ad340eSHenning Colliander 125026ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD, 125126ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); 125226ad340eSHenning Colliander cmd = KVASER_PCIEFD_KCAN_CMD_AT; 1253*954fb212SJimmy Assarsson cmd |= FIELD_PREP(KVASER_PCIEFD_KCAN_CMD_SEQ_MASK, ++can->cmd_seq); 125426ad340eSHenning Colliander iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG); 125526ad340eSHenning Colliander } else if (p->header[0] & KVASER_PCIEFD_SPACK_IDET && 125626ad340eSHenning Colliander p->header[0] & KVASER_PCIEFD_SPACK_IRM && 1257*954fb212SJimmy Assarsson cmdseq == FIELD_GET(KVASER_PCIEFD_PACKET_SEQ_MASK, p->header[1]) && 125826ad340eSHenning Colliander status & KVASER_PCIEFD_KCAN_STAT_IDLE) { 125926ad340eSHenning Colliander /* Reset detected, send end of flush if no packet are in FIFO */ 1260*954fb212SJimmy Assarsson u8 count = FIELD_GET(KVASER_PCIEFD_KCAN_TX_NR_PACKETS_CURRENT_MASK, 1261*954fb212SJimmy Assarsson ioread32(can->reg_base + KVASER_PCIEFD_KCAN_TX_NPACKETS_REG)); 126226ad340eSHenning Colliander 126326ad340eSHenning Colliander if (!count) 1264*954fb212SJimmy Assarsson iowrite32(FIELD_PREP(KVASER_PCIEFD_KCAN_CTRL_TYPE_MASK, 1265*954fb212SJimmy Assarsson KVASER_PCIEFD_KCAN_CTRL_TYPE_EFLUSH), 126626ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_CTRL_REG); 126726ad340eSHenning Colliander } else if (!(p->header[1] & KVASER_PCIEFD_SPACK_AUTO) && 1268*954fb212SJimmy Assarsson cmdseq == FIELD_GET(KVASER_PCIEFD_PACKET_SEQ_MASK, p->header[1])) { 126926ad340eSHenning Colliander /* Response to status request received */ 127026ad340eSHenning Colliander kvaser_pciefd_handle_status_resp(can, p); 127126ad340eSHenning Colliander if (can->can.state != CAN_STATE_BUS_OFF && 127226ad340eSHenning Colliander can->can.state != CAN_STATE_ERROR_ACTIVE) { 127326ad340eSHenning Colliander mod_timer(&can->bec_poll_timer, 127426ad340eSHenning Colliander KVASER_PCIEFD_BEC_POLL_FREQ); 127526ad340eSHenning Colliander } 127626ad340eSHenning Colliander } else if (p->header[0] & KVASER_PCIEFD_SPACK_RMCD && 127726ad340eSHenning Colliander !(status & KVASER_PCIEFD_KCAN_STAT_BUS_OFF_MSK)) { 127826ad340eSHenning Colliander /* Reset to bus on detected */ 127926ad340eSHenning Colliander if (!completion_done(&can->start_comp)) 128026ad340eSHenning Colliander complete(&can->start_comp); 128126ad340eSHenning Colliander } 128226ad340eSHenning Colliander 128326ad340eSHenning Colliander return 0; 128426ad340eSHenning Colliander } 128526ad340eSHenning Colliander 128626ad340eSHenning Colliander static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can, 128726ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p) 128826ad340eSHenning Colliander { 128926ad340eSHenning Colliander struct sk_buff *skb; 129026ad340eSHenning Colliander struct net_device_stats *stats = &can->can.dev->stats; 129126ad340eSHenning Colliander struct can_frame *cf; 129226ad340eSHenning Colliander 129326ad340eSHenning Colliander skb = alloc_can_err_skb(can->can.dev, &cf); 129426ad340eSHenning Colliander 129526ad340eSHenning Colliander stats->tx_errors++; 129626ad340eSHenning Colliander if (p->header[0] & KVASER_PCIEFD_APACKET_ABL) { 129726ad340eSHenning Colliander if (skb) 129826ad340eSHenning Colliander cf->can_id |= CAN_ERR_LOSTARB; 129926ad340eSHenning Colliander can->can.can_stats.arbitration_lost++; 130026ad340eSHenning Colliander } else if (skb) { 130126ad340eSHenning Colliander cf->can_id |= CAN_ERR_ACK; 130226ad340eSHenning Colliander } 130326ad340eSHenning Colliander 130426ad340eSHenning Colliander if (skb) { 130526ad340eSHenning Colliander cf->can_id |= CAN_ERR_BUSERROR; 1306ec681b91SJimmy Assarsson kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp); 130726ad340eSHenning Colliander netif_rx(skb); 130826ad340eSHenning Colliander } else { 130926ad340eSHenning Colliander stats->rx_dropped++; 131026ad340eSHenning Colliander netdev_warn(can->can.dev, "No memory left for err_skb\n"); 131126ad340eSHenning Colliander } 131226ad340eSHenning Colliander } 131326ad340eSHenning Colliander 131426ad340eSHenning Colliander static int kvaser_pciefd_handle_ack_packet(struct kvaser_pciefd *pcie, 131526ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p) 131626ad340eSHenning Colliander { 131726ad340eSHenning Colliander struct kvaser_pciefd_can *can; 131826ad340eSHenning Colliander bool one_shot_fail = false; 1319*954fb212SJimmy Assarsson u8 ch_id = FIELD_GET(KVASER_PCIEFD_PACKET_CHID_MASK, p->header[1]); 132026ad340eSHenning Colliander 132126ad340eSHenning Colliander if (ch_id >= pcie->nr_channels) 132226ad340eSHenning Colliander return -EIO; 132326ad340eSHenning Colliander 132426ad340eSHenning Colliander can = pcie->can[ch_id]; 132526ad340eSHenning Colliander /* Ignore control packet ACK */ 132626ad340eSHenning Colliander if (p->header[0] & KVASER_PCIEFD_APACKET_CT) 132726ad340eSHenning Colliander return 0; 132826ad340eSHenning Colliander 132926ad340eSHenning Colliander if (p->header[0] & KVASER_PCIEFD_APACKET_NACK) { 133026ad340eSHenning Colliander kvaser_pciefd_handle_nack_packet(can, p); 133126ad340eSHenning Colliander one_shot_fail = true; 133226ad340eSHenning Colliander } 133326ad340eSHenning Colliander 133426ad340eSHenning Colliander if (p->header[0] & KVASER_PCIEFD_APACKET_FLU) { 133526ad340eSHenning Colliander netdev_dbg(can->can.dev, "Packet was flushed\n"); 133626ad340eSHenning Colliander } else { 1337*954fb212SJimmy Assarsson int echo_idx = FIELD_GET(KVASER_PCIEFD_PACKET_SEQ_MASK, p->header[0]); 1338ec681b91SJimmy Assarsson int dlc; 1339ec681b91SJimmy Assarsson u8 count; 1340ec681b91SJimmy Assarsson struct sk_buff *skb; 1341ec681b91SJimmy Assarsson 1342ec681b91SJimmy Assarsson skb = can->can.echo_skb[echo_idx]; 1343ec681b91SJimmy Assarsson if (skb) 1344ec681b91SJimmy Assarsson kvaser_pciefd_set_skb_timestamp(pcie, skb, p->timestamp); 1345ec681b91SJimmy Assarsson dlc = can_get_echo_skb(can->can.dev, echo_idx, NULL); 1346*954fb212SJimmy Assarsson count = FIELD_GET(KVASER_PCIEFD_KCAN_TX_NR_PACKETS_CURRENT_MASK, 1347*954fb212SJimmy Assarsson ioread32(can->reg_base + KVASER_PCIEFD_KCAN_TX_NPACKETS_REG)); 134826ad340eSHenning Colliander 134926ad340eSHenning Colliander if (count < KVASER_PCIEFD_CAN_TX_MAX_COUNT && 135026ad340eSHenning Colliander netif_queue_stopped(can->can.dev)) 135126ad340eSHenning Colliander netif_wake_queue(can->can.dev); 135226ad340eSHenning Colliander 135326ad340eSHenning Colliander if (!one_shot_fail) { 135426ad340eSHenning Colliander struct net_device_stats *stats = &can->can.dev->stats; 135526ad340eSHenning Colliander 135626ad340eSHenning Colliander stats->tx_bytes += dlc; 135726ad340eSHenning Colliander stats->tx_packets++; 135826ad340eSHenning Colliander } 135926ad340eSHenning Colliander } 136026ad340eSHenning Colliander 136126ad340eSHenning Colliander return 0; 136226ad340eSHenning Colliander } 136326ad340eSHenning Colliander 136426ad340eSHenning Colliander static int kvaser_pciefd_handle_eflush_packet(struct kvaser_pciefd *pcie, 136526ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p) 136626ad340eSHenning Colliander { 136726ad340eSHenning Colliander struct kvaser_pciefd_can *can; 1368*954fb212SJimmy Assarsson u8 ch_id = FIELD_GET(KVASER_PCIEFD_PACKET_CHID_MASK, p->header[1]); 136926ad340eSHenning Colliander 137026ad340eSHenning Colliander if (ch_id >= pcie->nr_channels) 137126ad340eSHenning Colliander return -EIO; 137226ad340eSHenning Colliander 137326ad340eSHenning Colliander can = pcie->can[ch_id]; 137426ad340eSHenning Colliander 137526ad340eSHenning Colliander if (!completion_done(&can->flush_comp)) 137626ad340eSHenning Colliander complete(&can->flush_comp); 137726ad340eSHenning Colliander 137826ad340eSHenning Colliander return 0; 137926ad340eSHenning Colliander } 138026ad340eSHenning Colliander 138126ad340eSHenning Colliander static int kvaser_pciefd_read_packet(struct kvaser_pciefd *pcie, int *start_pos, 138226ad340eSHenning Colliander int dma_buf) 138326ad340eSHenning Colliander { 138426ad340eSHenning Colliander __le32 *buffer = pcie->dma_data[dma_buf]; 138526ad340eSHenning Colliander __le64 timestamp; 138626ad340eSHenning Colliander struct kvaser_pciefd_rx_packet packet; 138726ad340eSHenning Colliander struct kvaser_pciefd_rx_packet *p = &packet; 138826ad340eSHenning Colliander u8 type; 138926ad340eSHenning Colliander int pos = *start_pos; 139026ad340eSHenning Colliander int size; 139126ad340eSHenning Colliander int ret = 0; 139226ad340eSHenning Colliander 139326ad340eSHenning Colliander size = le32_to_cpu(buffer[pos++]); 139426ad340eSHenning Colliander if (!size) { 139526ad340eSHenning Colliander *start_pos = 0; 139626ad340eSHenning Colliander return 0; 139726ad340eSHenning Colliander } 139826ad340eSHenning Colliander 139926ad340eSHenning Colliander p->header[0] = le32_to_cpu(buffer[pos++]); 140026ad340eSHenning Colliander p->header[1] = le32_to_cpu(buffer[pos++]); 140126ad340eSHenning Colliander 140226ad340eSHenning Colliander /* Read 64-bit timestamp */ 140326ad340eSHenning Colliander memcpy(×tamp, &buffer[pos], sizeof(__le64)); 140426ad340eSHenning Colliander pos += 2; 140526ad340eSHenning Colliander p->timestamp = le64_to_cpu(timestamp); 140626ad340eSHenning Colliander 1407*954fb212SJimmy Assarsson type = FIELD_GET(KVASER_PCIEFD_PACKET_TYPE_MASK, p->header[1]); 140826ad340eSHenning Colliander switch (type) { 140926ad340eSHenning Colliander case KVASER_PCIEFD_PACK_TYPE_DATA: 141026ad340eSHenning Colliander ret = kvaser_pciefd_handle_data_packet(pcie, p, &buffer[pos]); 141126ad340eSHenning Colliander if (!(p->header[0] & KVASER_PCIEFD_RPACKET_RTR)) { 141226ad340eSHenning Colliander u8 data_len; 141326ad340eSHenning Colliander 1414*954fb212SJimmy Assarsson data_len = can_fd_dlc2len(FIELD_GET(KVASER_PCIEFD_RPACKET_DLC_MASK, 1415*954fb212SJimmy Assarsson p->header[1])); 141626ad340eSHenning Colliander pos += DIV_ROUND_UP(data_len, 4); 141726ad340eSHenning Colliander } 141826ad340eSHenning Colliander break; 141926ad340eSHenning Colliander 142026ad340eSHenning Colliander case KVASER_PCIEFD_PACK_TYPE_ACK: 142126ad340eSHenning Colliander ret = kvaser_pciefd_handle_ack_packet(pcie, p); 142226ad340eSHenning Colliander break; 142326ad340eSHenning Colliander 142426ad340eSHenning Colliander case KVASER_PCIEFD_PACK_TYPE_STATUS: 142526ad340eSHenning Colliander ret = kvaser_pciefd_handle_status_packet(pcie, p); 142626ad340eSHenning Colliander break; 142726ad340eSHenning Colliander 142826ad340eSHenning Colliander case KVASER_PCIEFD_PACK_TYPE_ERROR: 142926ad340eSHenning Colliander ret = kvaser_pciefd_handle_error_packet(pcie, p); 143026ad340eSHenning Colliander break; 143126ad340eSHenning Colliander 143226ad340eSHenning Colliander case KVASER_PCIEFD_PACK_TYPE_EFLUSH_ACK: 143326ad340eSHenning Colliander ret = kvaser_pciefd_handle_eflush_packet(pcie, p); 143426ad340eSHenning Colliander break; 143526ad340eSHenning Colliander 143626ad340eSHenning Colliander case KVASER_PCIEFD_PACK_TYPE_ACK_DATA: 143726ad340eSHenning Colliander case KVASER_PCIEFD_PACK_TYPE_BUS_LOAD: 143876c66ddfSJimmy Assarsson case KVASER_PCIEFD_PACK_TYPE_EFRAME_ACK: 143926ad340eSHenning Colliander case KVASER_PCIEFD_PACK_TYPE_TXRQ: 144026ad340eSHenning Colliander dev_info(&pcie->pci->dev, 144126ad340eSHenning Colliander "Received unexpected packet type 0x%08X\n", type); 144226ad340eSHenning Colliander break; 144326ad340eSHenning Colliander 144426ad340eSHenning Colliander default: 144526ad340eSHenning Colliander dev_err(&pcie->pci->dev, "Unknown packet type 0x%08X\n", type); 144626ad340eSHenning Colliander ret = -EIO; 144726ad340eSHenning Colliander break; 144826ad340eSHenning Colliander } 144926ad340eSHenning Colliander 145026ad340eSHenning Colliander if (ret) 145126ad340eSHenning Colliander return ret; 145226ad340eSHenning Colliander 145326ad340eSHenning Colliander /* Position does not point to the end of the package, 145426ad340eSHenning Colliander * corrupted packet size? 145526ad340eSHenning Colliander */ 145626ad340eSHenning Colliander if ((*start_pos + size) != pos) 145726ad340eSHenning Colliander return -EIO; 145826ad340eSHenning Colliander 145926ad340eSHenning Colliander /* Point to the next packet header, if any */ 146026ad340eSHenning Colliander *start_pos = pos; 146126ad340eSHenning Colliander 146226ad340eSHenning Colliander return ret; 146326ad340eSHenning Colliander } 146426ad340eSHenning Colliander 146526ad340eSHenning Colliander static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf) 146626ad340eSHenning Colliander { 146726ad340eSHenning Colliander int pos = 0; 146826ad340eSHenning Colliander int res = 0; 146926ad340eSHenning Colliander 147026ad340eSHenning Colliander do { 147126ad340eSHenning Colliander res = kvaser_pciefd_read_packet(pcie, &pos, dma_buf); 147226ad340eSHenning Colliander } while (!res && pos > 0 && pos < KVASER_PCIEFD_DMA_SIZE); 147326ad340eSHenning Colliander 147426ad340eSHenning Colliander return res; 147526ad340eSHenning Colliander } 147626ad340eSHenning Colliander 147724aecf55SJimmy Assarsson static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie) 147826ad340eSHenning Colliander { 147926ad340eSHenning Colliander u32 irq; 148026ad340eSHenning Colliander 148126ad340eSHenning Colliander irq = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG); 148226ad340eSHenning Colliander if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) { 148326ad340eSHenning Colliander kvaser_pciefd_read_buffer(pcie, 0); 148426ad340eSHenning Colliander /* Reset DMA buffer 0 */ 148526ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0, 148626ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG); 148726ad340eSHenning Colliander } 148826ad340eSHenning Colliander 148926ad340eSHenning Colliander if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) { 149026ad340eSHenning Colliander kvaser_pciefd_read_buffer(pcie, 1); 149126ad340eSHenning Colliander /* Reset DMA buffer 1 */ 149226ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1, 149326ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG); 149426ad340eSHenning Colliander } 149526ad340eSHenning Colliander 149626ad340eSHenning Colliander if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 || 149726ad340eSHenning Colliander irq & KVASER_PCIEFD_SRB_IRQ_DOF1 || 149826ad340eSHenning Colliander irq & KVASER_PCIEFD_SRB_IRQ_DUF0 || 149926ad340eSHenning Colliander irq & KVASER_PCIEFD_SRB_IRQ_DUF1) 150026ad340eSHenning Colliander dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq); 150126ad340eSHenning Colliander 150226ad340eSHenning Colliander iowrite32(irq, pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG); 150326ad340eSHenning Colliander } 150426ad340eSHenning Colliander 150524aecf55SJimmy Assarsson static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can) 150626ad340eSHenning Colliander { 150726ad340eSHenning Colliander u32 irq = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); 150826ad340eSHenning Colliander 150926ad340eSHenning Colliander if (irq & KVASER_PCIEFD_KCAN_IRQ_TOF) 151026ad340eSHenning Colliander netdev_err(can->can.dev, "Tx FIFO overflow\n"); 151126ad340eSHenning Colliander 151226ad340eSHenning Colliander if (irq & KVASER_PCIEFD_KCAN_IRQ_BPP) 151326ad340eSHenning Colliander netdev_err(can->can.dev, 151426ad340eSHenning Colliander "Fail to change bittiming, when not in reset mode\n"); 151526ad340eSHenning Colliander 151626ad340eSHenning Colliander if (irq & KVASER_PCIEFD_KCAN_IRQ_FDIC) 151726ad340eSHenning Colliander netdev_err(can->can.dev, "CAN FD frame in CAN mode\n"); 151826ad340eSHenning Colliander 151926ad340eSHenning Colliander if (irq & KVASER_PCIEFD_KCAN_IRQ_ROF) 152026ad340eSHenning Colliander netdev_err(can->can.dev, "Rx FIFO overflow\n"); 152126ad340eSHenning Colliander 152226ad340eSHenning Colliander iowrite32(irq, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); 152326ad340eSHenning Colliander } 152426ad340eSHenning Colliander 152526ad340eSHenning Colliander static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev) 152626ad340eSHenning Colliander { 152726ad340eSHenning Colliander struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev; 152826ad340eSHenning Colliander u32 board_irq; 152926ad340eSHenning Colliander int i; 153026ad340eSHenning Colliander 153126ad340eSHenning Colliander board_irq = ioread32(pcie->reg_base + KVASER_PCIEFD_IRQ_REG); 153226ad340eSHenning Colliander 1533*954fb212SJimmy Assarsson if (!(board_irq & KVASER_PCIEFD_IRQ_ALL_MASK)) 153426ad340eSHenning Colliander return IRQ_NONE; 153526ad340eSHenning Colliander 153626ad340eSHenning Colliander if (board_irq & KVASER_PCIEFD_IRQ_SRB) 153726ad340eSHenning Colliander kvaser_pciefd_receive_irq(pcie); 153826ad340eSHenning Colliander 153926ad340eSHenning Colliander for (i = 0; i < pcie->nr_channels; i++) { 154026ad340eSHenning Colliander if (!pcie->can[i]) { 154126ad340eSHenning Colliander dev_err(&pcie->pci->dev, 154226ad340eSHenning Colliander "IRQ mask points to unallocated controller\n"); 154326ad340eSHenning Colliander break; 154426ad340eSHenning Colliander } 154526ad340eSHenning Colliander 154626ad340eSHenning Colliander /* Check that mask matches channel (i) IRQ mask */ 154726ad340eSHenning Colliander if (board_irq & (1 << i)) 154826ad340eSHenning Colliander kvaser_pciefd_transmit_irq(pcie->can[i]); 154926ad340eSHenning Colliander } 155026ad340eSHenning Colliander 155126ad340eSHenning Colliander return IRQ_HANDLED; 155226ad340eSHenning Colliander } 155326ad340eSHenning Colliander 155426ad340eSHenning Colliander static void kvaser_pciefd_teardown_can_ctrls(struct kvaser_pciefd *pcie) 155526ad340eSHenning Colliander { 155626ad340eSHenning Colliander int i; 155726ad340eSHenning Colliander struct kvaser_pciefd_can *can; 155826ad340eSHenning Colliander 155926ad340eSHenning Colliander for (i = 0; i < pcie->nr_channels; i++) { 156026ad340eSHenning Colliander can = pcie->can[i]; 156126ad340eSHenning Colliander if (can) { 156226ad340eSHenning Colliander iowrite32(0, 156326ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 156426ad340eSHenning Colliander kvaser_pciefd_pwm_stop(can); 156526ad340eSHenning Colliander free_candev(can->can.dev); 156626ad340eSHenning Colliander } 156726ad340eSHenning Colliander } 156826ad340eSHenning Colliander } 156926ad340eSHenning Colliander 157026ad340eSHenning Colliander static int kvaser_pciefd_probe(struct pci_dev *pdev, 157126ad340eSHenning Colliander const struct pci_device_id *id) 157226ad340eSHenning Colliander { 157326ad340eSHenning Colliander int err; 157426ad340eSHenning Colliander struct kvaser_pciefd *pcie; 157526ad340eSHenning Colliander 157626ad340eSHenning Colliander pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); 157726ad340eSHenning Colliander if (!pcie) 157826ad340eSHenning Colliander return -ENOMEM; 157926ad340eSHenning Colliander 158026ad340eSHenning Colliander pci_set_drvdata(pdev, pcie); 158126ad340eSHenning Colliander pcie->pci = pdev; 158226ad340eSHenning Colliander 158326ad340eSHenning Colliander err = pci_enable_device(pdev); 158426ad340eSHenning Colliander if (err) 158526ad340eSHenning Colliander return err; 158626ad340eSHenning Colliander 158726ad340eSHenning Colliander err = pci_request_regions(pdev, KVASER_PCIEFD_DRV_NAME); 158826ad340eSHenning Colliander if (err) 158926ad340eSHenning Colliander goto err_disable_pci; 159026ad340eSHenning Colliander 159126ad340eSHenning Colliander pcie->reg_base = pci_iomap(pdev, 0, 0); 159226ad340eSHenning Colliander if (!pcie->reg_base) { 159326ad340eSHenning Colliander err = -ENOMEM; 159426ad340eSHenning Colliander goto err_release_regions; 159526ad340eSHenning Colliander } 159626ad340eSHenning Colliander 159726ad340eSHenning Colliander err = kvaser_pciefd_setup_board(pcie); 159826ad340eSHenning Colliander if (err) 159926ad340eSHenning Colliander goto err_pci_iounmap; 160026ad340eSHenning Colliander 160126ad340eSHenning Colliander err = kvaser_pciefd_setup_dma(pcie); 160226ad340eSHenning Colliander if (err) 160326ad340eSHenning Colliander goto err_pci_iounmap; 160426ad340eSHenning Colliander 160526ad340eSHenning Colliander pci_set_master(pdev); 160626ad340eSHenning Colliander 160726ad340eSHenning Colliander err = kvaser_pciefd_setup_can_ctrls(pcie); 160826ad340eSHenning Colliander if (err) 160926ad340eSHenning Colliander goto err_teardown_can_ctrls; 161026ad340eSHenning Colliander 161184762d8dSJimmy Assarsson err = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler, 161284762d8dSJimmy Assarsson IRQF_SHARED, KVASER_PCIEFD_DRV_NAME, pcie); 161384762d8dSJimmy Assarsson if (err) 161484762d8dSJimmy Assarsson goto err_teardown_can_ctrls; 161584762d8dSJimmy Assarsson 161626ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1, 161726ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG); 161826ad340eSHenning Colliander 161926ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1 | 162026ad340eSHenning Colliander KVASER_PCIEFD_SRB_IRQ_DOF0 | KVASER_PCIEFD_SRB_IRQ_DOF1 | 162126ad340eSHenning Colliander KVASER_PCIEFD_SRB_IRQ_DUF0 | KVASER_PCIEFD_SRB_IRQ_DUF1, 162226ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_SRB_IEN_REG); 162326ad340eSHenning Colliander 16247c921556SJimmy Assarsson /* Enable PCI interrupts */ 1625*954fb212SJimmy Assarsson iowrite32(KVASER_PCIEFD_IRQ_ALL_MASK, 162626ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_IEN_REG); 162726ad340eSHenning Colliander 162826ad340eSHenning Colliander /* Ready the DMA buffers */ 162926ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0, 163026ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG); 163126ad340eSHenning Colliander iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1, 163226ad340eSHenning Colliander pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG); 163326ad340eSHenning Colliander 163426ad340eSHenning Colliander err = kvaser_pciefd_reg_candev(pcie); 163526ad340eSHenning Colliander if (err) 163626ad340eSHenning Colliander goto err_free_irq; 163726ad340eSHenning Colliander 163826ad340eSHenning Colliander return 0; 163926ad340eSHenning Colliander 164026ad340eSHenning Colliander err_free_irq: 164111164bc3SJimmy Assarsson /* Disable PCI interrupts */ 164211164bc3SJimmy Assarsson iowrite32(0, pcie->reg_base + KVASER_PCIEFD_IEN_REG); 164326ad340eSHenning Colliander free_irq(pcie->pci->irq, pcie); 164426ad340eSHenning Colliander 164526ad340eSHenning Colliander err_teardown_can_ctrls: 164626ad340eSHenning Colliander kvaser_pciefd_teardown_can_ctrls(pcie); 164726ad340eSHenning Colliander iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG); 164826ad340eSHenning Colliander pci_clear_master(pdev); 164926ad340eSHenning Colliander 165026ad340eSHenning Colliander err_pci_iounmap: 165126ad340eSHenning Colliander pci_iounmap(pdev, pcie->reg_base); 165226ad340eSHenning Colliander 165326ad340eSHenning Colliander err_release_regions: 165426ad340eSHenning Colliander pci_release_regions(pdev); 165526ad340eSHenning Colliander 165626ad340eSHenning Colliander err_disable_pci: 165726ad340eSHenning Colliander pci_disable_device(pdev); 165826ad340eSHenning Colliander 165926ad340eSHenning Colliander return err; 166026ad340eSHenning Colliander } 166126ad340eSHenning Colliander 166226ad340eSHenning Colliander static void kvaser_pciefd_remove_all_ctrls(struct kvaser_pciefd *pcie) 166326ad340eSHenning Colliander { 166426ad340eSHenning Colliander struct kvaser_pciefd_can *can; 166526ad340eSHenning Colliander int i; 166626ad340eSHenning Colliander 166726ad340eSHenning Colliander for (i = 0; i < pcie->nr_channels; i++) { 166826ad340eSHenning Colliander can = pcie->can[i]; 166926ad340eSHenning Colliander if (can) { 167026ad340eSHenning Colliander iowrite32(0, 167126ad340eSHenning Colliander can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); 167226ad340eSHenning Colliander unregister_candev(can->can.dev); 167326ad340eSHenning Colliander del_timer(&can->bec_poll_timer); 167426ad340eSHenning Colliander kvaser_pciefd_pwm_stop(can); 167526ad340eSHenning Colliander free_candev(can->can.dev); 167626ad340eSHenning Colliander } 167726ad340eSHenning Colliander } 167826ad340eSHenning Colliander } 167926ad340eSHenning Colliander 168026ad340eSHenning Colliander static void kvaser_pciefd_remove(struct pci_dev *pdev) 168126ad340eSHenning Colliander { 168226ad340eSHenning Colliander struct kvaser_pciefd *pcie = pci_get_drvdata(pdev); 168326ad340eSHenning Colliander 168426ad340eSHenning Colliander kvaser_pciefd_remove_all_ctrls(pcie); 168526ad340eSHenning Colliander 16867c921556SJimmy Assarsson /* Disable interrupts */ 168726ad340eSHenning Colliander iowrite32(0, pcie->reg_base + KVASER_PCIEFD_SRB_CTRL_REG); 168826ad340eSHenning Colliander iowrite32(0, pcie->reg_base + KVASER_PCIEFD_IEN_REG); 168926ad340eSHenning Colliander 169026ad340eSHenning Colliander free_irq(pcie->pci->irq, pcie); 169126ad340eSHenning Colliander 169226ad340eSHenning Colliander pci_iounmap(pdev, pcie->reg_base); 169326ad340eSHenning Colliander pci_release_regions(pdev); 169426ad340eSHenning Colliander pci_disable_device(pdev); 169526ad340eSHenning Colliander } 169626ad340eSHenning Colliander 169726ad340eSHenning Colliander static struct pci_driver kvaser_pciefd = { 169826ad340eSHenning Colliander .name = KVASER_PCIEFD_DRV_NAME, 169926ad340eSHenning Colliander .id_table = kvaser_pciefd_id_table, 170026ad340eSHenning Colliander .probe = kvaser_pciefd_probe, 170126ad340eSHenning Colliander .remove = kvaser_pciefd_remove, 170226ad340eSHenning Colliander }; 170326ad340eSHenning Colliander 170426ad340eSHenning Colliander module_pci_driver(kvaser_pciefd) 1705