Commit 85ef87ba authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-next-for-5.19-20220419' of...

Merge tag 'linux-can-next-for-5.19-20220419' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2022-04-19

this is a pull request of 17 patches for net-next/master.

The first 2 patches are by me and target the CAN driver
infrastructure. One patch renames a function in the rx_offload helper
the other one updates the CAN bitrate calculation to prefer small bit
rate pre-scalers over larger ones, which is encouraged by the CAN in
Automation.

Kris Bahnsen contributes a patch to fix the links to Technologic
Systems web resources in the sja1000 driver.

Christophe Leroy's patch prepares the mpc5xxx_can driver for upcoming
powerpc header cleanup.

Minghao Chi's patch converts the flexcan driver to use
pm_runtime_resume_and_get().

The next 2 patches target the Xilinx CAN driver. Lukas Bulwahn's patch
fixes an entry in the MAINTAINERS file. A patch by me marks the bit
timing constants as const.

Wolfram Sang's patch documents r8a77961 support on the
renesas,rcar-canfd bindings document.

The next 2 patches are by me and add support for the mcp251863 chip to
the mcp251xfd driver.

The last 7 patches are by Pavel Pisa, Martin Jerabek et al. and add
the ctucanfd driver for the CTU CAN FD IP Core.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c1f6f1e6 cfdb2f36
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/can/ctu,ctucanfd.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: CTU CAN FD Open-source IP Core Device Tree Bindings
description: |
Open-source CAN FD IP core developed at the Czech Technical University in Prague
The core sources and documentation on project page
[1] sources : https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core
[2] datasheet : https://canbus.pages.fel.cvut.cz/ctucanfd_ip_core/doc/Datasheet.pdf
Integration in Xilinx Zynq SoC based system together with
OpenCores SJA1000 compatible controllers
[3] project : https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top
Martin Jerabek dimploma thesis with integration and testing
framework description
[4] PDF : https://dspace.cvut.cz/bitstream/handle/10467/80366/F3-DP-2019-Jerabek-Martin-Jerabek-thesis-2019-canfd.pdf
maintainers:
- Pavel Pisa <pisa@cmp.felk.cvut.cz>
- Ondrej Ille <ondrej.ille@gmail.com>
- Martin Jerabek <martin.jerabek01@gmail.com>
properties:
compatible:
oneOf:
- items:
- const: ctu,ctucanfd-2
- const: ctu,ctucanfd
- const: ctu,ctucanfd
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
description: |
phandle of reference clock (100 MHz is appropriate
for FPGA implementation on Zynq-7000 system).
maxItems: 1
required:
- compatible
- reg
- interrupts
- clocks
additionalProperties: false
examples:
- |
ctu_can_fd_0: can@43c30000 {
compatible = "ctu,ctucanfd";
interrupts = <0 30 4>;
clocks = <&clkc 15>;
reg = <0x43c30000 0x10000>;
};
...@@ -5,8 +5,8 @@ $id: http://devicetree.org/schemas/net/can/microchip,mcp251xfd.yaml# ...@@ -5,8 +5,8 @@ $id: http://devicetree.org/schemas/net/can/microchip,mcp251xfd.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml#
title: title:
Microchip MCP2517FD and MCP2518FD stand-alone CAN controller device tree Microchip MCP2517FD, MCP2518FD and MCP251863 stand-alone CAN
bindings controller device tree bindings
maintainers: maintainers:
- Marc Kleine-Budde <mkl@pengutronix.de> - Marc Kleine-Budde <mkl@pengutronix.de>
...@@ -17,13 +17,14 @@ allOf: ...@@ -17,13 +17,14 @@ allOf:
properties: properties:
compatible: compatible:
oneOf: oneOf:
- const: microchip,mcp2517fd - enum:
description: for MCP2517FD - microchip,mcp2517fd
- const: microchip,mcp2518fd - microchip,mcp2518fd
description: for MCP2518FD - microchip,mcp251xfd
- const: microchip,mcp251xfd - items:
description: to autodetect chip variant - enum:
- microchip,mcp251863
- const: microchip,mcp2518fd
reg: reg:
maxItems: 1 maxItems: 1
......
...@@ -23,6 +23,7 @@ properties: ...@@ -23,6 +23,7 @@ properties:
- renesas,r8a774e1-canfd # RZ/G2H - renesas,r8a774e1-canfd # RZ/G2H
- renesas,r8a7795-canfd # R-Car H3 - renesas,r8a7795-canfd # R-Car H3
- renesas,r8a7796-canfd # R-Car M3-W - renesas,r8a7796-canfd # R-Car M3-W
- renesas,r8a77961-canfd # R-Car M3-W+
- renesas,r8a77965-canfd # R-Car M3-N - renesas,r8a77965-canfd # R-Car M3-N
- renesas,r8a77970-canfd # R-Car V3M - renesas,r8a77970-canfd # R-Car V3M
- renesas,r8a77980-canfd # R-Car V3H - renesas,r8a77980-canfd # R-Car V3H
......
...@@ -283,6 +283,8 @@ patternProperties: ...@@ -283,6 +283,8 @@ patternProperties:
description: Shenzen Chuangsiqi Technology Co.,Ltd. description: Shenzen Chuangsiqi Technology Co.,Ltd.
"^ctera,.*": "^ctera,.*":
description: CTERA Networks Intl. description: CTERA Networks Intl.
"^ctu,.*":
description: Czech Technical University in Prague
"^cubietech,.*": "^cubietech,.*":
description: Cubietech, Ltd. description: Cubietech, Ltd.
"^cui,.*": "^cui,.*":
......
...@@ -5234,6 +5234,14 @@ T: git git://linuxtv.org/media_tree.git ...@@ -5234,6 +5234,14 @@ T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml
F: drivers/media/platform/sunxi/sun6i-csi/ F: drivers/media/platform/sunxi/sun6i-csi/
CTU CAN FD DRIVER
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
M: Ondrej Ille <ondrej.ille@gmail.com>
L: linux-can@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/net/can/ctu,ctucanfd.yaml
F: drivers/net/can/ctucanfd/
CW1200 WLAN driver CW1200 WLAN driver
M: Solomon Peachy <pizza@shaftnet.org> M: Solomon Peachy <pizza@shaftnet.org>
S: Maintained S: Maintained
...@@ -21632,7 +21640,7 @@ M: Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com> ...@@ -21632,7 +21640,7 @@ M: Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>
R: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com> R: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
L: linux-can@vger.kernel.org L: linux-can@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/net/can/xilinx_can.txt F: Documentation/devicetree/bindings/net/can/xilinx,can.yaml
F: drivers/net/can/xilinx_can.c F: drivers/net/can/xilinx_can.c
XILINX GPIO DRIVER XILINX GPIO DRIVER
......
...@@ -170,6 +170,7 @@ config PCH_CAN ...@@ -170,6 +170,7 @@ config PCH_CAN
source "drivers/net/can/c_can/Kconfig" source "drivers/net/can/c_can/Kconfig"
source "drivers/net/can/cc770/Kconfig" source "drivers/net/can/cc770/Kconfig"
source "drivers/net/can/ctucanfd/Kconfig"
source "drivers/net/can/ifi_canfd/Kconfig" source "drivers/net/can/ifi_canfd/Kconfig"
source "drivers/net/can/m_can/Kconfig" source "drivers/net/can/m_can/Kconfig"
source "drivers/net/can/mscan/Kconfig" source "drivers/net/can/mscan/Kconfig"
......
...@@ -16,6 +16,7 @@ obj-y += softing/ ...@@ -16,6 +16,7 @@ obj-y += softing/
obj-$(CONFIG_CAN_AT91) += at91_can.o obj-$(CONFIG_CAN_AT91) += at91_can.o
obj-$(CONFIG_CAN_CC770) += cc770/ obj-$(CONFIG_CAN_CC770) += cc770/
obj-$(CONFIG_CAN_C_CAN) += c_can/ obj-$(CONFIG_CAN_C_CAN) += c_can/
obj-$(CONFIG_CAN_CTUCANFD) += ctucanfd/
obj-$(CONFIG_CAN_FLEXCAN) += flexcan/ obj-$(CONFIG_CAN_FLEXCAN) += flexcan/
obj-$(CONFIG_CAN_GRCAN) += grcan.o obj-$(CONFIG_CAN_GRCAN) += grcan.o
obj-$(CONFIG_CAN_IFI_CANFD) += ifi_canfd/ obj-$(CONFIG_CAN_IFI_CANFD) += ifi_canfd/
......
config CAN_CTUCANFD
tristate "CTU CAN-FD IP core"
help
This driver adds support for the CTU CAN FD open-source IP core.
More documentation and core sources at project page
(https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core).
The core integration to Xilinx Zynq system as platform driver
is available (https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top).
Implementation on Intel FPGA-based PCI Express board is available
from project (https://gitlab.fel.cvut.cz/canbus/pcie-ctucanfd) and
on Intel SoC from project (https://gitlab.fel.cvut.cz/canbus/intel-soc-ctucanfd).
Guidepost CTU FEE CAN bus projects page https://canbus.pages.fel.cvut.cz/ .
config CAN_CTUCANFD_PCI
tristate "CTU CAN-FD IP core PCI/PCIe driver"
depends on CAN_CTUCANFD
depends on PCI
help
This driver adds PCI/PCIe support for CTU CAN-FD IP core.
The project providing FPGA design for Intel EP4CGX15 based DB4CGX15
PCIe board with PiKRON.com designed transceiver riser shield is available
at https://gitlab.fel.cvut.cz/canbus/pcie-ctucanfd .
config CAN_CTUCANFD_PLATFORM
tristate "CTU CAN-FD IP core platform (FPGA, SoC) driver"
depends on CAN_CTUCANFD
depends on OF || COMPILE_TEST
help
The core has been tested together with OpenCores SJA1000
modified to be CAN FD frames tolerant on MicroZed Zynq based
MZ_APO education kits designed by Petr Porazil from PiKRON.com
company. FPGA design https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top.
The kit description at the Computer Architectures course pages
https://cw.fel.cvut.cz/wiki/courses/b35apo/documentation/mz_apo/start .
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Makefile for the CTU CAN-FD IP module drivers
#
obj-$(CONFIG_CAN_CTUCANFD) := ctucanfd.o
ctucanfd-y := ctucanfd_base.o
obj-$(CONFIG_CAN_CTUCANFD_PCI) += ctucanfd_pci.o
obj-$(CONFIG_CAN_CTUCANFD_PLATFORM) += ctucanfd_platform.o
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*******************************************************************************
*
* CTU CAN FD IP Core
*
* Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU
* Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded
* Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU
* Copyright (C) 2018-2021 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded
*
* Project advisors:
* Jiri Novak <jnovak@fel.cvut.cz>
* Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Department of Measurement (http://meas.fel.cvut.cz/)
* Faculty of Electrical Engineering (http://www.fel.cvut.cz)
* Czech Technical University (http://www.cvut.cz/)
******************************************************************************/
#ifndef __CTUCANFD__
#define __CTUCANFD__
#include <linux/netdevice.h>
#include <linux/can/dev.h>
#include <linux/list.h>
enum ctu_can_fd_can_registers;
struct ctucan_priv {
struct can_priv can; /* must be first member! */
void __iomem *mem_base;
u32 (*read_reg)(struct ctucan_priv *priv,
enum ctu_can_fd_can_registers reg);
void (*write_reg)(struct ctucan_priv *priv,
enum ctu_can_fd_can_registers reg, u32 val);
unsigned int txb_head;
unsigned int txb_tail;
u32 txb_prio;
unsigned int ntxbufs;
spinlock_t tx_lock; /* spinlock to serialize allocation and processing of TX buffers */
struct napi_struct napi;
struct device *dev;
struct clk *can_clk;
int irq_flags;
unsigned long drv_flags;
u32 rxfrm_first_word;
struct list_head peers_on_pdev;
};
/**
* ctucan_probe_common - Device type independent registration call
*
* This function does all the memory allocation and registration for the CAN
* device.
*
* @dev: Handle to the generic device structure
* @addr: Base address of CTU CAN FD core address
* @irq: Interrupt number
* @ntxbufs: Number of implemented Tx buffers
* @can_clk_rate: Clock rate, if 0 then clock are taken from device node
* @pm_enable_call: Whether pm_runtime_enable should be called
* @set_drvdata_fnc: Function to set network driver data for physical device
*
* Return: 0 on success and failure value on error
*/
int ctucan_probe_common(struct device *dev, void __iomem *addr,
int irq, unsigned int ntxbufs,
unsigned long can_clk_rate,
int pm_enable_call,
void (*set_drvdata_fnc)(struct device *dev,
struct net_device *ndev));
int ctucan_suspend(struct device *dev) __maybe_unused;
int ctucan_resume(struct device *dev) __maybe_unused;
#endif /*__CTUCANFD__*/
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*******************************************************************************
*
* CTU CAN FD IP Core
*
* Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU
* Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded
* Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU
* Copyright (C) 2018-2021 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded
*
* Project advisors:
* Jiri Novak <jnovak@fel.cvut.cz>
* Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Department of Measurement (http://meas.fel.cvut.cz/)
* Faculty of Electrical Engineering (http://www.fel.cvut.cz)
* Czech Technical University (http://www.cvut.cz/)
******************************************************************************/
/* This file is autogenerated, DO NOT EDIT! */
#ifndef __CTU_CAN_FD_CAN_FD_FRAME_FORMAT__
#define __CTU_CAN_FD_CAN_FD_FRAME_FORMAT__
#include <linux/bits.h>
/* CAN_Frame_format memory map */
enum ctu_can_fd_can_frame_format {
CTUCANFD_FRAME_FORMAT_W = 0x0,
CTUCANFD_IDENTIFIER_W = 0x4,
CTUCANFD_TIMESTAMP_L_W = 0x8,
CTUCANFD_TIMESTAMP_U_W = 0xc,
CTUCANFD_DATA_1_4_W = 0x10,
CTUCANFD_DATA_5_8_W = 0x14,
CTUCANFD_DATA_61_64_W = 0x4c,
};
/* CAN_FD_Frame_format memory region */
/* FRAME_FORMAT_W registers */
#define REG_FRAME_FORMAT_W_DLC GENMASK(3, 0)
#define REG_FRAME_FORMAT_W_RTR BIT(5)
#define REG_FRAME_FORMAT_W_IDE BIT(6)
#define REG_FRAME_FORMAT_W_FDF BIT(7)
#define REG_FRAME_FORMAT_W_BRS BIT(9)
#define REG_FRAME_FORMAT_W_ESI_RSV BIT(10)
#define REG_FRAME_FORMAT_W_RWCNT GENMASK(15, 11)
/* IDENTIFIER_W registers */
#define REG_IDENTIFIER_W_IDENTIFIER_EXT GENMASK(17, 0)
#define REG_IDENTIFIER_W_IDENTIFIER_BASE GENMASK(28, 18)
/* TIMESTAMP_L_W registers */
#define REG_TIMESTAMP_L_W_TIME_STAMP_L_W GENMASK(31, 0)
/* TIMESTAMP_U_W registers */
#define REG_TIMESTAMP_U_W_TIMESTAMP_U_W GENMASK(31, 0)
/* DATA_1_4_W registers */
#define REG_DATA_1_4_W_DATA_1 GENMASK(7, 0)
#define REG_DATA_1_4_W_DATA_2 GENMASK(15, 8)
#define REG_DATA_1_4_W_DATA_3 GENMASK(23, 16)
#define REG_DATA_1_4_W_DATA_4 GENMASK(31, 24)
/* DATA_5_8_W registers */
#define REG_DATA_5_8_W_DATA_5 GENMASK(7, 0)
#define REG_DATA_5_8_W_DATA_6 GENMASK(15, 8)
#define REG_DATA_5_8_W_DATA_7 GENMASK(23, 16)
#define REG_DATA_5_8_W_DATA_8 GENMASK(31, 24)
/* DATA_61_64_W registers */
#define REG_DATA_61_64_W_DATA_61 GENMASK(7, 0)
#define REG_DATA_61_64_W_DATA_62 GENMASK(15, 8)
#define REG_DATA_61_64_W_DATA_63 GENMASK(23, 16)
#define REG_DATA_61_64_W_DATA_64 GENMASK(31, 24)
#endif
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
*
* CTU CAN FD IP Core
*
* Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU
* Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded
* Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU
* Copyright (C) 2018-2022 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded
*
* Project advisors:
* Jiri Novak <jnovak@fel.cvut.cz>
* Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Department of Measurement (http://meas.fel.cvut.cz/)
* Faculty of Electrical Engineering (http://www.fel.cvut.cz)
* Czech Technical University (http://www.cvut.cz/)
******************************************************************************/
#include <linux/module.h>
#include <linux/pci.h>
#include "ctucanfd.h"
#ifndef PCI_DEVICE_DATA
#define PCI_DEVICE_DATA(vend, dev, data) \
.vendor = PCI_VENDOR_ID_##vend, \
.device = PCI_DEVICE_ID_##vend##_##dev, \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0, \
.driver_data = (kernel_ulong_t)(data)
#endif
#ifndef PCI_VENDOR_ID_TEDIA
#define PCI_VENDOR_ID_TEDIA 0x1760
#endif
#ifndef PCI_DEVICE_ID_TEDIA_CTUCAN_VER21
#define PCI_DEVICE_ID_TEDIA_CTUCAN_VER21 0xff00
#endif
#define CTUCAN_BAR0_CTUCAN_ID 0x0000
#define CTUCAN_BAR0_CRA_BASE 0x4000
#define CYCLONE_IV_CRA_A2P_IE (0x0050)
#define CTUCAN_WITHOUT_CTUCAN_ID 0
#define CTUCAN_WITH_CTUCAN_ID 1
static bool use_msi = true;
module_param(use_msi, bool, 0444);
MODULE_PARM_DESC(use_msi, "PCIe implementation use MSI interrupts. Default: 1 (yes)");
static bool pci_use_second = true;
module_param(pci_use_second, bool, 0444);
MODULE_PARM_DESC(pci_use_second, "Use the second CAN core on PCIe card. Default: 1 (yes)");
struct ctucan_pci_board_data {
void __iomem *bar0_base;
void __iomem *cra_base;
void __iomem *bar1_base;
struct list_head ndev_list_head;
int use_msi;
};
static struct ctucan_pci_board_data *ctucan_pci_get_bdata(struct pci_dev *pdev)
{
return (struct ctucan_pci_board_data *)pci_get_drvdata(pdev);
}
static void ctucan_pci_set_drvdata(struct device *dev,
struct net_device *ndev)
{
struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
struct ctucan_priv *priv = netdev_priv(ndev);
struct ctucan_pci_board_data *bdata = ctucan_pci_get_bdata(pdev);
list_add(&priv->peers_on_pdev, &bdata->ndev_list_head);
priv->irq_flags = IRQF_SHARED;
}
/**
* ctucan_pci_probe - PCI registration call
* @pdev: Handle to the pci device structure
* @ent: Pointer to the entry from ctucan_pci_tbl
*
* This function does all the memory allocation and registration for the CAN
* device.
*
* Return: 0 on success and failure value on error
*/
static int ctucan_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct device *dev = &pdev->dev;
unsigned long driver_data = ent->driver_data;
struct ctucan_pci_board_data *bdata;
void __iomem *addr;
void __iomem *cra_addr;
void __iomem *bar0_base;
u32 cra_a2p_ie;
u32 ctucan_id = 0;
int ret;
unsigned int ntxbufs;
unsigned int num_cores = 1;
unsigned int core_i = 0;
int irq;
int msi_ok = 0;
ret = pci_enable_device(pdev);
if (ret) {
dev_err(dev, "pci_enable_device FAILED\n");
goto err;
}
ret = pci_request_regions(pdev, KBUILD_MODNAME);
if (ret) {
dev_err(dev, "pci_request_regions FAILED\n");
goto err_disable_device;
}
if (use_msi) {
ret = pci_enable_msi(pdev);
if (!ret) {
dev_info(dev, "MSI enabled\n");
pci_set_master(pdev);
msi_ok = 1;
}
}
dev_info(dev, "ctucan BAR0 0x%08llx 0x%08llx\n",
(long long)pci_resource_start(pdev, 0),
(long long)pci_resource_len(pdev, 0));
dev_info(dev, "ctucan BAR1 0x%08llx 0x%08llx\n",
(long long)pci_resource_start(pdev, 1),
(long long)pci_resource_len(pdev, 1));
addr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
if (!addr) {
dev_err(dev, "PCI BAR 1 cannot be mapped\n");
ret = -ENOMEM;
goto err_release_regions;
}
/* Cyclone IV PCI Express Control Registers Area */
bar0_base = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
if (!bar0_base) {
dev_err(dev, "PCI BAR 0 cannot be mapped\n");
ret = -EIO;
goto err_pci_iounmap_bar1;
}
if (driver_data == CTUCAN_WITHOUT_CTUCAN_ID) {
cra_addr = bar0_base;
num_cores = 2;
} else {
cra_addr = bar0_base + CTUCAN_BAR0_CRA_BASE;
ctucan_id = ioread32(bar0_base + CTUCAN_BAR0_CTUCAN_ID);
dev_info(dev, "ctucan_id 0x%08lx\n", (unsigned long)ctucan_id);
num_cores = ctucan_id & 0xf;
}
irq = pdev->irq;
ntxbufs = 4;
bdata = kzalloc(sizeof(*bdata), GFP_KERNEL);
if (!bdata) {
ret = -ENOMEM;
goto err_pci_iounmap_bar0;
}
INIT_LIST_HEAD(&bdata->ndev_list_head);
bdata->bar0_base = bar0_base;
bdata->cra_base = cra_addr;
bdata->bar1_base = addr;
bdata->use_msi = msi_ok;
pci_set_drvdata(pdev, bdata);
ret = ctucan_probe_common(dev, addr, irq, ntxbufs, 100000000,
0, ctucan_pci_set_drvdata);
if (ret < 0)
goto err_free_board;
core_i++;
while (pci_use_second && (core_i < num_cores)) {
addr += 0x4000;
ret = ctucan_probe_common(dev, addr, irq, ntxbufs, 100000000,
0, ctucan_pci_set_drvdata);
if (ret < 0) {
dev_info(dev, "CTU CAN FD core %d initialization failed\n",
core_i);
break;
}
core_i++;
}
/* enable interrupt in
* Avalon-MM to PCI Express Interrupt Enable Register
*/
cra_a2p_ie = ioread32(cra_addr + CYCLONE_IV_CRA_A2P_IE);
dev_info(dev, "cra_a2p_ie 0x%08x\n", cra_a2p_ie);
cra_a2p_ie |= 1;
iowrite32(cra_a2p_ie, cra_addr + CYCLONE_IV_CRA_A2P_IE);
cra_a2p_ie = ioread32(cra_addr + CYCLONE_IV_CRA_A2P_IE);
dev_info(dev, "cra_a2p_ie 0x%08x\n", cra_a2p_ie);
return 0;
err_free_board:
pci_set_drvdata(pdev, NULL);
kfree(bdata);
err_pci_iounmap_bar0:
pci_iounmap(pdev, cra_addr);
err_pci_iounmap_bar1:
pci_iounmap(pdev, addr);
err_release_regions:
if (msi_ok) {
pci_disable_msi(pdev);
pci_clear_master(pdev);
}
pci_release_regions(pdev);
err_disable_device:
pci_disable_device(pdev);
err:
return ret;
}
/**
* ctucan_pci_remove - Unregister the device after releasing the resources
* @pdev: Handle to the pci device structure
*
* This function frees all the resources allocated to the device.
* Return: 0 always
*/
static void ctucan_pci_remove(struct pci_dev *pdev)
{
struct net_device *ndev;
struct ctucan_priv *priv = NULL;
struct ctucan_pci_board_data *bdata = ctucan_pci_get_bdata(pdev);
dev_dbg(&pdev->dev, "ctucan_remove");
if (!bdata) {
dev_err(&pdev->dev, "%s: no list of devices\n", __func__);
return;
}
/* disable interrupt in
* Avalon-MM to PCI Express Interrupt Enable Register
*/
if (bdata->cra_base)
iowrite32(0, bdata->cra_base + CYCLONE_IV_CRA_A2P_IE);
while ((priv = list_first_entry_or_null(&bdata->ndev_list_head, struct ctucan_priv,
peers_on_pdev)) != NULL) {
ndev = priv->can.dev;
unregister_candev(ndev);
netif_napi_del(&priv->napi);
list_del_init(&priv->peers_on_pdev);
free_candev(ndev);
}
pci_iounmap(pdev, bdata->bar1_base);
if (bdata->use_msi) {
pci_disable_msi(pdev);
pci_clear_master(pdev);
}
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_iounmap(pdev, bdata->bar0_base);
pci_set_drvdata(pdev, NULL);
kfree(bdata);
}
static SIMPLE_DEV_PM_OPS(ctucan_pci_pm_ops, ctucan_suspend, ctucan_resume);
static const struct pci_device_id ctucan_pci_tbl[] = {
{PCI_DEVICE_DATA(TEDIA, CTUCAN_VER21,
CTUCAN_WITH_CTUCAN_ID)},
{},
};
static struct pci_driver ctucan_pci_driver = {
.name = KBUILD_MODNAME,
.id_table = ctucan_pci_tbl,
.probe = ctucan_pci_probe,
.remove = ctucan_pci_remove,
.driver.pm = &ctucan_pci_pm_ops,
};
module_pci_driver(ctucan_pci_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pavel Pisa <pisa@cmp.felk.cvut.cz>");
MODULE_DESCRIPTION("CTU CAN FD for PCI bus");
// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
*
* CTU CAN FD IP Core
*
* Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU
* Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded
* Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU
* Copyright (C) 2018-2022 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded
*
* Project advisors:
* Jiri Novak <jnovak@fel.cvut.cz>
* Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Department of Measurement (http://meas.fel.cvut.cz/)
* Faculty of Electrical Engineering (http://www.fel.cvut.cz)
* Czech Technical University (http://www.cvut.cz/)
******************************************************************************/
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include "ctucanfd.h"
#define DRV_NAME "ctucanfd"
static void ctucan_platform_set_drvdata(struct device *dev,
struct net_device *ndev)
{
struct platform_device *pdev = container_of(dev, struct platform_device,
dev);
platform_set_drvdata(pdev, ndev);
}
/**
* ctucan_platform_probe - Platform registration call
* @pdev: Handle to the platform device structure
*
* This function does all the memory allocation and registration for the CAN
* device.
*
* Return: 0 on success and failure value on error
*/
static int ctucan_platform_probe(struct platform_device *pdev)
{
struct resource *res; /* IO mem resources */
struct device *dev = &pdev->dev;
void __iomem *addr;
int ret;
unsigned int ntxbufs;
int irq;
/* Get the virtual base address for the device */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
addr = devm_ioremap_resource(dev, res);
if (IS_ERR(addr)) {
dev_err(dev, "Cannot remap address.\n");
ret = PTR_ERR(addr);
goto err;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "Cannot find interrupt.\n");
ret = irq;
goto err;
}
/* Number of tx bufs might be change in HW for future. If so,
* it will be passed as property via device tree
*/
ntxbufs = 4;
ret = ctucan_probe_common(dev, addr, irq, ntxbufs, 0,
1, ctucan_platform_set_drvdata);
if (ret < 0)
platform_set_drvdata(pdev, NULL);
err:
return ret;
}
/**
* ctucan_platform_remove - Unregister the device after releasing the resources
* @pdev: Handle to the platform device structure
*
* This function frees all the resources allocated to the device.
* Return: 0 always
*/
static int ctucan_platform_remove(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct ctucan_priv *priv = netdev_priv(ndev);
netdev_dbg(ndev, "ctucan_remove");
unregister_candev(ndev);
pm_runtime_disable(&pdev->dev);
netif_napi_del(&priv->napi);
free_candev(ndev);
return 0;
}
static SIMPLE_DEV_PM_OPS(ctucan_platform_pm_ops, ctucan_suspend, ctucan_resume);
/* Match table for OF platform binding */
static const struct of_device_id ctucan_of_match[] = {
{ .compatible = "ctu,ctucanfd-2", },
{ .compatible = "ctu,ctucanfd", },
{ /* end of list */ },
};
MODULE_DEVICE_TABLE(of, ctucan_of_match);
static struct platform_driver ctucanfd_driver = {
.probe = ctucan_platform_probe,
.remove = ctucan_platform_remove,
.driver = {
.name = DRV_NAME,
.pm = &ctucan_platform_pm_ops,
.of_match_table = ctucan_of_match,
},
};
module_platform_driver(ctucanfd_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Martin Jerabek");
MODULE_DESCRIPTION("CTU CAN FD for platform");
...@@ -116,7 +116,7 @@ int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt, ...@@ -116,7 +116,7 @@ int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt,
can_update_sample_point(btc, sample_point_nominal, tseg / 2, can_update_sample_point(btc, sample_point_nominal, tseg / 2,
&tseg1, &tseg2, &sample_point_error); &tseg1, &tseg2, &sample_point_error);
if (sample_point_error > best_sample_point_error) if (sample_point_error >= best_sample_point_error)
continue; continue;
best_sample_point_error = sample_point_error; best_sample_point_error = sample_point_error;
......
...@@ -221,7 +221,7 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload) ...@@ -221,7 +221,7 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload)
} }
EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo); EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo);
int can_rx_offload_queue_sorted(struct can_rx_offload *offload, int can_rx_offload_queue_timestamp(struct can_rx_offload *offload,
struct sk_buff *skb, u32 timestamp) struct sk_buff *skb, u32 timestamp)
{ {
struct can_rx_offload_cb *cb; struct can_rx_offload_cb *cb;
...@@ -240,7 +240,7 @@ int can_rx_offload_queue_sorted(struct can_rx_offload *offload, ...@@ -240,7 +240,7 @@ int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted); EXPORT_SYMBOL_GPL(can_rx_offload_queue_timestamp);
unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
unsigned int idx, u32 timestamp, unsigned int idx, u32 timestamp,
...@@ -256,7 +256,7 @@ unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, ...@@ -256,7 +256,7 @@ unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
if (!skb) if (!skb)
return 0; return 0;
err = can_rx_offload_queue_sorted(offload, skb, timestamp); err = can_rx_offload_queue_timestamp(offload, skb, timestamp);
if (err) { if (err) {
stats->rx_errors++; stats->rx_errors++;
stats->tx_fifo_errors++; stats->tx_fifo_errors++;
......
...@@ -723,11 +723,9 @@ static int flexcan_get_berr_counter(const struct net_device *dev, ...@@ -723,11 +723,9 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
const struct flexcan_priv *priv = netdev_priv(dev); const struct flexcan_priv *priv = netdev_priv(dev);
int err; int err;
err = pm_runtime_get_sync(priv->dev); err = pm_runtime_resume_and_get(priv->dev);
if (err < 0) { if (err < 0)
pm_runtime_put_noidle(priv->dev);
return err; return err;
}
err = __flexcan_get_berr_counter(dev, bec); err = __flexcan_get_berr_counter(dev, bec);
...@@ -845,7 +843,7 @@ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) ...@@ -845,7 +843,7 @@ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
if (tx_errors) if (tx_errors)
dev->stats.tx_errors++; dev->stats.tx_errors++;
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
if (err) if (err)
dev->stats.rx_fifo_errors++; dev->stats.rx_fifo_errors++;
} }
...@@ -892,7 +890,7 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) ...@@ -892,7 +890,7 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
if (unlikely(new_state == CAN_STATE_BUS_OFF)) if (unlikely(new_state == CAN_STATE_BUS_OFF))
can_bus_off(dev); can_bus_off(dev);
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
if (err) if (err)
dev->stats.rx_fifo_errors++; dev->stats.rx_fifo_errors++;
} }
...@@ -1700,11 +1698,9 @@ static int flexcan_open(struct net_device *dev) ...@@ -1700,11 +1698,9 @@ static int flexcan_open(struct net_device *dev)
return -EINVAL; return -EINVAL;
} }
err = pm_runtime_get_sync(priv->dev); err = pm_runtime_resume_and_get(priv->dev);
if (err < 0) { if (err < 0)
pm_runtime_put_noidle(priv->dev);
return err; return err;
}
err = open_candev(dev); err = open_candev(dev);
if (err) if (err)
......
...@@ -464,7 +464,7 @@ static void m_can_receive_skb(struct m_can_classdev *cdev, ...@@ -464,7 +464,7 @@ static void m_can_receive_skb(struct m_can_classdev *cdev,
struct net_device_stats *stats = &cdev->net->stats; struct net_device_stats *stats = &cdev->net->stats;
int err; int err;
err = can_rx_offload_queue_sorted(&cdev->offload, skb, err = can_rx_offload_queue_timestamp(&cdev->offload, skb,
timestamp); timestamp);
if (err) if (err)
stats->rx_fifo_errors++; stats->rx_fifo_errors++;
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/can/dev.h> #include <linux/can/dev.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <linux/clk.h> #include <linux/clk.h>
......
...@@ -107,7 +107,7 @@ config CAN_TSCAN1 ...@@ -107,7 +107,7 @@ config CAN_TSCAN1
depends on ISA depends on ISA
help help
This driver is for Technologic Systems' TSCAN-1 PC104 boards. This driver is for Technologic Systems' TSCAN-1 PC104 boards.
http://www.embeddedarm.com/products/board-detail.php?product=TS-CAN1 https://www.embeddedts.com/products/TS-CAN1
The driver supports multiple boards and automatically configures them: The driver supports multiple boards and automatically configures them:
PLD IO base addresses are read from jumpers JP1 and JP2, PLD IO base addresses are read from jumpers JP1 and JP2,
IRQ numbers are read from jumpers JP4 and JP5, IRQ numbers are read from jumpers JP4 and JP5,
......
...@@ -5,10 +5,9 @@ ...@@ -5,10 +5,9 @@
* Copyright 2010 Andre B. Oliveira * Copyright 2010 Andre B. Oliveira
*/ */
/* /* References:
* References: * - Getting started with TS-CAN1, Technologic Systems, Feb 2022
* - Getting started with TS-CAN1, Technologic Systems, Jun 2009 * https://docs.embeddedts.com/TS-CAN1
* http://www.embeddedarm.com/documentation/ts-can1-manual.pdf
*/ */
#include <linux/init.h> #include <linux/init.h>
......
...@@ -37,6 +37,12 @@ static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp2518fd = { ...@@ -37,6 +37,12 @@ static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp2518fd = {
.model = MCP251XFD_MODEL_MCP2518FD, .model = MCP251XFD_MODEL_MCP2518FD,
}; };
static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp251863 = {
.quirks = MCP251XFD_QUIRK_CRC_REG | MCP251XFD_QUIRK_CRC_RX |
MCP251XFD_QUIRK_CRC_TX | MCP251XFD_QUIRK_ECC,
.model = MCP251XFD_MODEL_MCP251863,
};
/* Autodetect model, start with CRC enabled. */ /* Autodetect model, start with CRC enabled. */
static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp251xfd = { static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp251xfd = {
.quirks = MCP251XFD_QUIRK_CRC_REG | MCP251XFD_QUIRK_CRC_RX | .quirks = MCP251XFD_QUIRK_CRC_REG | MCP251XFD_QUIRK_CRC_RX |
...@@ -75,6 +81,8 @@ static const char *__mcp251xfd_get_model_str(enum mcp251xfd_model model) ...@@ -75,6 +81,8 @@ static const char *__mcp251xfd_get_model_str(enum mcp251xfd_model model)
return "MCP2517FD"; return "MCP2517FD";
case MCP251XFD_MODEL_MCP2518FD: case MCP251XFD_MODEL_MCP2518FD:
return "MCP2518FD"; return "MCP2518FD";
case MCP251XFD_MODEL_MCP251863:
return "MCP251863";
case MCP251XFD_MODEL_MCP251XFD: case MCP251XFD_MODEL_MCP251XFD:
return "MCP251xFD"; return "MCP251xFD";
} }
...@@ -916,7 +924,7 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv) ...@@ -916,7 +924,7 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv)
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
if (err) if (err)
stats->rx_fifo_errors++; stats->rx_fifo_errors++;
...@@ -1021,7 +1029,7 @@ static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv) ...@@ -1021,7 +1029,7 @@ static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv)
return 0; return 0;
mcp251xfd_skb_set_timestamp(priv, skb, timestamp); mcp251xfd_skb_set_timestamp(priv, skb, timestamp);
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
if (err) if (err)
stats->rx_fifo_errors++; stats->rx_fifo_errors++;
...@@ -1094,7 +1102,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) ...@@ -1094,7 +1102,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv)
cf->data[7] = bec.rxerr; cf->data[7] = bec.rxerr;
} }
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
if (err) if (err)
stats->rx_fifo_errors++; stats->rx_fifo_errors++;
...@@ -1259,7 +1267,8 @@ mcp251xfd_handle_eccif_recover(struct mcp251xfd_priv *priv, u8 nr) ...@@ -1259,7 +1267,8 @@ mcp251xfd_handle_eccif_recover(struct mcp251xfd_priv *priv, u8 nr)
* - for mcp2518fd: offset not 0 or 1 * - for mcp2518fd: offset not 0 or 1
*/ */
if (chip_tx_tail != tx_tail || if (chip_tx_tail != tx_tail ||
!(offset == 0 || (offset == 1 && mcp251xfd_is_2518(priv)))) { !(offset == 0 || (offset == 1 && (mcp251xfd_is_2518FD(priv) ||
mcp251xfd_is_251863(priv))))) {
netdev_err(priv->ndev, netdev_err(priv->ndev,
"ECC Error information inconsistent (addr=0x%04x, nr=%d, tx_tail=0x%08x(%d), chip_tx_tail=%d, offset=%d).\n", "ECC Error information inconsistent (addr=0x%04x, nr=%d, tx_tail=0x%08x(%d), chip_tx_tail=%d, offset=%d).\n",
addr, nr, tx_ring->tail, tx_tail, chip_tx_tail, addr, nr, tx_ring->tail, tx_tail, chip_tx_tail,
...@@ -1697,7 +1706,7 @@ static int mcp251xfd_register_chip_detect(struct mcp251xfd_priv *priv) ...@@ -1697,7 +1706,7 @@ static int mcp251xfd_register_chip_detect(struct mcp251xfd_priv *priv)
else else
devtype_data = &mcp251xfd_devtype_data_mcp2517fd; devtype_data = &mcp251xfd_devtype_data_mcp2517fd;
if (!mcp251xfd_is_251X(priv) && if (!mcp251xfd_is_251XFD(priv) &&
priv->devtype_data.model != devtype_data->model) { priv->devtype_data.model != devtype_data->model) {
netdev_info(ndev, netdev_info(ndev,
"Detected %s, but firmware specifies a %s. Fixing up.\n", "Detected %s, but firmware specifies a %s. Fixing up.\n",
...@@ -1929,6 +1938,9 @@ static const struct of_device_id mcp251xfd_of_match[] = { ...@@ -1929,6 +1938,9 @@ static const struct of_device_id mcp251xfd_of_match[] = {
}, { }, {
.compatible = "microchip,mcp2518fd", .compatible = "microchip,mcp2518fd",
.data = &mcp251xfd_devtype_data_mcp2518fd, .data = &mcp251xfd_devtype_data_mcp2518fd,
}, {
.compatible = "microchip,mcp251863",
.data = &mcp251xfd_devtype_data_mcp251863,
}, { }, {
.compatible = "microchip,mcp251xfd", .compatible = "microchip,mcp251xfd",
.data = &mcp251xfd_devtype_data_mcp251xfd, .data = &mcp251xfd_devtype_data_mcp251xfd,
...@@ -1945,6 +1957,9 @@ static const struct spi_device_id mcp251xfd_id_table[] = { ...@@ -1945,6 +1957,9 @@ static const struct spi_device_id mcp251xfd_id_table[] = {
}, { }, {
.name = "mcp2518fd", .name = "mcp2518fd",
.driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp2518fd, .driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp2518fd,
}, {
.name = "mcp251863",
.driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp251863,
}, { }, {
.name = "mcp251xfd", .name = "mcp251xfd",
.driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp251xfd, .driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp251xfd,
......
...@@ -173,7 +173,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv, ...@@ -173,7 +173,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv,
} }
mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb); mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb);
err = can_rx_offload_queue_sorted(&priv->offload, skb, hw_rx_obj->ts); err = can_rx_offload_queue_timestamp(&priv->offload, skb, hw_rx_obj->ts);
if (err) if (err)
stats->rx_fifo_errors++; stats->rx_fifo_errors++;
......
...@@ -586,7 +586,8 @@ struct mcp251xfd_regs_status { ...@@ -586,7 +586,8 @@ struct mcp251xfd_regs_status {
enum mcp251xfd_model { enum mcp251xfd_model {
MCP251XFD_MODEL_MCP2517FD = 0x2517, MCP251XFD_MODEL_MCP2517FD = 0x2517,
MCP251XFD_MODEL_MCP2518FD = 0x2518, MCP251XFD_MODEL_MCP2518FD = 0x2518,
MCP251XFD_MODEL_MCP251XFD = 0xffff, /* autodetect model */ MCP251XFD_MODEL_MCP251863 = 0x251863,
MCP251XFD_MODEL_MCP251XFD = 0xffffffff, /* autodetect model */
}; };
struct mcp251xfd_devtype_data { struct mcp251xfd_devtype_data {
...@@ -659,12 +660,13 @@ struct mcp251xfd_priv { ...@@ -659,12 +660,13 @@ struct mcp251xfd_priv {
static inline bool \ static inline bool \
mcp251xfd_is_##_model(const struct mcp251xfd_priv *priv) \ mcp251xfd_is_##_model(const struct mcp251xfd_priv *priv) \
{ \ { \
return priv->devtype_data.model == MCP251XFD_MODEL_MCP##_model##FD; \ return priv->devtype_data.model == MCP251XFD_MODEL_MCP##_model; \
} }
MCP251XFD_IS(2517); MCP251XFD_IS(2517FD);
MCP251XFD_IS(2518); MCP251XFD_IS(2518FD);
MCP251XFD_IS(251X); MCP251XFD_IS(251863);
MCP251XFD_IS(251XFD);
static inline bool mcp251xfd_is_fd_mode(const struct mcp251xfd_priv *priv) static inline bool mcp251xfd_is_fd_mode(const struct mcp251xfd_priv *priv)
{ {
......
...@@ -633,7 +633,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, ...@@ -633,7 +633,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
cf->data[3] = CAN_ERR_PROT_LOC_ACK; cf->data[3] = CAN_ERR_PROT_LOC_ACK;
timestamp = hecc_read(priv, HECC_CANLNT); timestamp = hecc_read(priv, HECC_CANLNT);
err = can_rx_offload_queue_sorted(&priv->offload, skb, err = can_rx_offload_queue_timestamp(&priv->offload, skb,
timestamp); timestamp);
if (err) if (err)
ndev->stats.rx_fifo_errors++; ndev->stats.rx_fifo_errors++;
...@@ -668,7 +668,7 @@ static void ti_hecc_change_state(struct net_device *ndev, ...@@ -668,7 +668,7 @@ static void ti_hecc_change_state(struct net_device *ndev,
} }
timestamp = hecc_read(priv, HECC_CANLNT); timestamp = hecc_read(priv, HECC_CANLNT);
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
if (err) if (err)
ndev->stats.rx_fifo_errors++; ndev->stats.rx_fifo_errors++;
} }
......
...@@ -239,7 +239,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd = { ...@@ -239,7 +239,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd = {
}; };
/* AXI CANFD Data Bittiming constants as per AXI CANFD 1.0 specs */ /* AXI CANFD Data Bittiming constants as per AXI CANFD 1.0 specs */
static struct can_bittiming_const xcan_data_bittiming_const_canfd = { static const struct can_bittiming_const xcan_data_bittiming_const_canfd = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.tseg1_min = 1, .tseg1_min = 1,
.tseg1_max = 16, .tseg1_max = 16,
...@@ -265,7 +265,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd2 = { ...@@ -265,7 +265,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd2 = {
}; };
/* AXI CANFD 2.0 Data Bittiming constants as per AXI CANFD 2.0 spec */ /* AXI CANFD 2.0 Data Bittiming constants as per AXI CANFD 2.0 spec */
static struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.tseg1_min = 1, .tseg1_min = 1,
.tseg1_max = 32, .tseg1_max = 32,
......
...@@ -42,8 +42,8 @@ int can_rx_offload_add_manual(struct net_device *dev, ...@@ -42,8 +42,8 @@ int can_rx_offload_add_manual(struct net_device *dev,
int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload,
u64 reg); u64 reg);
int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload); int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload);
int can_rx_offload_queue_sorted(struct can_rx_offload *offload, int can_rx_offload_queue_timestamp(struct can_rx_offload *offload,
struct sk_buff *skb, u32 timestamp); struct sk_buff *skb, u32 timestamp);
unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
unsigned int idx, u32 timestamp, unsigned int idx, u32 timestamp,
unsigned int *frame_len_ptr); unsigned int *frame_len_ptr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment