516 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (C) 2015 - 2016 Thomas Körper, esd electronic system design gmbh3 * Copyright (C) 2017 - 2023 Stefan Mätje, esd electronics gmbh4 */5 6#include <linux/can/dev.h>7#include <linux/can.h>8#include <linux/can/netlink.h>9#include <linux/delay.h>10#include <linux/dma-mapping.h>11#include <linux/ethtool.h>12#include <linux/interrupt.h>13#include <linux/io.h>14#include <linux/kernel.h>15#include <linux/module.h>16#include <linux/netdevice.h>17#include <linux/pci.h>18 19#include "esdacc.h"20 21#define ESD_PCI_DEVICE_ID_PCIE402 0x040222 23#define PCI402_FPGA_VER_MIN 0x003d24#define PCI402_MAX_CORES 625#define PCI402_BAR 026#define PCI402_IO_OV_OFFS 027#define PCI402_IO_PCIEP_OFFS 0x1000028#define PCI402_IO_LEN_TOTAL 0x2000029#define PCI402_IO_LEN_CORE 0x200030#define PCI402_PCICFG_MSICAP 0x5031 32#define PCI402_DMA_MASK DMA_BIT_MASK(32)33#define PCI402_DMA_SIZE ALIGN(0x10000, PAGE_SIZE)34 35#define PCI402_PCIEP_OF_INT_ENABLE 0x005036#define PCI402_PCIEP_OF_BM_ADDR_LO 0x100037#define PCI402_PCIEP_OF_BM_ADDR_HI 0x100438#define PCI402_PCIEP_OF_MSI_ADDR_LO 0x100839#define PCI402_PCIEP_OF_MSI_ADDR_HI 0x100c40 41struct pci402_card {42 /* Actually mapped io space, all other iomem derived from this */43 void __iomem *addr;44 void __iomem *addr_pciep;45 46 void *dma_buf;47 dma_addr_t dma_hnd;48 49 struct acc_ov ov;50 struct acc_core *cores;51 52 bool msi_enabled;53};54 55/* The BTR register capabilities described by the can_bittiming_const structures56 * below are valid since esdACC version 0x0032.57 */58 59/* Used if the esdACC FPGA is built as CAN-Classic version. */60static const struct can_bittiming_const pci402_bittiming_const = {61 .name = "esd_402",62 .tseg1_min = 1,63 .tseg1_max = 16,64 .tseg2_min = 1,65 .tseg2_max = 8,66 .sjw_max = 4,67 .brp_min = 1,68 .brp_max = 512,69 .brp_inc = 1,70};71 72/* Used if the esdACC FPGA is built as CAN-FD version. */73static const struct can_bittiming_const pci402_bittiming_const_canfd = {74 .name = "esd_402fd",75 .tseg1_min = 1,76 .tseg1_max = 256,77 .tseg2_min = 1,78 .tseg2_max = 128,79 .sjw_max = 128,80 .brp_min = 1,81 .brp_max = 256,82 .brp_inc = 1,83};84 85static const struct net_device_ops pci402_acc_netdev_ops = {86 .ndo_open = acc_open,87 .ndo_stop = acc_close,88 .ndo_start_xmit = acc_start_xmit,89 .ndo_change_mtu = can_change_mtu,90 .ndo_eth_ioctl = can_eth_ioctl_hwts,91};92 93static const struct ethtool_ops pci402_acc_ethtool_ops = {94 .get_ts_info = can_ethtool_op_get_ts_info_hwts,95};96 97static irqreturn_t pci402_interrupt(int irq, void *dev_id)98{99 struct pci_dev *pdev = dev_id;100 struct pci402_card *card = pci_get_drvdata(pdev);101 irqreturn_t irq_status;102 103 irq_status = acc_card_interrupt(&card->ov, card->cores);104 105 return irq_status;106}107 108static int pci402_set_msiconfig(struct pci_dev *pdev)109{110 struct pci402_card *card = pci_get_drvdata(pdev);111 u32 addr_lo_offs = 0;112 u32 addr_lo = 0;113 u32 addr_hi = 0;114 u32 data = 0;115 u16 csr = 0;116 int err;117 118 /* The FPGA hard IP PCIe core implements a 64-bit MSI Capability119 * Register Format120 */121 err = pci_read_config_word(pdev, PCI402_PCICFG_MSICAP + PCI_MSI_FLAGS, &csr);122 if (err)123 goto failed;124 125 err = pci_read_config_dword(pdev, PCI402_PCICFG_MSICAP + PCI_MSI_ADDRESS_LO,126 &addr_lo);127 if (err)128 goto failed;129 err = pci_read_config_dword(pdev, PCI402_PCICFG_MSICAP + PCI_MSI_ADDRESS_HI,130 &addr_hi);131 if (err)132 goto failed;133 134 err = pci_read_config_dword(pdev, PCI402_PCICFG_MSICAP + PCI_MSI_DATA_64,135 &data);136 if (err)137 goto failed;138 139 addr_lo_offs = addr_lo & 0x0000ffff;140 addr_lo &= 0xffff0000;141 142 if (addr_hi)143 addr_lo |= 1; /* To enable 64-Bit addressing in PCIe endpoint */144 145 if (!(csr & PCI_MSI_FLAGS_ENABLE)) {146 err = -EINVAL;147 goto failed;148 }149 150 iowrite32(addr_lo, card->addr_pciep + PCI402_PCIEP_OF_MSI_ADDR_LO);151 iowrite32(addr_hi, card->addr_pciep + PCI402_PCIEP_OF_MSI_ADDR_HI);152 acc_ov_write32(&card->ov, ACC_OV_OF_MSI_ADDRESSOFFSET, addr_lo_offs);153 acc_ov_write32(&card->ov, ACC_OV_OF_MSI_DATA, data);154 155 return 0;156 157failed:158 pci_warn(pdev, "Error while setting MSI configuration:\n"159 "CSR: 0x%.4x, addr: 0x%.8x%.8x, offs: 0x%.4x, data: 0x%.8x\n",160 csr, addr_hi, addr_lo, addr_lo_offs, data);161 162 return err;163}164 165static int pci402_init_card(struct pci_dev *pdev)166{167 struct pci402_card *card = pci_get_drvdata(pdev);168 169 card->ov.addr = card->addr + PCI402_IO_OV_OFFS;170 card->addr_pciep = card->addr + PCI402_IO_PCIEP_OFFS;171 172 acc_reset_fpga(&card->ov);173 acc_init_ov(&card->ov, &pdev->dev);174 175 if (card->ov.version < PCI402_FPGA_VER_MIN) {176 pci_err(pdev,177 "esdACC version (0x%.4x) outdated, please update\n",178 card->ov.version);179 return -EINVAL;180 }181 182 if (card->ov.timestamp_frequency != ACC_TS_FREQ_80MHZ) {183 pci_err(pdev,184 "esdACC timestamp frequency of %uHz not supported by driver. Aborted.\n",185 card->ov.timestamp_frequency);186 return -EINVAL;187 }188 189 if (card->ov.active_cores > PCI402_MAX_CORES) {190 pci_err(pdev,191 "Card with %u active cores not supported by driver. Aborted.\n",192 card->ov.active_cores);193 return -EINVAL;194 }195 card->cores = devm_kcalloc(&pdev->dev, card->ov.active_cores,196 sizeof(struct acc_core), GFP_KERNEL);197 if (!card->cores)198 return -ENOMEM;199 200 if (card->ov.features & ACC_OV_REG_FEAT_MASK_CANFD) {201 pci_warn(pdev,202 "esdACC with CAN-FD feature detected. This driver doesn't support CAN-FD yet.\n");203 }204 205#ifdef __LITTLE_ENDIAN206 /* So card converts all busmastered data to LE for us: */207 acc_ov_set_bits(&card->ov, ACC_OV_OF_MODE,208 ACC_OV_REG_MODE_MASK_ENDIAN_LITTLE);209#endif210 211 return 0;212}213 214static int pci402_init_interrupt(struct pci_dev *pdev)215{216 struct pci402_card *card = pci_get_drvdata(pdev);217 int err;218 219 err = pci_enable_msi(pdev);220 if (!err) {221 err = pci402_set_msiconfig(pdev);222 if (!err) {223 card->msi_enabled = true;224 acc_ov_set_bits(&card->ov, ACC_OV_OF_MODE,225 ACC_OV_REG_MODE_MASK_MSI_ENABLE);226 pci_dbg(pdev, "MSI preparation done\n");227 }228 }229 230 err = devm_request_irq(&pdev->dev, pdev->irq, pci402_interrupt,231 IRQF_SHARED, dev_name(&pdev->dev), pdev);232 if (err)233 goto failure_msidis;234 235 iowrite32(1, card->addr_pciep + PCI402_PCIEP_OF_INT_ENABLE);236 237 return 0;238 239failure_msidis:240 if (card->msi_enabled) {241 acc_ov_clear_bits(&card->ov, ACC_OV_OF_MODE,242 ACC_OV_REG_MODE_MASK_MSI_ENABLE);243 pci_disable_msi(pdev);244 card->msi_enabled = false;245 }246 247 return err;248}249 250static void pci402_finish_interrupt(struct pci_dev *pdev)251{252 struct pci402_card *card = pci_get_drvdata(pdev);253 254 iowrite32(0, card->addr_pciep + PCI402_PCIEP_OF_INT_ENABLE);255 devm_free_irq(&pdev->dev, pdev->irq, pdev);256 257 if (card->msi_enabled) {258 acc_ov_clear_bits(&card->ov, ACC_OV_OF_MODE,259 ACC_OV_REG_MODE_MASK_MSI_ENABLE);260 pci_disable_msi(pdev);261 card->msi_enabled = false;262 }263}264 265static int pci402_init_dma(struct pci_dev *pdev)266{267 struct pci402_card *card = pci_get_drvdata(pdev);268 int err;269 270 err = dma_set_coherent_mask(&pdev->dev, PCI402_DMA_MASK);271 if (err) {272 pci_err(pdev, "DMA set mask failed!\n");273 return err;274 }275 276 /* The esdACC DMA engine needs the DMA buffer aligned to a 64k277 * boundary. The DMA API guarantees to align the returned buffer to the278 * smallest PAGE_SIZE order which is greater than or equal to the279 * requested size. With PCI402_DMA_SIZE == 64kB this suffices here.280 */281 card->dma_buf = dma_alloc_coherent(&pdev->dev, PCI402_DMA_SIZE,282 &card->dma_hnd, GFP_KERNEL);283 if (!card->dma_buf)284 return -ENOMEM;285 286 acc_init_bm_ptr(&card->ov, card->cores, card->dma_buf);287 288 iowrite32(card->dma_hnd,289 card->addr_pciep + PCI402_PCIEP_OF_BM_ADDR_LO);290 iowrite32(0, card->addr_pciep + PCI402_PCIEP_OF_BM_ADDR_HI);291 292 pci_set_master(pdev);293 294 acc_ov_set_bits(&card->ov, ACC_OV_OF_MODE,295 ACC_OV_REG_MODE_MASK_BM_ENABLE);296 297 return 0;298}299 300static void pci402_finish_dma(struct pci_dev *pdev)301{302 struct pci402_card *card = pci_get_drvdata(pdev);303 int i;304 305 acc_ov_clear_bits(&card->ov, ACC_OV_OF_MODE,306 ACC_OV_REG_MODE_MASK_BM_ENABLE);307 308 pci_clear_master(pdev);309 310 iowrite32(0, card->addr_pciep + PCI402_PCIEP_OF_BM_ADDR_LO);311 iowrite32(0, card->addr_pciep + PCI402_PCIEP_OF_BM_ADDR_HI);312 313 card->ov.bmfifo.messages = NULL;314 card->ov.bmfifo.irq_cnt = NULL;315 for (i = 0; i < card->ov.active_cores; i++) {316 struct acc_core *core = &card->cores[i];317 318 core->bmfifo.messages = NULL;319 core->bmfifo.irq_cnt = NULL;320 }321 322 dma_free_coherent(&pdev->dev, PCI402_DMA_SIZE, card->dma_buf,323 card->dma_hnd);324 card->dma_buf = NULL;325}326 327static void pci402_unregister_core(struct acc_core *core)328{329 netdev_info(core->netdev, "unregister\n");330 unregister_candev(core->netdev);331 332 free_candev(core->netdev);333 core->netdev = NULL;334}335 336static int pci402_init_cores(struct pci_dev *pdev)337{338 struct pci402_card *card = pci_get_drvdata(pdev);339 int err;340 int i;341 342 for (i = 0; i < card->ov.active_cores; i++) {343 struct acc_core *core = &card->cores[i];344 struct acc_net_priv *priv;345 struct net_device *netdev;346 u32 fifo_config;347 348 core->addr = card->ov.addr + (i + 1) * PCI402_IO_LEN_CORE;349 350 fifo_config = acc_read32(core, ACC_CORE_OF_TXFIFO_CONFIG);351 core->tx_fifo_size = (fifo_config >> 24);352 if (core->tx_fifo_size <= 1) {353 pci_err(pdev, "Invalid tx_fifo_size!\n");354 err = -EINVAL;355 goto failure;356 }357 358 netdev = alloc_candev(sizeof(*priv), core->tx_fifo_size);359 if (!netdev) {360 err = -ENOMEM;361 goto failure;362 }363 core->netdev = netdev;364 365 netdev->flags |= IFF_ECHO;366 netdev->dev_port = i;367 netdev->netdev_ops = &pci402_acc_netdev_ops;368 netdev->ethtool_ops = &pci402_acc_ethtool_ops;369 SET_NETDEV_DEV(netdev, &pdev->dev);370 371 priv = netdev_priv(netdev);372 priv->can.clock.freq = card->ov.core_frequency;373 priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |374 CAN_CTRLMODE_LISTENONLY |375 CAN_CTRLMODE_BERR_REPORTING |376 CAN_CTRLMODE_CC_LEN8_DLC;377 if (card->ov.features & ACC_OV_REG_FEAT_MASK_DAR)378 priv->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;379 if (card->ov.features & ACC_OV_REG_FEAT_MASK_CANFD)380 priv->can.bittiming_const = &pci402_bittiming_const_canfd;381 else382 priv->can.bittiming_const = &pci402_bittiming_const;383 priv->can.do_set_bittiming = acc_set_bittiming;384 priv->can.do_set_mode = acc_set_mode;385 priv->can.do_get_berr_counter = acc_get_berr_counter;386 387 priv->core = core;388 priv->ov = &card->ov;389 390 err = register_candev(netdev);391 if (err) {392 free_candev(core->netdev);393 core->netdev = NULL;394 goto failure;395 }396 397 netdev_info(netdev, "registered\n");398 }399 400 return 0;401 402failure:403 for (i--; i >= 0; i--)404 pci402_unregister_core(&card->cores[i]);405 406 return err;407}408 409static void pci402_finish_cores(struct pci_dev *pdev)410{411 struct pci402_card *card = pci_get_drvdata(pdev);412 int i;413 414 for (i = 0; i < card->ov.active_cores; i++)415 pci402_unregister_core(&card->cores[i]);416}417 418static int pci402_probe(struct pci_dev *pdev, const struct pci_device_id *ent)419{420 struct pci402_card *card = NULL;421 int err;422 423 err = pci_enable_device(pdev);424 if (err)425 return err;426 427 card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);428 if (!card) {429 err = -ENOMEM;430 goto failure_disable_pci;431 }432 433 pci_set_drvdata(pdev, card);434 435 err = pci_request_regions(pdev, pci_name(pdev));436 if (err)437 goto failure_disable_pci;438 439 card->addr = pci_iomap(pdev, PCI402_BAR, PCI402_IO_LEN_TOTAL);440 if (!card->addr) {441 err = -ENOMEM;442 goto failure_release_regions;443 }444 445 err = pci402_init_card(pdev);446 if (err)447 goto failure_unmap;448 449 err = pci402_init_dma(pdev);450 if (err)451 goto failure_unmap;452 453 err = pci402_init_interrupt(pdev);454 if (err)455 goto failure_finish_dma;456 457 err = pci402_init_cores(pdev);458 if (err)459 goto failure_finish_interrupt;460 461 return 0;462 463failure_finish_interrupt:464 pci402_finish_interrupt(pdev);465 466failure_finish_dma:467 pci402_finish_dma(pdev);468 469failure_unmap:470 pci_iounmap(pdev, card->addr);471 472failure_release_regions:473 pci_release_regions(pdev);474 475failure_disable_pci:476 pci_disable_device(pdev);477 478 return err;479}480 481static void pci402_remove(struct pci_dev *pdev)482{483 struct pci402_card *card = pci_get_drvdata(pdev);484 485 pci402_finish_interrupt(pdev);486 pci402_finish_cores(pdev);487 pci402_finish_dma(pdev);488 pci_iounmap(pdev, card->addr);489 pci_release_regions(pdev);490 pci_disable_device(pdev);491}492 493static const struct pci_device_id pci402_tbl[] = {494 {495 .vendor = PCI_VENDOR_ID_ESDGMBH,496 .device = ESD_PCI_DEVICE_ID_PCIE402,497 .subvendor = PCI_VENDOR_ID_ESDGMBH,498 .subdevice = PCI_ANY_ID,499 },500 { 0, }501};502MODULE_DEVICE_TABLE(pci, pci402_tbl);503 504static struct pci_driver pci402_driver = {505 .name = KBUILD_MODNAME,506 .id_table = pci402_tbl,507 .probe = pci402_probe,508 .remove = pci402_remove,509};510module_pci_driver(pci402_driver);511 512MODULE_DESCRIPTION("Socket-CAN driver for esd CAN 402 card family with esdACC core on PCIe");513MODULE_AUTHOR("Thomas Körper <socketcan@esd.eu>");514MODULE_AUTHOR("Stefan Mätje <stefan.maetje@esd.eu>");515MODULE_LICENSE("GPL");516