Skip to contentSkip to conversation

CTU CAN FD open-source IP core SocketCAN driver, PCI, platform integration and documentation

PATCH Superseded Pavel Pisa 2 participants 19 messages Oct 22, 2020 – Oct 26, 2020 1 message not in the archive

Subsystems (6)

v6 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Pavel Pisa

author maintainer
#0 lore raw

v6 cover CTU CAN FD open-source IP core SocketCAN driver, PCI, platform integration and documentation

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-ctu_can_fd).
The CTU CAN FD core emulation send for review for QEMU mainline. Development repository for QEMU emulation - ctu-canfd branch of
https://gitlab.fel.cvut.cz/canbus/qemu-canbus

More about CAN bus related projects used and developed at CTU FEE on the guidepost page http://canbus.pages.fel.cvut.cz/ .

Martin Jerabek (1):
can: ctucanfd: add support for CTU CAN FD open-source IP core - bus
independent part.

Pavel Pisa (5):
dt-bindings: vendor-prefix: add prefix for the Czech Technical
University in Prague.
dt-bindings: net: can: binding for CTU CAN FD open-source IP core.
can: ctucanfd: CTU CAN FD open-source IP core - PCI bus support.
can: ctucanfd: CTU CAN FD open-source IP core - platform/SoC support.
docs: ctucanfd: CTU CAN FD open-source IP core documentation.

The version 6 changes:
- sent at 2020-10-22
- the driver has been tested with 5.9 bigendian MIPS kernel against QEMU CTU CAN FD model and correct behavior on PCIe virtual board for big-endian system passed
- documentation updated to reflect inclusion of SocketCAN FD and CTU CAN FD functional model support into QEMU mainline
- the integration for Cyclone V 5CSEMA4U23C6 based DE0-Nano-SoC Terasic board used for SkodaAuto research projects at our university has been clean up by its author (Jaroslav Beran) and published
https://gitlab.fel.cvut.cz/canbus/intel-soc-ctucanfd
- Xilinx Zynq Microzed MZ_APO based target for automatic test updated to Debian 10 base.

The version 5 changes:
- sent at 2020-08-15
- correct Kconfig formatting according to Randy Dunlap
- silence warnings reported by make W=1 C=1 flags. Changes suggested by Jakub Kicinski
- big thanks for core patch review by Pavel Machek resulting in more readability and formating updates
- fix power management errors found by Pavel Machek
- removed comments from d-t bindings as suggested by Rob Herring
- selected ctu,ctucanfd-2 as alternative name to ctu,ctucanfd which allows to bind to actual major HDL core sources version 2.x if for some reason driver adaptation would not work on version read from the core
- line length limit relaxed to 100 characters on some cases where it helps to readability

The version 4 changes:
- sent at 2020-08-04
- changes summary, 169 non-merge commits, 6 driver, 32 IP core sources enhancements and fixes, 58 tests in master and about additional 30 iso-testbench preparation branch.
- convert device-tree binding documentation to YAML
- QEMU model of CTU CAN FD IP core and generic extension of QEMU CAN bus emulation developed by Jan Charvat.
- driver tested on QEMU emulated Malta big-endian MIPS platform and big endian-support fixed.
- checkpatch from 5.4 kernel used to cleanup driver formatting
- header files generated from IP core IP-Xact description updated to include protocol exception (pex) field. Mechanism to set it from the driver is not provided yet.

The version 3 changes:
- sent at 2019-12-21
- adapts device tree bindings documentation according to
Rob Herring suggestions.
- the driver has been separated to individual modules for core support, PCI bus integration and platform, SoC integration.
- the FPGA design has been cleaned up and CAN protocol FSM redesigned by Ondrej Ille (the core redesign has been reason to pause attempts to driver submission)
- the work from February 2019 on core, test framework and driver 1601 commits in total, 436 commits in the core sources, 144 commits in the driver, 151 documentation, 502 in tests.
- not all continuous integration tests updated for latest design version yet
https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core/pipelines
- Zynq hardware in the loop test show no issues for after driver PCI and platform separation and latest VHDL sources updates.
- driver code has been periodically tested on 4.18.5-rt3 and 4.19 long term stable kernels.
- test of the patches before submission is run on 5.4 kernel
- the core has been integrated by Jaroslav Beran <[email protected]> into Intel FPGA based SoC used in the tester developed for Skoda auto at Department of Measurement, Faculty of Electrical Engineering, Czech Technical University https://meas.fel.cvut.cz/ . He has contributed feedback and fixes to the project.

The version 2 sent at 2019-02-27

The version 1 sent at 2019-02-22

Ondrej Ille has prepared the CTU CAN IP Core sources for new release. We are waiting with it for the driver review, our intention is to release IP when driver is reviewed and mainlined.

DKMS CTU CAN FD driver build by OpenBuildService to ease integration into Debian systems when driver is not provided by the distribution

https://build.opensuse.org/package/show/home:ppisa/ctu_can_fd

Jan Charvat <[email protected]> finished work to extend already mainlined QEMU SJA1000 and SocketCAN support to provide even CAN FD support and CTU CAN FD core support.

https://gitlab.fel.cvut.cz/canbus/qemu-canbus/-/tree/ctu-canfd

The patches has been sent for review to QEMU mainlining list.

Thanks in advance to all who help us to deliver the project into public.

Thanks to all colleagues, reviewers and other providing feedback, infrastructure and enthusiasm and motivation for open-source work.

Build infrastructure and hardware is provided by
Department of Control Engineering,
Faculty of Electrical Engineering,
Czech Technical University in Prague
https://dce.fel.cvut.cz/en

 .../bindings/net/can/ctu,ctucanfd.yaml        |   63 +
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 .../ctu/FSM_TXT_Buffer_user.png               |  Bin 0 -> 174807 bytes
 .../device_drivers/ctu/ctucanfd-driver.rst    |  638 ++++++++++
 drivers/net/can/Kconfig                       |    1 +
 drivers/net/can/Makefile                      |    1 +
 drivers/net/can/ctucanfd/Kconfig              |   35 +
 drivers/net/can/ctucanfd/Makefile             |   13 +
 drivers/net/can/ctucanfd/ctu_can_fd.c         | 1105 +++++++++++++++++
 drivers/net/can/ctucanfd/ctu_can_fd.h         |   87 ++
 drivers/net/can/ctucanfd/ctu_can_fd_frame.h   |  189 +++
 drivers/net/can/ctucanfd/ctu_can_fd_hw.c      |  790 ++++++++++++
 drivers/net/can/ctucanfd/ctu_can_fd_hw.h      |  916 ++++++++++++++
 drivers/net/can/ctucanfd/ctu_can_fd_pci.c     |  314 +++++
 .../net/can/ctucanfd/ctu_can_fd_platform.c    |  142 +++
 drivers/net/can/ctucanfd/ctu_can_fd_regs.h    |  971 +++++++++++++++
 16 files changed, 5267 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/can/ctu,ctucanfd.yaml
 create mode 100644 Documentation/networking/device_drivers/ctu/FSM_TXT_Buffer_user.png
 create mode 100644 Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst
 create mode 100644 drivers/net/can/ctucanfd/Kconfig
 create mode 100644 drivers/net/can/ctucanfd/Makefile
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd.c
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd.h
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_frame.h
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_hw.c
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_hw.h
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_pci.c
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_platform.c
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_regs.h
Signature · 1 line
2.20.1
author maintainer
#1 lore raw

PATCH v6 1/6 dt-bindings: vendor-prefix: add prefix for the Czech Technical University in Prague.

The Czech Technical University in Prague (CTU) is one of the biggest and oldest (founded 1707) technical universities in Europe. The abbreviation in Czech language is ČVUT according to official name in Czech language

České vysoké učení technické v Praze

The English translation

The Czech Technical University in Prague

The university pages in English

https://www.cvut.cz/en

---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/vendor-prefixes.yaml +2 -0
index 967e78c5ec0a..dedb10f1b250 100644
@@ -215,6 +215,8 @@ patternProperties:
     description: Hangzhou C-SKY Microsystems Co., Ltd
   "^csq,.*":
     description: Shenzen Chuangsiqi Technology Co.,Ltd.
+  "^ctu,.*":
+    description: Czech Technical University in Prague
   "^cubietech,.*":
     description: Cubietech, Ltd.
   "^cypress,.*":
Signature · 1 line
2.20.1
author maintainer
#2 lore raw

PATCH v6 2/6 dt-bindings: net: can: binding for CTU CAN FD open-source IP core.

In reply to Pavel Pisa

The device-tree bindings for open-source/open-hardware CAN FD IP core designed at the Czech Technical University in Prague.

CTU CAN FD IP core and other CTU CAN bus related projects listing and documentation page

http://canbus.pages.fel.cvut.cz/

---
 .../bindings/net/can/ctu,ctucanfd.yaml        | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/can/ctu,ctucanfd.yaml
Documentation/devicetree/bindings/net/can/ctu,ctucanfd.yaml new file +63 -0
new file mode 100644
index 000000000000..5113bb419ec1
@@ -0,0 +1,63 @@
+# 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/Progdokum.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 <[email protected]>
+  - Ondrej Ille <[email protected]>
+  - Martin Jerabek <[email protected]>
+
+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>;
+    };
Signature · 1 line
2.20.1
#3 lore raw

Re: [PATCH v6 2/6] dt-bindings: net: can: binding for CTU CAN FD open-source IP core.

Quoted 10 lines · Pavel Pisa

The device-tree bindings for open-source/open-hardware CAN FD IP core designed at the Czech Technical University in Prague.

CTU CAN FD IP core and other CTU CAN bus related projects listing and documentation page

http://canbus.pages.fel.cvut.cz/

1,2: Acked-by: Pavel Machek <[email protected]>

Signature · 1 line
http://www.livejournal.com/~pavelmachek
author maintainer
#4 lore raw

PATCH v6 3/6 can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.

In reply to Pavel Pisa

From: Martin Jerabek <[email protected]>

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 FGA based PCI Express board is available from project (https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd).

More about CAN bus related projects used and developed at CTU FEE at
http://canbus.pages.fel.cvut.cz/ .

---
 drivers/net/can/Kconfig                     |    1 +
 drivers/net/can/Makefile                    |    1 +
 drivers/net/can/ctucanfd/Kconfig            |   15 +
 drivers/net/can/ctucanfd/Makefile           |    7 +
 drivers/net/can/ctucanfd/ctu_can_fd.c       | 1105 +++++++++++++++++++
 drivers/net/can/ctucanfd/ctu_can_fd.h       |   87 ++
 drivers/net/can/ctucanfd/ctu_can_fd_frame.h |  189 ++++
 drivers/net/can/ctucanfd/ctu_can_fd_hw.c    |  790 +++++++++++++
 drivers/net/can/ctucanfd/ctu_can_fd_hw.h    |  916 +++++++++++++++
 drivers/net/can/ctucanfd/ctu_can_fd_regs.h  |  971 ++++++++++++++++
 10 files changed, 4082 insertions(+)
 create mode 100644 drivers/net/can/ctucanfd/Kconfig
 create mode 100644 drivers/net/can/ctucanfd/Makefile
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd.c
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd.h
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_frame.h
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_hw.c
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_hw.h
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_regs.h
drivers/net/can/Kconfig +1 -0
index 17c166cc8482..458afc4b81f2 100644
@@ -168,6 +168,7 @@ config PCH_CAN
 
 source "drivers/net/can/c_can/Kconfig"
 source "drivers/net/can/cc770/Kconfig"
+source "drivers/net/can/ctucanfd/Kconfig"
 source "drivers/net/can/ifi_canfd/Kconfig"
 source "drivers/net/can/m_can/Kconfig"
 source "drivers/net/can/mscan/Kconfig"
drivers/net/can/Makefile +1 -0
index 22164300122d..28b39cd122f0 100644
@@ -21,6 +21,7 @@ obj-y				+= softing/
 obj-$(CONFIG_CAN_AT91)		+= at91_can.o
 obj-$(CONFIG_CAN_CC770)		+= cc770/
 obj-$(CONFIG_CAN_C_CAN)		+= c_can/
+obj-$(CONFIG_CAN_CTUCANFD)	+= ctucanfd/
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 obj-$(CONFIG_CAN_IFI_CANFD)	+= ifi_canfd/
drivers/net/can/ctucanfd/Kconfig new file +15 -0
new file mode 100644
index 000000000000..b6d47bba7150
@@ -0,0 +1,15 @@
+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-ctu_can_fd).
+	  Guidepost CTU FEE CAN bus projects page http://canbus.pages.fel.cvut.cz/ .
+
+if CAN_CTUCANFD
+
+endif
drivers/net/can/ctucanfd/Makefile new file +7 -0
new file mode 100644
index 000000000000..8d47008d0076
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for the CTU CAN-FD IP module drivers
+#
+
+obj-$(CONFIG_CAN_CTUCANFD) := ctucanfd.o
+ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o
drivers/net/can/ctucanfd/ctu_can_fd.c new file +1105 -0

1,105 lines not on this page · raw message

drivers/net/can/ctucanfd/ctu_can_fd.h new file +87 -0

87 lines not on this page · raw message

drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +189 -0

189 lines not on this page · raw message

drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +790 -0

790 lines not on this page · raw message

drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +916 -0

793 lines not on this page · raw message

drivers/net/can/ctucanfd/ctu_can_fd_regs.h new file +971 -0

971 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.20.1

Part of the diff is not shown here. View the raw message.

#5 lore raw

Re: [PATCH v6 3/6] can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.

Hi!

Quoted 9 lines

From: Martin Jerabek <[email protected]>

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 FGA based PCI Express board is available from project (https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd).

Is "FGA" a typo? Yes, it is.

Anyway, following link tells me:

Project 'canbus/pcie-ctu_can_fd' was moved to 'canbus/pcie-ctucanfd'. Please update any links and bookmarks that may still have the old path. Fixing it in Kconfig is more important.

drivers/net/can/ctucanfd/Kconfig line 15

Quoted 6 lines

+++ b/drivers/net/can/ctucanfd/Kconfig

drivers/net/can/ctucanfd/Kconfig new file +3 -0
@@ -0,0 +1,15 @@
 
+if CAN_CTUCANFD
+
+endif

Empty -> drop?

Review line 1

Quoted 7 lines

+++ b/drivers/net/can/ctucanfd/Makefile

(quoted diff) +3 -0
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
 
+++ b/drivers/net/can/ctucanfd/ctu_can_fd.c
@@ -0,0 +1,1105 @@
+// SPDX-License-Identifier: GPL-2.0-or-later

Having Makefile and sources with different licenses is rather unusual.

drivers/net/can/ctucanfd/ctu_can_fd.c line 56

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+static const char * const ctucan_state_strings[] = {
+	"CAN_STATE_ERROR_ACTIVE",
+	"CAN_STATE_ERROR_WARNING",
+	"CAN_STATE_ERROR_PASSIVE",
+	"CAN_STATE_BUS_OFF",
+	"CAN_STATE_STOPPED",
+	"CAN_STATE_SLEEPING"
+};

Put this near function that uses this?

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+/**
+ * ctucan_set_bittiming - CAN set bit timing routine
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the driver set bittiming routine.
+ * Return: 0 on success and failure value on error

drivers/net/can/ctucanfd/ctu_can_fd.c line 191

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +9 -0
+ */
 
+/**
+ * ctucan_chip_start - This routine starts the driver
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the drivers start routine.
+ *
+ * Return: 0 on success and failure value on error
+ */

Good documentation is nice, but repeating "This routine starts the driver" in "This is the drivers start routine." is not too helpful.

Quoted 11 lines

+/**
+ * ctucan_start_xmit - Starts the transmission
+ * @skb: sk_buff pointer that contains data to be Txed
+ * @ndev: Pointer to net_device structure
+ *
+ * This function is invoked from upper layers to initiate transmission. This
+ * function uses the next available free txbuf and populates their fields to
+ * start the transmission.
+ *
+ * Return: %NETDEV_TX_OK on success and failure value on error
+ */

Based on other documentation, I'd expect this to return -ESOMETHING on error, but it returns NETDEV_TX_BUSY.

drivers/net/can/ctucanfd/ctu_can_fd.c line 320

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+	/* Check if the TX buffer is full */
+	if (unlikely(!CTU_CAN_FD_TXTNF(ctu_can_get_status(&priv->p)))) {
+		netif_stop_queue(ndev);
+		netdev_err(ndev, "BUG!, no TXB free when queue awake!\n");
+		return NETDEV_TX_BUSY;
+	}

You call stop_queue() without spinlock...

drivers/net/can/ctucanfd/ctu_can_fd.c line 347

Quoted 11 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +11 -0
+	spin_lock_irqsave(&priv->tx_lock, flags);
+
+	ctucan_hw_txt_set_rdy(&priv->p, txb_id);
+
+	priv->txb_head++;
+
+	/* Check if all TX buffers are full */
+	if (!CTU_CAN_FD_TXTNF(ctu_can_get_status(&priv->p)))
+		netif_stop_queue(ndev);
+
+	spin_unlock_irqrestore(&priv->tx_lock, flags);

...and then with spinlock held. One of them is buggy.

Quoted 10 lines

+/**
+ * xcan_rx - Is called from CAN isr to complete the received
+ * frame processing
+ * @ndev: Pointer to net_device structure
+ *
+ * This function is invoked from the CAN isr(poll) to process the Rx frames. It
+ * does minimal processing and invokes "netif_receive_skb" to complete further
+ * processing.
+ * Return: 1 on success and 0 on failure.
+ */

Adapt to usual 0 / -EFOO?

Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +4 -0
+	/* Check for Arbitration Lost interrupt */
+	if (isr.s.ali) {
+		if (dologerr)
+			netdev_info(ndev, "  arbitration lost");

drivers/net/can/ctucanfd/ctu_can_fd.c line 508

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +10 -0
+		priv->can.can_stats.arbitration_lost++;
+		if (skb) {
+			cf->can_id |= CAN_ERR_LOSTARB;
+			cf->data[0] = CAN_ERR_LOSTARB_UNSPEC;
+		}
+	}
+
+	/* Check for Bus Error interrupt */
+	if (isr.s.bei) {
+		netdev_info(ndev, "  bus error");

Missing "if (dologerr)" here?

drivers/net/can/ctucanfd/ctu_can_fd.c line 544

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +10 -0
+static int ctucan_rx_poll(struct napi_struct *napi, int quota)
+{
+	struct net_device *ndev = napi->dev;
+	struct ctucan_priv *priv = netdev_priv(ndev);
+	int work_done = 0;
+	union ctu_can_fd_status status;
+	u32 framecnt;
+
+	framecnt = ctucan_hw_get_rx_frame_count(&priv->p);
+	netdev_dbg(ndev, "rx_poll: %d frames in RX FIFO", framecnt);

This will be rather noisy, right?

drivers/net/can/ctucanfd/ctu_can_fd.c line 558

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+	/* Check for RX FIFO Overflow */
+	status = ctu_can_get_status(&priv->p);
+	if (status.s.dor) {
+		struct net_device_stats *stats = &ndev->stats;
+		struct can_frame *cf;
+		struct sk_buff *skb;
+
+		netdev_info(ndev, "  rx fifo overflow");

And this goes at different loglevel, which will be confusing?

drivers/net/can/ctucanfd/ctu_can_fd.c line 610

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +5 -0
+/**
+ * xcan_tx_interrupt - Tx Done Isr
+ * @ndev:	net_device pointer
+ */
+static void ctucan_tx_interrupt(struct net_device *ndev)

Mismatch between code and docs.

drivers/net/can/ctucanfd/ctu_can_fd.c line 619

Quoted 1 line
drivers/net/can/ctucanfd/ctu_can_fd.c new file +1 -0
+	netdev_dbg(ndev, "%s", __func__);

This is inconsistent with other debugging.... and perhaps it is time to remove this kind of debugging for merge.

drivers/net/can/ctucanfd/ctu_can_fd.c line 729

Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +4 -0
+/**
+ * xcan_interrupt - CAN Isr
+ */
+static irqreturn_t ctucan_interrupt(int irq, void *dev_id)

Inconsistent.

drivers/net/can/ctucanfd/ctu_can_fd.c line 770

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +5 -0
+		/* Error interrupts */
+		if (isr.s.ewli || isr.s.fcsi || isr.s.ali) {
+			union ctu_can_fd_int_stat ierrmask = { .s = {
+				  .ewli = 1, .fcsi = 1, .ali = 1, .bei = 1 } };
+			icr.u32 = isr.u32 & ierrmask.u32;

We normally do bit arithmetics instead of this.

drivers/net/can/ctucanfd/ctu_can_fd.c line 802

Quoted 7 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +7 -0
+	{
+		union ctu_can_fd_int_stat imask;
+
+		imask.u32 = 0xffffffff;
+		ctucan_hw_int_ena_clr(&priv->p, imask);
+		ctucan_hw_int_mask_set(&priv->p, imask);
+	}

More like this. Plus avoid block here...?

Quoted 6 lines

+/**
+ * ctucan_close - Driver close routine
+ * @ndev: Pointer to net_device structure
+ *
+ * Return: 0 always
+ */

You see, this is better. No need to say "Driver close routine" twice. Now, make the rest consistent :-).

drivers/net/can/ctucanfd/ctu_can_fd.c line 984

Quoted 2 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +2 -0
+EXPORT_SYMBOL(ctucan_suspend);
+EXPORT_SYMBOL(ctucan_resume);

_GPL?

And what kind of multi-module stuff are you doing that you need symbols exported?

drivers/net/can/ctucanfd/ctu_can_fd.c line 989

Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +4 -0
+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))
+{

Splitting/simplifying this somehow would be good.

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 49

Quoted 3 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +3 -0
+/* Register descriptions: */
+union ctu_can_fd_frame_form_w {
+	uint32_t u32;

u32, as you write elsewhere.

Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +4 -0
+	struct ctu_can_fd_frame_form_w_s {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+  /* FRAME_FORM_W */
+		uint32_t dlc                     : 4;

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 63

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +10 -0
+		uint32_t reserved_4              : 1;
+		uint32_t rtr                     : 1;
+		uint32_t ide                     : 1;
+		uint32_t fdf                     : 1;
+		uint32_t reserved_8              : 1;
+		uint32_t brs                     : 1;
+		uint32_t esi_rsv                 : 1;
+		uint32_t rwcnt                   : 5;
+		uint32_t reserved_31_16         : 16;
+#else

I believe you should simply avoid using bitfields.

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 125

Quoted 7 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +7 -0
+union ctu_can_fd_timestamp_l_w {
+	uint32_t u32;
+	struct ctu_can_fd_timestamp_l_w_s {
+  /* TIMESTAMP_L_W */
+		uint32_t time_stamp_31_0        : 32;
+	} s;
+};

This is crazy.

Quoted 7 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +7 -0
+union ctu_can_fd_data_5_8_w {
+	uint32_t u32;
+	struct ctu_can_fd_data_5_8_w_s {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+  /* DATA_5_8_W */
+		uint32_t data_5                  : 8;
+		uint32_t data_6                  : 8;

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 169

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +10 -0
+		uint32_t data_7                  : 8;
+		uint32_t data_8                  : 8;
+#else
+		uint32_t data_8                  : 8;
+		uint32_t data_7                  : 8;
+		uint32_t data_6                  : 8;
+		uint32_t data_5                  : 8;
+#endif
+	} s;
+};

even more crazy.

Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +4 -0
+#ifdef __KERNEL__
+# include <linux/can/dev.h>
+#else
+/* The hardware registers mapping and low level layer should build

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 44

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +10 -0
+ * in userspace to allow development and verification of CTU CAN IP
+ * core VHDL design when loaded into hardware. Debugging hardware
+ * from kernel driver is really difficult, leads to system stucks
+ * by error reporting etc. Testing of exactly the same code
+ * in userspace together with headers generated automatically
+ * generated from from IP-XACT/cactus helps to driver to hardware
+ * and QEMU emulation model consistency keeping.
+ */
+# include "ctu_can_fd_linux_defs.h"
+#endif

Please remove non-kernel code for merge.

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 53

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+void ctucan_hw_write32(struct ctucan_hw_priv *priv,
+		       enum ctu_can_fd_can_registers reg, u32 val)
+{
+	iowrite32(val, priv->mem_base + reg);
+}

And get rid of this kind of abstraction layer.

Quoted 1 line

+// TODO: rename or do not depend on previous value of id

TODO: grep for TODO and C++ comments before attempting merge.

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 118

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+static bool ctucan_hw_len_to_dlc(u8 len, u8 *dlc)
+{
+	*dlc = can_len2dlc(len);
+	return true;
+}

Compared to how well other code is documented... This one is voodoo.

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 173

Quoted 13 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +13 -0
+bool ctucan_hw_set_ret_limit(struct ctucan_hw_priv *priv, bool enable, u8 limit)
+{
+	union ctu_can_fd_mode_settings reg;
+
+	if (limit > CTU_CAN_FD_RETR_MAX)
+		return false;
+
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_MODE);
+	reg.s.rtrle = enable ? RTRLE_ENABLED : RTRLE_DISABLED;
+	reg.s.rtrth = limit & 0xF;
+	priv->write_reg(priv, CTU_CAN_FD_MODE, reg.u32);
+	return true;
+}

As elsewhere, I'd suggest 0/-ERRNO.

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 185

Quoted 11 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +10 -0
+void ctucan_hw_set_mode_reg(struct ctucan_hw_priv *priv,
+			    const struct can_ctrlmode *mode)
+{
+	u32 flags = mode->flags;
+	union ctu_can_fd_mode_settings reg;
+
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_MODE);
 
+	if (mode->mask & CAN_CTRLMODE_LOOPBACK)
+		reg.s.ilbp = flags & CAN_CTRLMODE_LOOPBACK ?
+					INT_LOOP_ENABLED : INT_LOOP_DISABLED;

Not sure what is going on here, but having mode->flags in same format as hardware register would help...?

Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +4 -0
+	switch (fnum) {
+	case CTU_CAN_FD_FILTER_A:
+		if (reg.s.sfa)
+			return true;

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 438

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +10 -0
+	break;
+	case CTU_CAN_FD_FILTER_B:
+		if (reg.s.sfb)
+			return true;
+	break;
+	case CTU_CAN_FD_FILTER_C:
+		if (reg.s.sfc)
+			return true;
+	break;
+	}

Check indentation of break statemnts, also elsewhere in this file

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 450

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +8 -0
+bool ctucan_hw_get_range_filter_support(struct ctucan_hw_priv *priv)
+{
+	union ctu_can_fd_filter_control_filter_status reg;
+
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_FILTER_CONTROL);
+
+	if (reg.s.sfr)
+		return true;

return !!reg.s.sfr; ?

Quoted 2 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +2 -0
+enum ctu_can_fd_tx_status_tx1s ctucan_hw_get_tx_status(struct ctucan_hw_priv
+							*priv, u8 buf)

...

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 621

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+	default:
+		status = ~0;
+	}
+	return (enum ctu_can_fd_tx_status_tx1s)status;
+}

Is ~0 in the enum?

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 658

Quoted 1 line
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +1 -0
+	// TODO: use named constants for the command

TODO...

Quoted 1 line

+// TODO: AL_CAPTURE and ERROR_CAPTURE

...

drivers/net/can/ctucanfd/ctu_can_fd_hw.h line 37

Quoted 3 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +3 -0
+#if defined(__LITTLE_ENDIAN_BITFIELD) == defined(__BIG_ENDIAN_BITFIELD)
+# error __BIG_ENDIAN_BITFIELD or __LITTLE_ENDIAN_BITFIELD must be defined.
+#endif

:-).

drivers/net/can/ctucanfd/ctu_can_fd_hw.h line 63

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +5 -0
+// True if Core is transceiver of current frame
+#define CTU_CAN_FD_IS_TRANSMITTER(stat) (!!(stat).ts)
+
+// True if Core is receiver of current frame
+#define CTU_CAN_FD_IS_RECEIVER(stat) (!!(stat).s.rxs)

Why not, documentation is nice. But it is in big contrast to other parts of code where there's no docs at all.

drivers/net/can/ctucanfd/ctu_can_fd_hw.h line 134

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +10 -0
+struct ctucan_hw_priv;
+#ifndef ctucan_hw_priv
+struct ctucan_hw_priv {
+	void __iomem *mem_base;
+	u32 (*read_reg)(struct ctucan_hw_priv *priv,
+			enum ctu_can_fd_can_registers reg);
+	void (*write_reg)(struct ctucan_hw_priv *priv,
+			  enum ctu_can_fd_can_registers reg, u32 val);
+};
+#endif

Should not be needed in kernel.

Quoted 6 lines

+/**
+ * ctucan_hw_read_rx_word - Reads one word of CAN Frame from RX FIFO Buffer.
+ *
+ * @priv: Private info
+ *
+ * Return: One wword of received frame

Typo 'word'.

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 3

Quoted 5 lines

+++ b/drivers/net/can/ctucanfd/ctu_can_fd_regs.h

drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +3 -0
@@ -0,0 +1,971 @@
+
+/* This file is autogenerated, DO NOT EDIT! */
+

Yay. How is that supposed to work after merge?

Best regards,
Pavel

Signature · 1 line
http://www.livejournal.com/~pavelmachek
author maintainer
#6 lore raw

Re: [PATCH v6 3/6] can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.

Hello Pavel,

thanks for review.

For everybody: the amount of code, analyses etc. is really huge. If you do not have time and consider this discussion as lost of your time and or badwidth send me a note. I will remove your from the recipients list and if you think that some lists should be omitted as well, please give me notice too. Same if you want to receive only final resolutions, patches when they pass through some of the lists.

Quoted 13 lines · On Thursday 22 of October 2020 13:02:13 Pavel Machek wrote:

Hi!

Quoted 10 lines

From: Martin Jerabek <[email protected]>

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 FGA based PCI Express board is available from project (https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd).

Quoted 1 line

Is "FGA" a typo? Yes, it is.

Done, thanks for catching.

I really need to force some of other people from the project and follow up project to read all original Matin Jerabek's and mine texts. I am blind to many of these typos as I see same text many times.

Quoted 5 lines

Anyway, following link tells me:

Project 'canbus/pcie-ctu_can_fd' was moved to 'canbus/pcie-ctucanfd'. Please update any links and bookmarks that may still have the old path. Fixing it in Kconfig is more important.

Done, move is result of some more steps to name unification.

Quoted 8 lines

drivers/net/can/ctucanfd/Kconfig line 15

Quoted 6 lines

+++ b/drivers/net/can/ctucanfd/Kconfig

drivers/net/can/ctucanfd/Kconfig new file +3 -0
@@ -0,0 +1,15 @@
 
+if CAN_CTUCANFD
+
+endif

Empty -> drop?

Considering as appropriate after other patches comments read. If you have other idea for patches series build give me a hint.

Quoted 9 lines

Review line 1

Quoted 7 lines

+++ b/drivers/net/can/ctucanfd/Makefile

(quoted diff) +3 -0
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
 
+++ b/drivers/net/can/ctucanfd/ctu_can_fd.c
@@ -0,0 +1,1105 @@
+// SPDX-License-Identifier: GPL-2.0-or-later

Having Makefile and sources with different licenses is rather unusual.

Makefile changed to GPL-2.0-or-later.
I do not consider use of Linux specific Makefile outside GPL 2 only Linux kernel tree. But C sources are important for us even in userspace tests and possible future projects.

Quoted 10 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 56

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+static const char * const ctucan_state_strings[] = {
+	"CAN_STATE_ERROR_ACTIVE",
+	"CAN_STATE_ERROR_WARNING",
+	"CAN_STATE_ERROR_PASSIVE",
+	"CAN_STATE_BUS_OFF",
+	"CAN_STATE_STOPPED",
+	"CAN_STATE_SLEEPING"
+};

Put this near function that uses this?

I prefer defines at start of the file, but I agree that in this case it is different case and used only in ctucan_state_to_str . I would prefer to move function up after array.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +7 -0
+/**
+ * ctucan_set_bittiming - CAN set bit timing routine
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the driver set bittiming routine.
+ * Return: 0 on success and failure value on error
+ */
Quoted 11 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 191

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+/**
+ * ctucan_chip_start - This routine starts the driver
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the drivers start routine.
+ *
+ * Return: 0 on success and failure value on error
+ */

Good documentation is nice, but repeating "This routine starts the driver" in "This is the drivers start routine." is not too helpful.

OK, initially probably more or less placeholder to add more infomation. I will remove it.

Quoted 12 lines
Quoted 11 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+/**
+ * ctucan_start_xmit - Starts the transmission
+ * @skb:	sk_buff pointer that contains data to be Txed
+ * @ndev:	Pointer to net_device structure
+ *
+ * This function is invoked from upper layers to initiate transmission.

This + * function uses the next available free txbuf and populates their fields to + * start the transmission.
+ *
+ * Return: %NETDEV_TX_OK on success and failure value on error
+ */

Quoted 2 lines

Based on other documentation, I'd expect this to return -ESOMETHING on error, but it returns NETDEV_TX_BUSY.

I add information about explicit error/need for postpone type.

Quoted 9 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 320

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+	/* Check if the TX buffer is full */
+	if (unlikely(!CTU_CAN_FD_TXTNF(ctu_can_get_status(&priv->p)))) {
+		netif_stop_queue(ndev);
+		netdev_err(ndev, "BUG!, no TXB free when queue awake!\n");
+		return NETDEV_TX_BUSY;
+	}

You call stop_queue() without spinlock...

Quoted 13 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 347

Quoted 11 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +11 -0
+	spin_lock_irqsave(&priv->tx_lock, flags);
+
+	ctucan_hw_txt_set_rdy(&priv->p, txb_id);
+
+	priv->txb_head++;
+
+	/* Check if all TX buffers are full */
+	if (!CTU_CAN_FD_TXTNF(ctu_can_get_status(&priv->p)))
+		netif_stop_queue(ndev);
+
+	spin_unlock_irqrestore(&priv->tx_lock, flags);

...and then with spinlock held. One of them is buggy.

I did not feel it that way initially. But may it be there is a problem.

I expect that NET core does not invoke net_device_ops::ndo_start_xmit aka ctucan_start_xmit when previous invocation is in progress still. I think I have even checked it in the sources.
So we can do check for free message buffer in hardware without locking. If there is no space we stop further transmit
but then there is something wrong anyway, because when there was xmit started then there was already free space in hardware. So generally this is some fatal error in logic or hardware or driver. I hope that concurrent run of netif_wake_queue internal functions to ctucan_start_xmit is prevented by NET core logic and locking. So even if some buffer becomes free in meanwhile and invokes netif_wake_queue, it waits with next ctucan_start_xmit invocation till previous one finishes.

Incorrect concurrence can happen if ctucan_hw_txt_set_rdy and frame transmission finishes before ctucan_start_xmit finishes. In such case there appear incorrect sequence of manipulation with hardware and counting occupied and free buffers. So buffer counting is protected by spinlock....

If this is the last empty TX buffer filled by xmit then further xmit has to be stopped. So we call netif_stop_queue(ndev); In the theory, it can be called after spin lock release (if netif_wake_queue is synchronized). So if mine analysis is right then I can check HW for empty buffer under spinlock, keep result and call netif_stop_queue later. It seems that netif_stop_queue is called in other drivers with irq locks held. So there should not be a problem, netif_stop_queue locking is orthogonal to &priv->tx_lock which protects HW and slots counting.

But if somebody can check and clarify that my idea is wrong or confirm, that moving out of spinlock section is correct way to go, I would be happy. Many CAN controllers use only single buffer for TX so they do not solve these conditions. These which solve more parallel Tx buffers seems to not prove me wrong according to my reading.

Quoted 11 lines
Quoted 10 lines

+/**
+ * xcan_rx - Is called from CAN isr to complete the received
+ * frame processing
+ * @ndev: Pointer to net_device structure
+ *
+ * This function is invoked from the CAN isr(poll) to process the Rx frames. It + * does minimal processing and invokes "netif_receive_skb" to complete further + * processing.
+ * Return: 1 on success and 0 on failure.
+ */

Quoted 1 line

Adapt to usual 0 / -EFOO?

OK

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+	/* Check for Arbitration Lost interrupt */
+	if (isr.s.ali) {
+		if (dologerr)
+			netdev_info(ndev, "  arbitration lost");
+		priv->can.can_stats.arbitration_lost++;
+		if (skb) {
+			cf->can_id |= CAN_ERR_LOSTARB;
+			cf->data[0] = CAN_ERR_LOSTARB_UNSPEC;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 508

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+		}
+	}
+
+	/* Check for Bus Error interrupt */
+	if (isr.s.bei) {
+		netdev_info(ndev, "  bus error");

Missing "if (dologerr)" here?

Intention was to left this one to appear without rate limit, it is really indication of bigger problem. But on the other hand without dologerr would be quite short/unclear, but does not overflow the log buffers... We would discuss what to do with my colleagues, suggestions welcomed.

Quoted 4 lines
Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +4 -0
+static int ctucan_rx_poll(struct napi_struct *napi, int quota)
+{
+	struct net_device *ndev = napi->dev;
+	struct ctucan_priv *priv = netdev_priv(ndev);
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 544

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+	int work_done = 0;
+	union ctu_can_fd_status status;
+	u32 framecnt;
+
+	framecnt = ctucan_hw_get_rx_frame_count(&priv->p);
+	netdev_dbg(ndev, "rx_poll: %d frames in RX FIFO", framecnt);

This will be rather noisy, right?

It has use to debug during development but may be it should be removed or controlled by other option.

Quoted 10 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 558

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+	/* Check for RX FIFO Overflow */
+	status = ctu_can_get_status(&priv->p);
+	if (status.s.dor) {
+		struct net_device_stats *stats = &ndev->stats;
+		struct can_frame *cf;
+		struct sk_buff *skb;
+
+		netdev_info(ndev, "  rx fifo overflow");

And this goes at different loglevel, which will be confusing?

I add prefix there, this condition is more important to be noticed.

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 610

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +5 -0
+/**
+ * xcan_tx_interrupt - Tx Done Isr
+ * @ndev:	net_device pointer
+ */
+static void ctucan_tx_interrupt(struct net_device *ndev)

Mismatch between code and docs.

Corrected.

Quoted 4 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 619

Quoted 1 line
drivers/net/can/ctucanfd/ctu_can_fd.c new file +1 -0
+	netdev_dbg(ndev, "%s", __func__);

This is inconsistent with other debugging.... and perhaps it is time to remove this kind of debugging for merge.

OK

Quoted 6 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 729

Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +4 -0
+/**
+ * xcan_interrupt - CAN Isr
+ */
+static irqreturn_t ctucan_interrupt(int irq, void *dev_id)

Inconsistent.

Corrected

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 770

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +5 -0
+		/* Error interrupts */
+		if (isr.s.ewli || isr.s.fcsi || isr.s.ali) {
+			union ctu_can_fd_int_stat ierrmask = { .s = {
+				  .ewli = 1, .fcsi = 1, .ali = 1, .bei = 1 } };
+			icr.u32 = isr.u32 & ierrmask.u32;

We normally do bit arithmetics instead of this.

This is attempt to use only HW definitions generated from registers definition in IPXACT format

https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core/-/blob/master/spec/CTU/ip/CAN_FD_IP_Core/2.1/CAN_FD_IP_Core.2.1.xml

Which I consider as good option which should be preserved. I prefer to have only singe source of infomation which is kept with rest in automatic sync.

Quoted 9 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 802

Quoted 7 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +7 -0
+	{
+		union ctu_can_fd_int_stat imask;
+
+		imask.u32 = 0xffffffff;
+		ctucan_hw_int_ena_clr(&priv->p, imask);
+		ctucan_hw_int_mask_set(&priv->p, imask);
+	}

More like this. Plus avoid block here...?

Blocks is to document that imask is really local for these two lines, no need to look for it elsewhere in the function. But I can move declaration to start of the function.

Quoted 7 lines
Quoted 6 lines

+/**
+ * ctucan_close - Driver close routine
+ * @ndev: Pointer to net_device structure
+ *
+ * Return: 0 always
+ */

Quoted 7 lines

You see, this is better. No need to say "Driver close routine" twice. Now, make the rest consistent :-).

drivers/net/can/ctucanfd/ctu_can_fd.c line 984

Quoted 2 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +2 -0
+EXPORT_SYMBOL(ctucan_suspend);
+EXPORT_SYMBOL(ctucan_resume);

_GPL?

Should we be so strict??? Ondrej Ille can provide his opinion there.

Quoted 9 lines

And what kind of multi-module stuff are you doing that you need symbols exported?

drivers/net/can/ctucanfd/ctu_can_fd.c line 989

Quoted 4 lines

+int ctucan_probe_common(struct device *dev, void __iomem *addr, int irq,
unsigned int ntxbufs, + unsigned long can_clk_rate, int pm_enable_call,

drivers/net/can/ctucanfd/ctu_can_fd.c new file +2 -0
+			void (*set_drvdata_fnc)(struct device *dev, struct net_device *ndev))
+{

Splitting/simplifying this somehow would be good.

This is attempt to hide the most of all other functions from bus integration modules. Prototype is not nice, but it is only one of a few function exported. The arguments can be passed through structure. May it be better???

Quoted 5 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 49

Quoted 3 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +3 -0
+/* Register descriptions: */
+union ctu_can_fd_frame_form_w {
+	uint32_t u32;

u32, as you write elsewhere.

I would be happy, if we can keep uint32_t there.
The header files are generated from IPXACT and are intended to be used even outside of Linux kernel. I.e. QEMU

https://git.qemu.org/?p=qemu.git;a=blob;f=hw/net/can/ctu_can_fd_regs.h

Easy way to compare these together is great to keep consistency. Adaptation of generation tools to run in multiple modes would be overhead. So if the uint32_t type in HW definition is acceptable for Linux kernel it would save us lot of headaches and possible errors in the future.

Enforce u32 in all other projects in form visible
from this and other header files is problematic.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +8 -0
+	struct ctu_can_fd_frame_form_w_s {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+  /* FRAME_FORM_W */
+		uint32_t dlc                     : 4;
+		uint32_t reserved_4              : 1;
+		uint32_t rtr                     : 1;
+		uint32_t ide                     : 1;
+		uint32_t fdf                     : 1;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 63

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +6 -0
+		uint32_t reserved_8              : 1;
+		uint32_t brs                     : 1;
+		uint32_t esi_rsv                 : 1;
+		uint32_t rwcnt                   : 5;
+		uint32_t reserved_31_16         : 16;
+#else

I believe you should simply avoid using bitfields.

I would prefer style I have negotiated with my students for generated HW description for RTEMS TI TMS570 support

https://git.rtems.org/rtems/tree/bsps/arm/tms570/include/bsp/ti_herc/reg_dcan.h

but Ondrej Ille argued that the macro names are long and you need more of them or ?: hack to encode filed position and its length. Which is correct arguments. There are more Linux kernel files using this style

grep -r __LITTLE_ENDIAN_BITFIELD include

so we agreed that it should be acceptable. Big and little endian part match is guaranteed because files are autogenerated. Actual access and move to bitfiled typed variable is done through right IO access functions and offsets are given by defines. So there are no registers HW access overlay structures used.

Quoted 9 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 125

Quoted 7 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +7 -0
+union ctu_can_fd_timestamp_l_w {
+	uint32_t u32;
+	struct ctu_can_fd_timestamp_l_w_s {
+  /* TIMESTAMP_L_W */
+		uint32_t time_stamp_31_0        : 32;
+	} s;
+};

This is crazy.

Hmmm, we can add special rules to tools to skip some special cases but actual files exactly math what is in documentation and VHDL sources and registers implementation. See page 61 / PDF 67 of

http://canbus.pages.fel.cvut.cz/ctucanfd_ip_core/Progdokum.pdf

Yes there is still space for improvements but we need to have acceptable base for already running applications.

Quoted 11 lines
Quoted 11 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +11 -0
+union ctu_can_fd_data_5_8_w {
+	uint32_t u32;
+	struct ctu_can_fd_data_5_8_w_s {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+  /* DATA_5_8_W */
+		uint32_t data_5                  : 8;
+		uint32_t data_6                  : 8;
+		uint32_t data_7                  : 8;
+		uint32_t data_8                  : 8;
+#else
+		uint32_t data_8                  : 8;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 169

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +6 -0
+		uint32_t data_7                  : 8;
+		uint32_t data_6                  : 8;
+		uint32_t data_5                  : 8;
+#endif
+	} s;
+};

even more crazy.

Data part other then DATA_1_4_W is not referenced from the driver. And yes, I would like more DATA_0_3_W etc... But question is indexing in the standards. I have tried to help the project to move into direction to be sustainable in our small team and enhance consistency. But we have not resources to start whole
work from scratch again and due to effort into testing, analyses etc. it would be extremely hard to get into same state again. And I hope that there are not many really painfull limits for future enhancements.

The design can be extended for 8 TX frames for examle. Above that there would be problem with atomic priority management. But this should be enough for most applications and if sequential stream at some priority is required then we can combine core with DMA. The same for RX. I plan DMA there. Actual design with SW controllable priorities allows us to maintain single TX FIFO but even more dynamic multiqueue FIFOs. I want to have time to experiment in these directions, but until the code is mainlined it would be really headache to keep additional features above base changing according to reviewer requests. So when there is this really simple minimal base for CAN/CAN FD functionality agreed upon then we want to develop extensions in more directions interresting for us and our applications.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +8 -0
+#ifdef __KERNEL__
+# include <linux/can/dev.h>
+#else
+/* The hardware registers mapping and low level layer should build
+ * in userspace to allow development and verification of CTU CAN IP
+ * core VHDL design when loaded into hardware. Debugging hardware
+ * from kernel driver is really difficult, leads to system stucks
+ * by error reporting etc. Testing of exactly the same code
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 44

Quoted 6 lines

+ * in userspace together with headers generated automatically
+ * generated from from IP-XACT/cactus helps to driver to hardware
+ * and QEMU emulation model consistency keeping.
+ */

drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +2 -0
+# include "ctu_can_fd_linux_defs.h"
+#endif

Please remove non-kernel code for merge.

This is only one line which allows us to run code test in userspace which is of big help to keep code consistent. This part of kernel driver sources is used during userspace test of hardware registers implemented right in each FPGA build run so it checks that SW and HW matches

https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top/-/jobs/73445

See the line cantest/test_regtest.py::test_regtest PASSED

If you confirm that it is really required to remove this single include ifdef then we remove it. But it would break our tooling and we have to patching during tests or keep in sync two versions of this C file which has to be prepared manually, it cannot be autogenerated, because it holds algorithmic description how to access structures defined by hardware.

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 53

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+void ctucan_hw_write32(struct ctucan_hw_priv *priv,
+		       enum ctu_can_fd_can_registers reg, u32 val)
+{
+	iowrite32(val, priv->mem_base + reg);
+}

And get rid of this kind of abstraction layer.

We need big and little endian support. This works and is tiny. I can try to switch to linux/regmap.h, but it seems to me as a monster and I do not understand it fully yet.

MCAN uses similar approach, common part

static inline u32 m_can_read(struct m_can_classdev *cdev, enum m_can_reg reg)

{
        return cdev->ops->read_reg(cdev, reg);
}

platform bus specific one

static u32 iomap_read_reg(struct m_can_classdev *cdev, int reg)

{
        struct m_can_plat_priv *priv = cdev->device_data;

        return readl(priv->base + reg);
}

So I think that it is not against actual conventions.

When the CTU CAN FD IP core driver runs on big endian systems then PCI bus is usually still mapped little endian way but platform IP mapping is native big endian. Actual driver automatically decides according to CTU_CAN_FD_DEVICE_ID register read.

Quoted 3 lines
Quoted 1 line

+// TODO: rename or do not depend on previous value of id

TODO: grep for TODO and C++ comments before attempting merge.

That is my mistake, but some of these are really there for future development or cleanups, some only remarks. As I have said I do not consider projects as perfect or finished but as in state usable for broader community and when format is really agreed/accepted then we can continue. But I do not want waste my time to work above code base which has to be changed again and again. So there are much more TODOs in my head.

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 118

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+static bool ctucan_hw_len_to_dlc(u8 len, u8 *dlc)
+{
+	*dlc = can_len2dlc(len);
+	return true;
+}

Compared to how well other code is documented... This one is voodoo.

OK, I have invested lot of time after Marin Jerabek's submission of diploma theses to make code really documented etc.. I add there something even that it is really simple use of can_len2dlc. May it be, we can use that directly. It is Linux specific, but clean.

Quoted 7 lines
Quoted 7 lines

+bool ctucan_hw_set_ret_limit(struct ctucan_hw_priv *priv, bool enable, u8 limit) +{

drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+	union ctu_can_fd_mode_settings reg;
+
+	if (limit > CTU_CAN_FD_RETR_MAX)
+		return false;
+
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 173

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +6 -0
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_MODE);
+	reg.s.rtrle = enable ? RTRLE_ENABLED : RTRLE_DISABLED;
+	reg.s.rtrth = limit & 0xF;
+	priv->write_reg(priv, CTU_CAN_FD_MODE, reg.u32);
+	return true;
+}

As elsewhere, I'd suggest 0/-ERRNO.

Hmm, generally there is attempt to keep ctu_can_fd_hw.c dependant only on generated hardware description and independent of OS specific constructs. It helps its testing in other environments. Yes, there exists even Windows drier for other SkodaAuto project and CTU CAN FD integration which runs same ctu_can_fd_hw.c And it is the only part which directly depends on HW registers placement. We do not go typical direction of Windows code and then adaptation for Linux. We try to be OS agnostic in lowest level HW adaptation and provide minimal well matching driver which does not take care of generated sources.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +7 -0
+void ctucan_hw_set_mode_reg(struct ctucan_hw_priv *priv,
+			    const struct can_ctrlmode *mode)
+{
+	u32 flags = mode->flags;
+	union ctu_can_fd_mode_settings reg;
+
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_MODE);
Quoted 6 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 185

Quoted 3 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +3 -0
+	if (mode->mask & CAN_CTRLMODE_LOOPBACK)
+		reg.s.ilbp = flags & CAN_CTRLMODE_LOOPBACK ?
+					INT_LOOP_ENABLED : INT_LOOP_DISABLED;

Not sure what is going on here, but having mode->flags in same format as hardware register would help...?

In this case we prefer to use defines which match Linux SocketCAN defines (CAN_CTRLMODE_LOOPBACK,...) and translate them to HW specific bits only inside ctu_can_fd_hw.c to not pollute driver by hardware specific details. As you can see, we use Linux specific define and adapt other builds to match Linux convention.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +8 -0
+	switch (fnum) {
+	case CTU_CAN_FD_FILTER_A:
+		if (reg.s.sfa)
+			return true;
+	break;
+	case CTU_CAN_FD_FILTER_B:
+		if (reg.s.sfb)
+			return true;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 438

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +6 -0
+	break;
+	case CTU_CAN_FD_FILTER_C:
+		if (reg.s.sfc)
+			return true;
+	break;
+	}

Check indentation of break statemnts, also elsewhere in this file

OK, I look at examples, I am not sure if I have overlooked checkpatch.pl warnings... I think that not. So it seems to be acceptabe for some case at least in 4.19 RT.

Quoted 10 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 450

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +8 -0
+bool ctucan_hw_get_range_filter_support(struct ctucan_hw_priv *priv)
+{
+	union ctu_can_fd_filter_control_filter_status reg;
+
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_FILTER_CONTROL);
+
+	if (reg.s.sfr)
+		return true;

return !!reg.s.sfr; ?

OK.

Quoted 5 lines
Quoted 2 lines

+enum ctu_can_fd_tx_status_tx1s ctucan_hw_get_tx_status(struct
ctucan_hw_priv + *priv, u8 buf)

...

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 621

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+	default:
+		status = ~0;
+	}
+	return (enum ctu_can_fd_tx_status_tx1s)status;
+}

Is ~0 in the enum?

This can happen only when there is fundamental internal error in the code logic, but good catch, I add something to enum.

Quoted 3 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 658

Quoted 1 line
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +1 -0
+	// TODO: use named constants for the command

TODO...

It is intenal mechanism between ctu_can_fd_hw.c and ctu_can_fd_hw.h with fully documented external API in ctu_can_fd_hw.h . So it is questionable if to polute user visible header there by another definitions. May it be we should switch to type ctu_can_fd_tx_command for command or do other optimization which I can imagine.

This TODO is Ondrej Ille and Marin Jerabek leftover, so they should provide their suggestion and intention there as well as consequences of change for other projects which are not mine busyness.

Quoted 2 lines
Quoted 1 line

+// TODO: AL_CAPTURE and ERROR_CAPTURE

Again colleagues remark for future work. For me, it is important basic function under GNU/Linux.

Quoted 6 lines
Quoted 5 lines
(quoted diff) +2 -0
+#if defined(__LITTLE_ENDIAN_BITFIELD) == defined(__BIG_ENDIAN_BITFIELD)
+# error __BIG_ENDIAN_BITFIELD or __LITTLE_ENDIAN_BITFIELD must be

defined. +#endif

:-).

To catch problems in another more undermined environments which I am happy not to take care at all.

Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.h line 63

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +5 -0
+// True if Core is transceiver of current frame
+#define CTU_CAN_FD_IS_TRANSMITTER(stat) (!!(stat).ts)
+
+// True if Core is receiver of current frame
+#define CTU_CAN_FD_IS_RECEIVER(stat) (!!(stat).s.rxs)

Why not, documentation is nice. But it is in big contrast to other parts of code where there's no docs at all.

This is to document things outside of ctu_can_fd_hw.c. On the other hand actual HW is documented in referenced generated PDF file so there is not so big need to documents each bit of ctu_can_fd_hw.c . There is even internal HW docuemntation

http://canbus.pages.fel.cvut.cz/ctucanfd_ip_core/ctu_can_fd_architecture.pdf

so in the fact these parts are documented for those who poke with them quite well and for regular driver developer the functions of ctu_can_fd_hw.h should provide all what is needed. And yes you can use referenced documentation and go deeper

https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core/-/blob/master/src/memory_registers/memory_registers.vhd

so basically ctu_can_fd_hw.c is interface between those who wants to go deeper, try to modify HW, do verification etc. and these who do not care about these HW specific bits and ctu_can_fd_hw.h should be sufficient for driver developers.

All this division to abstraction layers is result of more iterations thoughts and experiments. There are not many open-source/open-hardware projects of this scale where to learn from and we are really limited team. Chips Alliance aims this direction now
but CTU CAN FD project predates its founding by many years.

Quoted 4 lines
Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +4 -0
+struct ctucan_hw_priv;
+#ifndef ctucan_hw_priv
+struct ctucan_hw_priv {
+	void __iomem *mem_base;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.h line 134

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +6 -0
+	u32 (*read_reg)(struct ctucan_hw_priv *priv,
+			enum ctu_can_fd_can_registers reg);
+	void (*write_reg)(struct ctucan_hw_priv *priv,
+			  enum ctu_can_fd_can_registers reg, u32 val);
+};
+#endif

Should not be needed in kernel.

I am really not sure if this is required for some userpace tests or other CTU CAN FD based projects. It is to colleagues participating in other projects to defend this ifndef. I think that it is remnant of hacks before I have separated ctucan_priv and ctucan_hw_priv structures for proper layering.

Quoted 8 lines
Quoted 6 lines

+/**
+ * ctucan_hw_read_rx_word - Reads one word of CAN Frame from RX FIFO Buffer. + *
+ * @priv: Private info
+ *
+ * Return: One wword of received frame

Typo 'word'.

Thanks.

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 3

Quoted 5 lines

+++ b/drivers/net/can/ctucanfd/ctu_can_fd_regs.h

drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +3 -0
@@ -0,0 +1,971 @@
+
+/* This file is autogenerated, DO NOT EDIT! */
+

Yay. How is that supposed to work after merge?

I think that it is really better to not edit this file directly. It has to match exactly hardware. So we provide compatible license which allows you edit, but you have been warned to not shoot into your own leg.

And for sure you can clone CTU CAN FD repo and experiment and generate your own core derivative. You can even include tools into Linux kernel tree or reference them

https://github.com/Blebowski/Reg_Map_Gen
https://github.com/Blebowski/ipyxact

same as use complete Kactus2 IP cores editor to manage specification file.

But if somebody wants to do such massive changes without coordination with us it would be polite to copy driver do different directory under another name and change "ctu,ctucanfd" in device tree to something different.

Again thanks for review, I try to follow most of your suggestions for some I would be really happy if you and other reviewers
try to look at the project as the whole. Linux driver is really small (but very important) part and some relatively small
and I think not so important changes can result in significant problems in another parts of the quite large project
and its automatic testing and inject errors without our notice. Actual setup allows us to run full synthetic and real hardware tests for each changed line in driver or HDL sources. This is simple test and each night complex test including simulated jitter on CAN lines etc. is run. In sum, it takes servers about three hours to do all testing on multiple projects to provide next day results for the previous day development step.

Best wishes,

Pavel

A message that is not in the archive (sent off-list or not yet received): CAA7Zjpam0uFCXwXS4_X5Sq3wJcNUSxOxPiTm860OXDNs-xHgyg@mail.gmail.com

author maintainer
#8 lore raw

Re: [PATCH v6 3/6] can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.

Hello Ondrej and others,

Quoted 10 lines · On Monday 26 of October 2020 14:38:59 Ondrej Ille wrote:

Hello Pavel and Pavel,

first of all, Pavel (Machek) thank you for review, we appreciate it. We will try to fix as much mistakes as possible. Please, see my comments below.

With Regards
Ondrej

On Thu, Oct 22, 2020 at 10:22 PM Pavel Pisa <[email protected]> wrote:

...

Quoted 41 lines
Quoted 18 lines
Quoted 6 lines
Quoted 6 lines

+/**
+ * ctucan_start_xmit - Starts the transmission
+ * @skb: sk_buff pointer that contains data to be Txed
+ * @ndev: Pointer to net_device structure
+ *
+ * This function is invoked from upper layers to initiate

transmission.

Quoted 1 line
Quoted 1 line

This + * function uses the next available free txbuf and populates

their

Quoted 5 lines
Quoted 4 lines

fields to + * start the transmission.
+ *
+ * Return: %NETDEV_TX_OK on success and failure value on error
+ */

Quoted 4 lines
Quoted 2 lines

Based on other documentation, I'd expect this to return -ESOMETHING on error, but it returns NETDEV_TX_BUSY.

I add information about explicit error/need for postpone type.

Changing description, OK. Pavel Pisa, but why did you change handling of insertion
failure to TXT Buffer to return NETDEV_TX_BUSY and increment tx_dropped? Is there some preference on what should the driver return in case of HW error?
Also, couldnt we afford not to check return value of ctucan_hw_insert_frame ? Is purpose of
driver to be fail-safe against HW bug which says "There is TX buffer free in Status register", but in reality,
no TXT Buffer is free?

If we look at when ctu_can_hw_insert_frame returns false, it is when:
1. We attempt to insert to non-existent TXT buffer -> Under drivers
control to do rotation correctly.
2. If cfg->len > CAN_FD_MAX_LEN. Couldnt this check be removed?
CAN_FD_MAX_LEN is
defined for Linux, so it is not OS agnostic... Also, is it possible
that driver will call insert with

Quoted 5 lines
      cf->len > CAN_FD_MAX_LEN?

3. When there is HW bug (as mentioned earlier). There are assertions in
RTL checking this situation
will not happend!
So maybe we dont even need to check return value of this function at all?

I try to follow other drivers.
So if everything is OK then return NETDEV_TX_OK.

If there is no Tx buffer available then return NETDEV_TX_BUSY. Some retransmit or drop should be handled by NET core in such case. This situation should not appear in reality, because Tx queue should be stopped if there is no free Tx buffer and should not be reenable earlien than at least one is available. So this situation is bug in driver logic or NET core.

If the check for CAN FD frame format fails then it is right to drop SKB and it is handled with NETDEV_TX_OK return in other drivers as well. Only statistic counter increments. If the Tx buffer selected by driver s in incorrect state then it is even more serious bug so alternative is to stop whole driver and report fatal error.

Quoted 11 lines
Quoted 10 lines
Quoted 5 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 508

Quoted 3 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +3 -0
+   /* Check for Bus Error interrupt */
+   if (isr.s.bei) {
+           netdev_info(ndev, "  bus error");

Missing "if (dologerr)" here?

Intention was to left this one to appear without rate limit, it is really indication of bigger problem. But on the other hand without dologerr would be quite short/unclear, but does not overflow the log buffers... We would discuss what to do with my colleagues, suggestions welcomed.

Quoted 6 lines

I agree with adding "dologerror" check here. It is true that arbitration lost is not really an
error, and Bus error (error frame), therefore Bus error has higher "severity". Could we
maybe do it that both have "dologerr" condition, but arbitration lost uses "netdev_dbg"?

Arbitration lost should not be reported nor generate interrupt for usual can application setup.

Quoted 13 lines
Quoted 13 lines
Quoted 12 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 544

Quoted 10 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +10 -0
+static int ctucan_rx_poll(struct napi_struct *napi, int quota)
+{
+   struct net_device *ndev = napi->dev;
+   struct ctucan_priv *priv = netdev_priv(ndev);
+   int work_done = 0;
+   union ctu_can_fd_status status;
+   u32 framecnt;
+
+   framecnt = ctucan_hw_get_rx_frame_count(&priv->p);
+   netdev_dbg(ndev, "rx_poll: %d frames in RX FIFO", framecnt);

This will be rather noisy, right?

Quoted 4 lines
Quoted 2 lines

It has use to debug during development but may be it should be removed or controlled by other option.

Maybe again suppress by "net_ratelimit" ?

I have removed this one and report only errors.

...

Quoted 7 lines
Quoted 6 lines

https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core/-/blob/master/spec/CTU
/ip/CAN_FD_IP_Core/2.1/CAN_FD_IP_Core.2.1.xml

Which I consider as good option which should be preserved. I prefer to have only singe source of infomation which is kept with rest in automatic sync.

Quoted 16 lines

We are really trying only to use bitfields generated in ctu_can_fd_regs. Whether it is bitfield or
mask, is up to debate, but we always use generated values. Linux driver is only one part of it
all. The golden source (IP-XACT) is propagated to RTL, 2 different TB packages, constant definitions,
generated documentation. This is the only way how to keep register map consistent with limited
developer resources we have. If we corrupt this rule, we end up with 4 different representations
of register maps:
1. What Testebench thinks
2. What is in RTL
3. What is in documentation
4. What driver sees.
and then we will never put it back together again...

I think that it is even important example for others. And there is not listed use of the generated header files for functional emulation in QEMU. I have even plan to use generator to prepare RO/RW mask for QEMU and IP block emulation skeleton for QEMU automatically. This part has not been implemented during last bachelor thesis. That part was written manually but it is in QEMU mainline now.

If there is strong preferences for macros than bitfields we add macros generation alternative.

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +7 -0
+   {
+           union ctu_can_fd_int_stat imask;
+
+           imask.u32 = 0xffffffff;
+           ctucan_hw_int_ena_clr(&priv->p, imask);
+           ctucan_hw_int_mask_set(&priv->p, imask);
+   }
Quoted 7 lines
Quoted 5 lines
Quoted 1 line

More like this. Plus avoid block here...?

Blocks is to document that imask is really local for these two lines, no need to look for it elsewhere in the function. But I can move declaration to start of the function.

I would also remove blocks here.

Flattened

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 6 lines

+/**
+ * ctucan_close - Driver close routine
+ * @ndev: Pointer to net_device structure
+ *
+ * Return: 0 always
+ */

You see, this is better. No need to say "Driver close routine" twice. Now, make the rest consistent :-).

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 984

Quoted 2 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +2 -0
+EXPORT_SYMBOL(ctucan_suspend);
+EXPORT_SYMBOL(ctucan_resume);

_GPL?

Should we be so strict??? Ondrej Ille can provide his opinion there.

Is it really necessary? If yes, then we can change it.

I see no reason that it is necessary. Without GPL some vendor can come with CTU CAN FD integration on such platform, where integration code stays unavailable to users. But common driver part has to be made available. We can prevent such use of the driver code, but I see no big wind there or financial income instrument.

...

Quoted 9 lines
Quoted 8 lines

Hmmm, we can add special rules to tools to skip some special cases but actual files exactly math what is in documentation and VHDL sources and registers implementation. See page 61 / PDF 67 of

http://canbus.pages.fel.cvut.cz/ctucanfd_ip_core/Progdokum.pdf

Yes there is still space for improvements but we need to have acceptable base for already running applications.

Quoted 9 lines

Point taken. These are indeed ridiculous. I was thinking about adding some skip rule
to the register map generator, but I am out of IP-XACT fields to represent this thing.
Maybe I can use vendor extensions do to hide it? Or custom switch? Anyway, the
same thing needs to be resolved if HW design has dedicated test registers which
are for debug. I will think about some solution.

I personally prefer rules without exception. Defined 32-bit fields over whole register are harmless and if narrowed or reorganized later then in can help.

....

Quoted 6 lines
Quoted 4 lines

OK, I have invested lot of time after Marin Jerabek's submission of diploma theses to make code really documented etc.. I add there something even that it is really simple use of can_len2dlc. May it be, we can use that directly. It is Linux specific, but clean.

Using can_len2dlc seems as right option for me...

Done

Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line

+// TODO: AL_CAPTURE and ERROR_CAPTURE

Again colleagues remark for future work. For me, it is important basic function under GNU/Linux.

Again, CAN be removed and moved to Issue tracker on Gitlab.

Please add issue, I have removed this one already.

Quoted 5 lines

It is basically the same topic as above. We need to generate everything from single
source, otherwise we are not able to keep all the targets (RTL, TB, driver, docs)
consistent.

Best wishes,

Pavel

author maintainer
#9 lore raw

Re: [PATCH v6 3/6] can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.

In reply to Pavel Machek

Hello Pavel and others,

thanks for review and suggestions. I have spent weekend to attempt to resolve the most of the suggestions.

The result is merge request to our projects

https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core/-/merge_requests/372

I am running test with two CTU CAN FD cores and two SJA1000 FD tollereant against two CTU CAN FD cores on PCIe board on my home machine from the morning. Zynq XCANs are not put into the mix because they are not FD tolerant.

Actual statistics from Zynq system

can2: flags=193<UP,RUNNING,NOARP> mtu 16 Open Cores SJA1000 FD tollerant
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC) RX packets 2431626 bytes 14089057 (13.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 329075 bytes 2383757 (2.2 MiB)
TX errors 65043 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 49

can3: flags=193<UP,RUNNING,NOARP> mtu 16 Open Cores SJA1000 FD tollerant
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC) RX packets 2695281 bytes 15459822 (14.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 50

can4: flags=193<UP,RUNNING,NOARP> mtu 72 CTU CAN FD on Zynq
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC) RX packets 84791228 bytes 1307744193 (1.2 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1189540 bytes 17447286 (16.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 47

can5: flags=193<UP,RUNNING,NOARP> mtu 72 CTU CAN FD on Zynq
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC) RX packets 81264790 bytes 1273404732 (1.1 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4715979 bytes 51786821 (49.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 48

Statistic from my the Intel Core 2 based system, only CTU CAN FD, EMS PCI board not used, it is not FD tollereant.

can2: flags=193<UP,RUNNING,NOARP> mtu 72 CTU CAN FD on DB4CGX15
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC) RX packets 77731204 bytes 1222332122 (1.1 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 847131 bytes 13328222 (12.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 33

can3: flags=193<UP,RUNNING,NOARP> mtu 72 CTU CAN FD on DB4CGX15
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC) RX packets 1830253 bytes 28749064 (27.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 76340684 bytes 1200464054 (1.1 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 33

There is no indication of errors in the logs. On the other hand, massive renames and even some code functional changes to allow rewrite some parts to be better readable could introduce some errors.

Automatic systemic tests and builds do passed in the final version

https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core/-/pipelines/25070

Same as automatic test at computes at the university

https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top/-/pipelines/25071

So hopefully nothing is broken but testing for all corner cases after this update can take weeks.

The response to review notes follows. I will wait for remarks form the community or at least check for typos from colleagues and then I send v7 series.

Best wishes,

Pavel

Quoted 13 lines · On Thursday 22 of October 2020 13:02:13 Pavel Machek wrote:

Hi!

Quoted 10 lines

From: Martin Jerabek <[email protected]>

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 FGA based PCI Express board is available from project (https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd).

Quoted 1 line

Is "FGA" a typo? Yes, it is.

Fixed

Quoted 5 lines

Anyway, following link tells me:

Project 'canbus/pcie-ctu_can_fd' was moved to 'canbus/pcie-ctucanfd'. Please update any links and bookmarks that may still have the old path. Fixing it in Kconfig is more important.

Unification of ctu_can_fd -> ctucanfd done for file names, driver paths, device tree and documentation. Not enough resources to unify HDL sources, generated files etc. It would break history (blames etc.), testing etc., there are more than 4k occurrences.

Quoted 8 lines

drivers/net/can/ctucanfd/Kconfig line 15

Quoted 6 lines

+++ b/drivers/net/can/ctucanfd/Kconfig

drivers/net/can/ctucanfd/Kconfig new file +3 -0
@@ -0,0 +1,15 @@
 
+if CAN_CTUCANFD
+
+endif

Empty -> drop?

TODO

Quoted 9 lines

Review line 1

Quoted 7 lines

+++ b/drivers/net/can/ctucanfd/Makefile

(quoted diff) +3 -0
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
 
+++ b/drivers/net/can/ctucanfd/ctu_can_fd.c
@@ -0,0 +1,1105 @@
+// SPDX-License-Identifier: GPL-2.0-or-later

Having Makefile and sources with different licenses is rather unusual.

UNified

Quoted 10 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 56

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+static const char * const ctucan_state_strings[] = {
+	"CAN_STATE_ERROR_ACTIVE",
+	"CAN_STATE_ERROR_WARNING",
+	"CAN_STATE_ERROR_PASSIVE",
+	"CAN_STATE_BUS_OFF",
+	"CAN_STATE_STOPPED",
+	"CAN_STATE_SLEEPING"
+};

Put this near function that uses this?

ctucan_state_to_str() moved after array, array defined with strict correspondence of index to text.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +7 -0
+/**
+ * ctucan_set_bittiming - CAN set bit timing routine
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the driver set bittiming routine.
+ * Return: 0 on success and failure value on error
+ */
Quoted 11 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 191

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+/**
+ * ctucan_chip_start - This routine starts the driver
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the drivers start routine.
+ *
+ * Return: 0 on success and failure value on error
+ */

Good documentation is nice, but repeating "This routine starts the driver" in "This is the drivers start routine." is not too helpful.

Included relevant text as well as I have decided to move call to ctucan_reset() out of ctucan_chip_start() and slightly reorder/clarify some part of initialization and error handling.

Quoted 12 lines
Quoted 11 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+/**
+ * ctucan_start_xmit - Starts the transmission
+ * @skb:	sk_buff pointer that contains data to be Txed
+ * @ndev:	Pointer to net_device structure
+ *
+ * This function is invoked from upper layers to initiate transmission.

This + * function uses the next available free txbuf and populates their fields to + * start the transmission.
+ *
+ * Return: %NETDEV_TX_OK on success and failure value on error
+ */

Quoted 2 lines

Based on other documentation, I'd expect this to return -ESOMETHING on error, but it returns NETDEV_TX_BUSY.

Clarified NETDEV_TX_BUSY case and decided to drop frame if there is problem with format, length or other parameters during attempt to move frame into hardware.

Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 320

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+	/* Check if the TX buffer is full */
+	if (unlikely(!CTU_CAN_FD_TXTNF(ctu_can_get_status(&priv->p)))) {
+		netif_stop_queue(ndev);
+		netdev_err(ndev, "BUG!, no TXB free when queue awake!\n");
+		return NETDEV_TX_BUSY;
+	}

You call stop_queue() without spinlock...

I hope that netif_stop_queue can be called from ctucan_start_xmit without locking and that during ctucan_start_xmit() call, would networking core postpone finish of netif_wake_queue(ndev) invoked from other CPU core or kernel thread. I have send longer request for clarification in previous reply and I would be happy, if somebody can check that my findings are right. If all that locking in network core work as I understand it then I would move the second call out of spinlock. But if there are differences how locking in networking core works between kernel versions (I have noticed some indication in the past) then I think that actual solution is correct and more robust. Even other drivers calls netif_stop_queue from irq lock protected regions...

Quoted 5 lines
Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +5 -0
+	spin_lock_irqsave(&priv->tx_lock, flags);
+
+	ctucan_hw_txt_set_rdy(&priv->p, txb_id);
+
+	priv->txb_head++;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 347

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+
+	/* Check if all TX buffers are full */
+	if (!CTU_CAN_FD_TXTNF(ctu_can_get_status(&priv->p)))
+		netif_stop_queue(ndev);
+
+	spin_unlock_irqrestore(&priv->tx_lock, flags);

...and then with spinlock held. One of them is buggy.

See above.

Quoted 11 lines
Quoted 10 lines

+/**
+ * xcan_rx - Is called from CAN isr to complete the received
+ * frame processing
+ * @ndev: Pointer to net_device structure
+ *
+ * This function is invoked from the CAN isr(poll) to process the Rx frames. It + * does minimal processing and invokes "netif_receive_skb" to complete further + * processing.
+ * Return: 1 on success and 0 on failure.
+ */

Quoted 1 line

Adapt to usual 0 / -EFOO?

I have clarified that 1 is used to inform that frame has been fully received and sent to the network layer. 0 inform that there is frame first word read but SKB cannot be (hopefully temporarily) allocated. -EAGAIN indicate unlikelly condition that function is called when there is no frame in Rx FIFO, this indicates HW bug because this cannot happen when Rx FIFO frame count is not zero.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+	/* Check for Arbitration Lost interrupt */
+	if (isr.s.ali) {
+		if (dologerr)
+			netdev_info(ndev, "  arbitration lost");
+		priv->can.can_stats.arbitration_lost++;
+		if (skb) {
+			cf->can_id |= CAN_ERR_LOSTARB;
+			cf->data[0] = CAN_ERR_LOSTARB_UNSPEC;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 508

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+		}
+	}
+
+	/* Check for Bus Error interrupt */
+	if (isr.s.bei) {
+		netdev_info(ndev, "  bus error");

Missing "if (dologerr)" here?

Bus error is result of series of troubles and should be logged. Bus restart after bus error is rate limited by driver nad hardware, so the missing dologerr is intentional there. I have added \n to all messages and left them to be considered independent.

Quoted 4 lines
Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +4 -0
+static int ctucan_rx_poll(struct napi_struct *napi, int quota)
+{
+	struct net_device *ndev = napi->dev;
+	struct ctucan_priv *priv = netdev_priv(ndev);
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 544

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +6 -0
+	int work_done = 0;
+	union ctu_can_fd_status status;
+	u32 framecnt;
+
+	framecnt = ctucan_hw_get_rx_frame_count(&priv->p);
+	netdev_dbg(ndev, "rx_poll: %d frames in RX FIFO", framecnt);

This will be rather noisy, right?

OK, usesfull during development and only on debug level but removed now.

Quoted 10 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 558

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +8 -0
+	/* Check for RX FIFO Overflow */
+	status = ctu_can_get_status(&priv->p);
+	if (status.s.dor) {
+		struct net_device_stats *stats = &ndev->stats;
+		struct can_frame *cf;
+		struct sk_buff *skb;
+
+		netdev_info(ndev, "  rx fifo overflow");

And this goes at different loglevel, which will be confusing?

Levels try to be reciprocal to severity and proportional to occurrence frequency. Can be tuned for sure. Some most flooding are ratelimited.

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 610

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +5 -0
+/**
+ * xcan_tx_interrupt - Tx Done Isr
+ * @ndev:	net_device pointer
+ */
+static void ctucan_tx_interrupt(struct net_device *ndev)

Mismatch between code and docs.

Corrected.

Quoted 4 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 619

Quoted 1 line
drivers/net/can/ctucanfd/ctu_can_fd.c new file +1 -0
+	netdev_dbg(ndev, "%s", __func__);

This is inconsistent with other debugging.... and perhaps it is time to remove this kind of debugging for merge.

I have removed some and will consider others.
We are far from being production silicon version, so some debugging helps even "hardware"/HDL development.

It seems that checkpatch pushes me in use of __func__.

WARNING: Prefer using '"%s...", __func__' to using 'ctucan_set_bittiming', this function's name, in a string #127: FILE: /home/pi/fpga/can-fd/ctu-can-fd/CAN_FD_IP_Core/driver/linux/ctucanfd_base.c:127:
+ netdev_dbg(ndev, "ctucan_set_bittiming\n");

Generally, I am not sure if it is problem to have there many debugs at NET debug level. Today, when it is possible to control debug levels on per file basis it should not be so big problem and it can help to debug code and hardware interaction. It can be removed any time later.

Quoted 6 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 729

Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +4 -0
+/**
+ * xcan_interrupt - CAN Isr
+ */
+static irqreturn_t ctucan_interrupt(int irq, void *dev_id)

Inconsistent.

Corrected.

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 770

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +5 -0
+		/* Error interrupts */
+		if (isr.s.ewli || isr.s.fcsi || isr.s.ali) {
+			union ctu_can_fd_int_stat ierrmask = { .s = {
+				  .ewli = 1, .fcsi = 1, .ali = 1, .bei = 1 } };
+			icr.u32 = isr.u32 & ierrmask.u32;

We normally do bit arithmetics instead of this.

As described, my intention is to use only fields and bits mapping which is directly generated from IPXACT specification
and team decision was to to use structs for bitfields.
So I do not want to add manually introduced defines.
Even that core interface is stabilized at least for version 2.x now, I want all code to directly reflect HW design changes.

Quoted 9 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 802

Quoted 7 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +7 -0
+	{
+		union ctu_can_fd_int_stat imask;
+
+		imask.u32 = 0xffffffff;
+		ctucan_hw_int_ena_clr(&priv->p, imask);
+		ctucan_hw_int_mask_set(&priv->p, imask);
+	}

More like this. Plus avoid block here...?

Block is to inform, that imask is really local and you do not need to look for it elsewhere in the function.
But you prefer flat so I move define to start and remove block. In this case all F are OK, we know that there is nothing else than interrupts enable, mask bits, and if all should be stopped in response to error, then there cannot be problem even after some move of bitfileds in the register.

Quoted 7 lines
Quoted 6 lines

+/**
+ * ctucan_close - Driver close routine
+ * @ndev: Pointer to net_device structure
+ *
+ * Return: 0 always
+ */

Quoted 7 lines

You see, this is better. No need to say "Driver close routine" twice. Now, make the rest consistent :-).

drivers/net/can/ctucanfd/ctu_can_fd.c line 984

Quoted 2 lines
drivers/net/can/ctucanfd/ctu_can_fd.c new file +2 -0
+EXPORT_SYMBOL(ctucan_suspend);
+EXPORT_SYMBOL(ctucan_resume);

_GPL?

Not critical for me, may be Ondrej Ille has some opinion there.

Quoted 2 lines

And what kind of multi-module stuff are you doing that you need symbols exported?

Seems to be understood from followup patches.

Quoted 6 lines

drivers/net/can/ctucanfd/ctu_can_fd.c line 989

Quoted 4 lines

+int ctucan_probe_common(struct device *dev, void __iomem *addr, int irq,
unsigned int ntxbufs, + unsigned long can_clk_rate, int pm_enable_call,

drivers/net/can/ctucanfd/ctu_can_fd.c new file +2 -0
+			void (*set_drvdata_fnc)(struct device *dev, struct net_device *ndev))
+{

Splitting/simplifying this somehow would be good.

If you confirm my offer to move to structure with options then I look at it. On the other hand when functions prototype changes it enforces all users to get update which can bee better to catch problems than sillent structure fields addition. If zeroed the first then probably manageable too.

Quoted 5 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 49

Quoted 3 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +3 -0
+/* Register descriptions: */
+union ctu_can_fd_frame_form_w {
+	uint32_t u32;

u32, as you write elsewhere.

As I already described these generated files should be used one to one in QEMU and other tools. There seems to be acceptable to use uint32_t in the kernel for these cases. Definition of u32 type in all other cases would lead often to unwanted pollute of namespace.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +8 -0
+	struct ctu_can_fd_frame_form_w_s {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+  /* FRAME_FORM_W */
+		uint32_t dlc                     : 4;
+		uint32_t reserved_4              : 1;
+		uint32_t rtr                     : 1;
+		uint32_t ide                     : 1;
+		uint32_t fdf                     : 1;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 63

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +6 -0
+		uint32_t reserved_8              : 1;
+		uint32_t brs                     : 1;
+		uint32_t esi_rsv                 : 1;
+		uint32_t rwcnt                   : 5;
+		uint32_t reserved_31_16         : 16;
+#else

I believe you should simply avoid using bitfields.

I have already described that my personal tendency
is similar but in this case big and little part
is kept consistent by generation and it was preferred solution by colleagues. There are more places where this style is used in the kernel and we do not use overlay structures for hardware directly. Value is read by iored/iowrite in all cases and union/struct works only for local variables to parse bitfields. It is correct from IO synchronization
and single access rules and it optimizes to same code as use of defines on local variables.

Quoted 9 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 125

Quoted 7 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +7 -0
+union ctu_can_fd_timestamp_l_w {
+	uint32_t u32;
+	struct ctu_can_fd_timestamp_l_w_s {
+  /* TIMESTAMP_L_W */
+		uint32_t time_stamp_31_0        : 32;
+	} s;
+};

This is crazy.

Yes, but generated from spec so it is kept consistent. Adding exception for case that size of field is 32-bits is possible but when field size changes it would cause incorrect access.

Quoted 11 lines
Quoted 11 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +11 -0
+union ctu_can_fd_data_5_8_w {
+	uint32_t u32;
+	struct ctu_can_fd_data_5_8_w_s {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+  /* DATA_5_8_W */
+		uint32_t data_5                  : 8;
+		uint32_t data_6                  : 8;
+		uint32_t data_7                  : 8;
+		uint32_t data_8                  : 8;
+#else
+		uint32_t data_8                  : 8;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 169

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +6 -0
+		uint32_t data_7                  : 8;
+		uint32_t data_6                  : 8;
+		uint32_t data_5                  : 8;
+#endif
+	} s;
+};

even more crazy.

This is mainly for documentation where it has place and reason. It is used only in sense of data area start in the driver.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +8 -0
+#ifdef __KERNEL__
+# include <linux/can/dev.h>
+#else
+/* The hardware registers mapping and low level layer should build
+ * in userspace to allow development and verification of CTU CAN IP
+ * core VHDL design when loaded into hardware. Debugging hardware
+ * from kernel driver is really difficult, leads to system stucks
+ * by error reporting etc. Testing of exactly the same code
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 44

Quoted 6 lines

+ * in userspace together with headers generated automatically
+ * generated from from IP-XACT/cactus helps to driver to hardware
+ * and QEMU emulation model consistency keeping.
+ */

drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +2 -0
+# include "ctu_can_fd_linux_defs.h"
+#endif

Please remove non-kernel code for merge.

As I tried to describe these mechanism allows to ensure that there is match between HW access generated registers description and manual algorithmic part of HW interface and actual implementation of registers file by different test from userpace run during each driver or HDL update. I am convinced personally that it worth to be run and tested. Alternative to #ifdef is file patching during userspace build, but we use same files with symliks only during GitLab runner execution. It would complicate things on our side and can lead to not catching problem which would cost really much more than four additional lines. I have added description for others to understand value of this solution.
If really requested to be removed, then I would follow requirement but with bad taste what more worthless problems I have to spent my time.

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 53

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+void ctucan_hw_write32(struct ctucan_hw_priv *priv,
+		       enum ctu_can_fd_can_registers reg, u32 val)
+{
+	iowrite32(val, priv->mem_base + reg);
+}

And get rid of this kind of abstraction layer.

We need to support big endian and little endian mapping in same driver. I.e. bigendian MIPS with little endian PCI mapping (that is standard) and big endian for SoC integration. I really think that linux/regmap.h is to big monster for this simple purpose. See my previous analysis and reference to similar conclusions of M_CAN authors.

Quoted 3 lines
Quoted 1 line

+// TODO: rename or do not depend on previous value of id

TODO: grep for TODO and C++ comments before attempting merge.

There should not be any C++ comment except SPDX, which seems to be preffered even in other kernel C files and TODOs. They go after my colleagues providing basic HW abstraction. I have replaced C++ comments in ctucanfd_hw.h.

Code restructured to resolve this TODO.

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 118

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+static bool ctucan_hw_len_to_dlc(u8 len, u8 *dlc)
+{
+	*dlc = can_len2dlc(len);
+	return true;
+}

Compared to how well other code is documented... This one is voodoo.

Wrapper removed, can_len2dlc used directly.

Generally ctucanfd_hw.h/ctucanfd_hw.c provides documented API to the driver. Who wants to poke with ctucanfd_hw.h/ctucanfd_hw.c should read HW, registers docs, to which code directly corresponds.

http://canbus.pages.fel.cvut.cz/ctucanfd_ip_core/Progdokum.pdf
http://canbus.pages.fel.cvut.cz/ctucanfd_ip_core/ctu_can_fd_architecture.pdf

Quoted 7 lines
Quoted 7 lines

+bool ctucan_hw_set_ret_limit(struct ctucan_hw_priv *priv, bool enable, u8 limit) +{

drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+	union ctu_can_fd_mode_settings reg;
+
+	if (limit > CTU_CAN_FD_RETR_MAX)
+		return false;
+
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 173

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +6 -0
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_MODE);
+	reg.s.rtrle = enable ? RTRLE_ENABLED : RTRLE_DISABLED;
+	reg.s.rtrth = limit & 0xF;
+	priv->write_reg(priv, CTU_CAN_FD_MODE, reg.u32);
+	return true;
+}

As elsewhere, I'd suggest 0/-ERRNO.

I would prefer this HW documenting layer without dependency of concrete systems status reporting mechanisms. EXXX rule can be followed but at cost of testing, other systems integration etc.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +7 -0
+void ctucan_hw_set_mode_reg(struct ctucan_hw_priv *priv,
+			    const struct can_ctrlmode *mode)
+{
+	u32 flags = mode->flags;
+	union ctu_can_fd_mode_settings reg;
+
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_MODE);
Quoted 6 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 185

Quoted 3 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +3 -0
+	if (mode->mask & CAN_CTRLMODE_LOOPBACK)
+		reg.s.ilbp = flags & CAN_CTRLMODE_LOOPBACK ?
+					INT_LOOP_ENABLED : INT_LOOP_DISABLED;

Not sure what is going on here, but having mode->flags in same format as hardware register would help...?

Converts SocketCAN defined code to actual encoding in the HDL

https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/can/netlink.h#L95

So this is to have external API of HW access functions as close to SocketCAN as possible.

Quoted 8 lines
Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +8 -0
+	switch (fnum) {
+	case CTU_CAN_FD_FILTER_A:
+		if (reg.s.sfa)
+			return true;
+	break;
+	case CTU_CAN_FD_FILTER_B:
+		if (reg.s.sfb)
+			return true;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 438

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +6 -0
+	break;
+	case CTU_CAN_FD_FILTER_C:
+		if (reg.s.sfc)
+			return true;
+	break;
+	}

Check indentation of break statemnts, also elsewhere in this file

Strange that checkpatch accepts this, but changing.

Quoted 10 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 450

Quoted 8 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +8 -0
+bool ctucan_hw_get_range_filter_support(struct ctucan_hw_priv *priv)
+{
+	union ctu_can_fd_filter_control_filter_status reg;
+
+	reg.u32 = priv->read_reg(priv, CTU_CAN_FD_FILTER_CONTROL);
+
+	if (reg.s.sfr)
+		return true;

return !!reg.s.sfr; ?

Replaced

Quoted 5 lines
Quoted 2 lines

+enum ctu_can_fd_tx_status_tx1s ctucan_hw_get_tx_status(struct
ctucan_hw_priv + *priv, u8 buf)

...

Quoted 7 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 621

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +5 -0
+	default:
+		status = ~0;
+	}
+	return (enum ctu_can_fd_tx_status_tx1s)status;
+}

Is ~0 in the enum?

Hmm enum ctu_can_fd_tx_status_tx1s is generated from IPXACT CTU CAN FD specification. The ~0 is there to catch fatal problems, to put something, which does not match any enum value. Changing enum is problematic, it would require to change generator or specification... It is to catch real problem in the code implementation. So I am not sure what else I can do there.

Quoted 5 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.c line 658

Quoted 1 line
drivers/net/can/ctucanfd/ctu_can_fd_hw.c new file +1 -0
+	// TODO: use named constants for the command

TODO...

Quoted 1 line

+// TODO: AL_CAPTURE and ERROR_CAPTURE

Removed, I am not sure what was on the mind of colleagues who has placed this TODO there.

Quoted 6 lines
Quoted 4 lines
(quoted diff) +2 -0
+#if defined(__LITTLE_ENDIAN_BITFIELD) == defined(__BIG_ENDIAN_BITFIELD)
+# error __BIG_ENDIAN_BITFIELD or __LITTLE_ENDIAN_BITFIELD must be

defined. +#endif

:-).
:

Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.h line 63

Quoted 5 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +5 -0
+// True if Core is transceiver of current frame
+#define CTU_CAN_FD_IS_TRANSMITTER(stat) (!!(stat).ts)
+
+// True if Core is receiver of current frame
+#define CTU_CAN_FD_IS_RECEIVER(stat) (!!(stat).s.rxs)

Why not, documentation is nice. But it is in big contrast to other parts of code where there's no docs at all.

The ctucanfd_hw.h API should be documented for driver implementers. ctucanfd_hw.c require to read real HW docs.

Quoted 4 lines
Quoted 4 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +4 -0
+struct ctucan_hw_priv;
+#ifndef ctucan_hw_priv
+struct ctucan_hw_priv {
+	void __iomem *mem_base;
Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_hw.h line 134

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_hw.h new file +6 -0
+	u32 (*read_reg)(struct ctucan_hw_priv *priv,
+			enum ctu_can_fd_can_registers reg);
+	void (*write_reg)(struct ctucan_hw_priv *priv,
+			  enum ctu_can_fd_can_registers reg, u32 val);
+};
+#endif

Should not be needed in kernel.

Old mechanism, actual user space tests can live without it.

Quoted 19 lines
Quoted 6 lines

+/**
+ * ctucan_hw_read_rx_word - Reads one word of CAN Frame from RX FIFO Buffer. + *
+ * @priv: Private info
+ *
+ * Return: One wword of received frame

Typo 'word'.

drivers/net/can/ctucanfd/ctu_can_fd_frame.h line 3

Quoted 5 lines

+++ b/drivers/net/can/ctucanfd/ctu_can_fd_regs.h

drivers/net/can/ctucanfd/ctu_can_fd_frame.h new file +3 -0
@@ -0,0 +1,971 @@
+
+/* This file is autogenerated, DO NOT EDIT! */
+

Yay. How is that supposed to work after merge?

Best regards,
Pavel

Quoted 17 lines · On Thursday 22 of October 2020 13:39:52 Pavel Machek wrote:
Quoted 11 lines
(quoted diff) +7 -0
@@ -12,4 +12,13 @@ config CAN_CTUCANFD
 
 if CAN_CTUCANFD
 
+config CAN_CTUCANFD_PCI
+	tristate "CTU CAN-FD IP core PCI/PCIe driver"
+	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
Quoted 3 lines

available + at https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd .
+
endif

Ok, now the if in the first patch makes sense. It can stay.

Quoted 1 line

And it is separate module, so EXPORT_SYMBOLs make sense. Ok.

I have changed dependency to not use if but
depends on CAN_CTUCANFD

Quoted 7 lines

Review

Quoted 5 lines
(quoted diff) +4 -0
+#ifndef PCI_VENDOR_ID_TEDIA
+#define PCI_VENDOR_ID_TEDIA 0x1760
+#endif
 
+#define PCI_DEVICE_ID_TEDIA_CTUCAN_VER21 0xff00

These should go elsewhere.

Kept for now, I will adapt to suggestions but I would prefer to put it independent to allow easy backports for meanwhile.

Quoted 1 line
Quoted 1 line

+#define PCI_DEVICE_ID_ALTERA_CTUCAN_TEST 0xCAFD

Test integration not in use removed.

Quoted 5 lines

Review

Quoted 3 lines
(quoted diff) +2 -0
+static bool use_msi = 1;
+static bool pci_use_second = 1;

true?

Changed to true.

Quoted 7 lines · On Thursday 22 of October 2020 13:43:06 Pavel Machek wrote:

Hi!

Quoted 5 lines

+++ b/drivers/net/can/ctucanfd/Kconfig

(quoted diff) +0 -0
@@ -21,4 +21,15 @@ config CAN_CTUCANFD_PCI
 	  PCIe board with PiKRON.com designed transceiver riser shield is

available at https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd .

Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+config CAN_CTUCANFD_PLATFORM
+	tristate "CTU CAN-FD IP core platform (FPGA, SoC) driver"
+	depends on OF || COMPILE_TEST
+	help

This is likely wrong, as it can enable config of CAN_CTUCANFD=M, CAN_CTUCANFD_PLATFORM=y, right?

Chanegd to depends on

Quoted 9 lines

Review ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o · line 13

Quoted 7 lines
(quoted diff) +3 -0
@@ -8,3 +8,6 @@ ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o
 
 obj-$(CONFIG_CAN_CTUCANFD_PCI) += ctucanfd_pci.o
 ctucanfd_pci-y := ctu_can_fd_pci.o
+
+obj-$(CONFIG_CAN_CTUCANFD_PLATFORM) += ctucanfd_platform.o
+ctucanfd_platform-y += ctu_can_fd_platform.o

Can you simply add right object files directly?

I have done rename in many places to fullfill this single line. Full rename in HDL would require to analyze 4k+ occurrences.

Quoted 11 lines · On Thursday 22 of October 2020 13:25:40 Pavel Machek wrote:
Quoted 7 lines · Pavel Pisa

CTU CAN FD IP core documentation based on Martin Jeřábek's diploma theses Open-source and Open-hardware CAN FD Protocol Support
https://dspace.cvut.cz/handle/10467/80366
.

---
 .../ctu/FSM_TXT_Buffer_user.png               | Bin 0 -> 174807 bytes

Maybe picture should stay on website, somewhere. It is rather big for kernel sources.

I have invested time to redraw image in Inscape and do more optimization to reduce 172K to 16K SVG.

Quoted 5 lines
Quoted 5 lines
(quoted diff) +5 -0
+About SocketCAN
+---------------
+
+SocketCAN is a standard common interface for CAN devices in the Linux
+kernel. As the name suggests, the bus is accessed via sockets, similarly
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +2 -0
+to common network devices. The reasoning behind this is in depth
+described in `Linux SocketCAN

<https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Doc
umentation/networking/can.rst>`_. +In short, it offers a

(quoted diff) +2 -0
+natural way to implement and work with higher layer protocols over CAN,
+in the same way as, e.g., UDP/IP over Ethernet.

Drop? Or at least link directly to the file in kernel tree?

What is the best way to cross-reference RST documentation in Linux kernel sources??

Quoted 2 lines
Quoted 2 lines

+Device probe
+~~~~~~~~~~~~

...

Quoted 3 lines

Dunno. Is it suitable? This is supposed to be ctu-can documentation, not "how hardware works" docs.

I would be happy if it stays in our standalone build. If it is problem for mainline I try to reduce text. Help, suggestions etc. much appreciated.
Mr. Ille, Mr. Jerabek and others, please help there. Same with checking for errors.

Thanks for your time (when you reached the end of the discussion),

Pavel

author maintainer
#10 lore raw

PATCH v6 4/6 can: ctucanfd: CTU CAN FD open-source IP core - PCI bus support.

In reply to Pavel Pisa

PCI bus adaptation for CTU CAN FD open-source 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-ctu_can_fd .

---
 drivers/net/can/ctucanfd/Kconfig          |   9 +
 drivers/net/can/ctucanfd/Makefile         |   3 +
 drivers/net/can/ctucanfd/ctu_can_fd_pci.c | 314 ++++++++++++++++++++++
 3 files changed, 326 insertions(+)
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_pci.c
drivers/net/can/ctucanfd/Kconfig +9 -0
index b6d47bba7150..fb4d3cda6885 100644
@@ -12,4 +12,13 @@ config CAN_CTUCANFD
 
 if CAN_CTUCANFD
 
+config CAN_CTUCANFD_PCI
+	tristate "CTU CAN-FD IP core PCI/PCIe driver"
+	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-ctu_can_fd .
+
 endif
drivers/net/can/ctucanfd/Makefile +3 -0
index 8d47008d0076..eb945260952d 100644
@@ -5,3 +5,6 @@
 
 obj-$(CONFIG_CAN_CTUCANFD) := ctucanfd.o
 ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o
+
+obj-$(CONFIG_CAN_CTUCANFD_PCI) += ctucanfd_pci.o
+ctucanfd_pci-y := ctu_can_fd_pci.o
drivers/net/can/ctucanfd/ctu_can_fd_pci.c new file +314 -0

314 lines not on this page · raw message

Signature · 1 line
2.20.1
#11 lore raw

Re: [PATCH v6 4/6] can: ctucanfd: CTU CAN FD open-source IP core - PCI bus support.

Hi!

Quoted 4 lines
drivers/net/can/ctucanfd/Kconfig +0 -0
@@ -12,4 +12,13 @@ config CAN_CTUCANFD
 
 if CAN_CTUCANFD
 

drivers/net/can/ctucanfd/Kconfig config CAN_CTUCANFD · line 24

Quoted 10 lines
drivers/net/can/ctucanfd/Kconfig +9 -0
+config CAN_CTUCANFD_PCI
+	tristate "CTU CAN-FD IP core PCI/PCIe driver"
+	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-ctu_can_fd .
+
 endif

Ok, now the if in the first patch makes sense. It can stay.

And it is separate module, so EXPORT_SYMBOLs make sense. Ok.

drivers/net/can/ctucanfd/ctu_can_fd_pci.c line 49

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_pci.c new file +5 -0
+#ifndef PCI_VENDOR_ID_TEDIA
+#define PCI_VENDOR_ID_TEDIA 0x1760
+#endif
 
+#define PCI_DEVICE_ID_ALTERA_CTUCAN_TEST  0xCAFD
+#define PCI_DEVICE_ID_TEDIA_CTUCAN_VER21 0xff00

These should go elsewhere.

drivers/net/can/ctucanfd/ctu_can_fd_pci.c line 62

Quoted 2 lines
drivers/net/can/ctucanfd/ctu_can_fd_pci.c new file +2 -0
+static bool use_msi = 1;
+static bool pci_use_second = 1;

true?

Best regards,
Pavel

Signature · 1 line
http://www.livejournal.com/~pavelmachek
author maintainer
#12 lore raw

Re: [PATCH v6 4/6] can: ctucanfd: CTU CAN FD open-source IP core - PCI bus support.

Hello Pavel,

thanks for review.

Quoted 19 lines · On Thursday 22 of October 2020 13:39:52 Pavel Machek wrote:

Hi!

Quoted 11 lines
drivers/net/can/ctucanfd/Kconfig +7 -0
@@ -12,4 +12,13 @@ config CAN_CTUCANFD
 
 if CAN_CTUCANFD
 
+config CAN_CTUCANFD_PCI
+	tristate "CTU CAN-FD IP core PCI/PCIe driver"
+	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
Quoted 3 lines

available + at https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd .
+
endif

Ok, now the if in the first patch makes sense. It can stay.

Quoted 1 line

And it is separate module, so EXPORT_SYMBOLs make sense. Ok.

Great.

Quoted 8 lines

drivers/net/can/ctucanfd/ctu_can_fd_pci.c line 49

Quoted 6 lines
drivers/net/can/ctucanfd/ctu_can_fd_pci.c new file +5 -0
+#ifndef PCI_VENDOR_ID_TEDIA
+#define PCI_VENDOR_ID_TEDIA 0x1760
+#endif
 
+#define PCI_DEVICE_ID_ALTERA_CTUCAN_TEST  0xCAFD
+#define PCI_DEVICE_ID_TEDIA_CTUCAN_VER21 0xff00

These should go elsewhere.

They should propagate somehow from

https://pci-ids.ucw.cz/read/PC/1760/ff00

We have registered them long time ago.
I am not sure what is right mechanism.

Quoted 3 lines

drivers/net/can/ctucanfd/ctu_can_fd_pci.c line 46

Quoted 3 lines
drivers/net/can/ctucanfd/ctu_can_fd_pci.c new file +3 -0
+#ifndef PCI_VENDOR_ID_TEDIA
+#define PCI_VENDOR_ID_TEDIA 0x1760
+#endif

So this one should be known to kernel globally, but I would be happy if driver build even if global process to introduce define did not proceed end even backports would be required for long time until kernel including CTU CAN FD propagates into distributions, and industrial systems distributions lag often a lot

Quoted 1 line
Quoted 1 line

+#define PCI_DEVICE_ID_ALTERA_CTUCAN_TEST 0xCAFD

We drop this, I hope we have no system running old test version of the core integration before Tedia offered us to reserve some IDs (promissed that they would never use them in future) for us.

Quoted 1 line
Quoted 1 line

+#define PCI_DEVICE_ID_TEDIA_CTUCAN_VER21 0xff00

This should propagate into kernel from registry or at least match registry.

Quoted 4 lines

drivers/net/can/ctucanfd/ctu_can_fd_pci.c line 62

Quoted 2 lines
drivers/net/can/ctucanfd/ctu_can_fd_pci.c new file +2 -0
+static bool use_msi = 1;
+static bool pci_use_second = 1;

true?

Done

Best wishes,

Pavel

author maintainer
#13 lore raw

PATCH v6 5/6 can: ctucanfd: CTU CAN FD open-source IP core - platform/SoC support.

In reply to Pavel Pisa

Platform bus adaptation for CTU CAN FD open-source IP core.

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 .

Kit carrier board and mechanics design source files

https://gitlab.com/pikron/projects/mz_apo/microzed_apo

The work is documented in Martin Jeřábek's diploma theses Open-source and Open-hardware CAN FD Protocol Support

https://dspace.cvut.cz/handle/10467/80366
.

---
 drivers/net/can/ctucanfd/Kconfig              |  11 ++
 drivers/net/can/ctucanfd/Makefile             |   3 +
 .../net/can/ctucanfd/ctu_can_fd_platform.c    | 142 ++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 drivers/net/can/ctucanfd/ctu_can_fd_platform.c
drivers/net/can/ctucanfd/Kconfig +11 -0
index fb4d3cda6885..01fcfe5873cc 100644
@@ -21,4 +21,15 @@ config CAN_CTUCANFD_PCI
 	  PCIe board with PiKRON.com designed transceiver riser shield is available
 	  at https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd .
 
+config CAN_CTUCANFD_PLATFORM
+	tristate "CTU CAN-FD IP core platform (FPGA, SoC) driver"
+	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/b182/courses/b35apo/documentation/mz_apo/start .
+
 endif
drivers/net/can/ctucanfd/Makefile +3 -0
index eb945260952d..a77ca72d534e 100644
@@ -8,3 +8,6 @@ ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o
 
 obj-$(CONFIG_CAN_CTUCANFD_PCI) += ctucanfd_pci.o
 ctucanfd_pci-y := ctu_can_fd_pci.o
+
+obj-$(CONFIG_CAN_CTUCANFD_PLATFORM) += ctucanfd_platform.o
+ctucanfd_platform-y += ctu_can_fd_platform.o
drivers/net/can/ctucanfd/ctu_can_fd_platform.c new file +142 -0

142 lines not on this page · raw message

Signature · 1 line
2.20.1
#14 lore raw

Re: [PATCH v6 5/6] can: ctucanfd: CTU CAN FD open-source IP core - platform/SoC support.

Hi!

drivers/net/can/ctucanfd/Kconfig config CAN_CTUCANFD_PCI · line 27

Quoted 9 lines

+++ b/drivers/net/can/ctucanfd/Kconfig

drivers/net/can/ctucanfd/Kconfig +4 -0
@@ -21,4 +21,15 @@ config CAN_CTUCANFD_PCI
 	  PCIe board with PiKRON.com designed transceiver riser shield is available
 	  at https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd .
 
+config CAN_CTUCANFD_PLATFORM
+	tristate "CTU CAN-FD IP core platform (FPGA, SoC) driver"
+	depends on OF || COMPILE_TEST
+	help

This is likely wrong, as it can enable config of CAN_CTUCANFD=M, CAN_CTUCANFD_PLATFORM=y, right?

drivers/net/can/ctucanfd/Makefile ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o · line 13

Quoted 7 lines
drivers/net/can/ctucanfd/Makefile +3 -0
@@ -8,3 +8,6 @@ ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o
 
 obj-$(CONFIG_CAN_CTUCANFD_PCI) += ctucanfd_pci.o
 ctucanfd_pci-y := ctu_can_fd_pci.o
+
+obj-$(CONFIG_CAN_CTUCANFD_PLATFORM) += ctucanfd_platform.o
+ctucanfd_platform-y += ctu_can_fd_platform.o

Can you simply add right object files directly?

Best regards,
Pavel

Signature · 1 line
http://www.livejournal.com/~pavelmachek
author maintainer
#15 lore raw

Re: [PATCH v6 5/6] can: ctucanfd: CTU CAN FD open-source IP core - platform/SoC support.

Hello Pavel,

thanks for review.

Quoted 7 lines · On Thursday 22 of October 2020 13:43:06 Pavel Machek wrote:

Hi!

Quoted 5 lines

+++ b/drivers/net/can/ctucanfd/Kconfig

(quoted diff) +0 -0
@@ -21,4 +21,15 @@ config CAN_CTUCANFD_PCI
 	  PCIe board with PiKRON.com designed transceiver riser shield is

available at https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd .

Quoted 7 lines

drivers/net/can/ctucanfd/Kconfig config CAN_CTUCANFD_PCI · line 27

Quoted 4 lines
drivers/net/can/ctucanfd/Kconfig +4 -0
+config CAN_CTUCANFD_PLATFORM
+	tristate "CTU CAN-FD IP core platform (FPGA, SoC) driver"
+	depends on OF || COMPILE_TEST
+	help

This is likely wrong, as it can enable config of CAN_CTUCANFD=M, CAN_CTUCANFD_PLATFORM=y, right?

My original code has not || COMPILE_TEST alternative.

But I have been asked to add it

Quoted 3 lines · On Sunday 16 of August 2020 01:28:13 Randy Dunlap wrote:

Can this be

        depends on OF || COMPILE_TEST

?

I have send discussion later that I am not sure if it is right but followed suggestion. If there is no other reply now,
I would drop || COMPILE_TEST. I believe that then it is correct for regular use. I ma not sure about all consequences of COMPILE_TEST missing.

Quoted 9 lines

drivers/net/can/ctucanfd/Makefile ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o · line 13

Quoted 7 lines
drivers/net/can/ctucanfd/Makefile +3 -0
@@ -8,3 +8,6 @@ ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o
 
 obj-$(CONFIG_CAN_CTUCANFD_PCI) += ctucanfd_pci.o
 ctucanfd_pci-y := ctu_can_fd_pci.o
+
+obj-$(CONFIG_CAN_CTUCANFD_PLATFORM) += ctucanfd_platform.o
+ctucanfd_platform-y += ctu_can_fd_platform.o

Can you simply add right object files directly?

This is more tough question. We have kept sources
as ctu_can_fd.c, ctu_can_fd_hw.c etc. to produce final ctucanfd.ko which matches device tree entry etc. after name simplification now...
So we move from underscores to ctucanfd on more places. So yes, we can rename ctu_can_fd.c to ctucanfd_drv.c + others keep final ctucanfd.ko and change to single file based objects ctucanfd_platform.c and ctucanfd_pci.c

If you think that it worth to be redone, I would do that. It would disrupt sources history, may it be blames, merging etc... but I would invest effort into it if asked for.

Best wishes,

Pavel

#16 lore raw

Re: [PATCH v6 5/6] can: ctucanfd: CTU CAN FD open-source IP core - platform/SoC support.

Hi!

Quoted 22 lines
Quoted 5 lines
Quoted 5 lines

+++ b/drivers/net/can/ctucanfd/Kconfig

(quoted diff) +0 -0
@@ -21,4 +21,15 @@ config CAN_CTUCANFD_PCI
 	  PCIe board with PiKRON.com designed transceiver riser shield is

available at https://gitlab.fel.cvut.cz/canbus/pcie-ctu_can_fd .

Quoted 7 lines

drivers/net/can/ctucanfd/Kconfig config CAN_CTUCANFD_PCI · line 27

Quoted 4 lines
drivers/net/can/ctucanfd/Kconfig +4 -0
+config CAN_CTUCANFD_PLATFORM
+	tristate "CTU CAN-FD IP core platform (FPGA, SoC) driver"
+	depends on OF || COMPILE_TEST
+	help

This is likely wrong, as it can enable config of CAN_CTUCANFD=M, CAN_CTUCANFD_PLATFORM=y, right?

My original code has not || COMPILE_TEST alternative.

But I have been asked to add it

Quoted 3 lines · On Sunday 16 of August 2020 01:28:13 Randy Dunlap wrote:

Can this be

        depends on OF || COMPILE_TEST

?

Quoted 5 lines

I have send discussion later that I am not sure if it is right but followed suggestion. If there is no other reply now,
I would drop || COMPILE_TEST. I believe that then it is correct for regular use. I ma not sure about all consequences of COMPILE_TEST missing.

COMPILE_TEST is not a problem. But you need to make this depend on main CONFIG_ option to disallow CAN_CTUCANFD=M, CAN_CTUCANFD_PLATFORM=y combination.

Quoted 19 lines
Quoted 9 lines

drivers/net/can/ctucanfd/Makefile ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o · line 13

Quoted 7 lines
drivers/net/can/ctucanfd/Makefile +3 -0
@@ -8,3 +8,6 @@ ctucanfd-y := ctu_can_fd.o ctu_can_fd_hw.o
 
 obj-$(CONFIG_CAN_CTUCANFD_PCI) += ctucanfd_pci.o
 ctucanfd_pci-y := ctu_can_fd_pci.o
+
+obj-$(CONFIG_CAN_CTUCANFD_PLATFORM) += ctucanfd_platform.o
+ctucanfd_platform-y += ctu_can_fd_platform.o

Can you simply add right object files directly?

This is more tough question. We have kept sources
as ctu_can_fd.c, ctu_can_fd_hw.c etc. to produce final ctucanfd.ko which matches device tree entry etc. after name simplification now...
So we move from underscores to ctucanfd on more places. So yes, we can rename ctu_can_fd.c to ctucanfd_drv.c + others keep final ctucanfd.ko and change to single file based objects ctucanfd_platform.c and ctucanfd_pci.c

Quoted 3 lines

If you think that it worth to be redone, I would do that. It would disrupt sources history, may it be blames, merging etc... but I would invest effort into it if asked for.

git can handle renames. Or you can use the new names for module names...?

Best regards,
Pavel

Signature · 1 line
http://www.livejournal.com/~pavelmachek
author maintainer
#17 lore raw

PATCH v6 6/6 docs: ctucanfd: CTU CAN FD open-source IP core documentation.

In reply to Pavel Pisa

CTU CAN FD IP core documentation based on Martin Jeřábek's diploma theses Open-source and Open-hardware CAN FD Protocol Support
https://dspace.cvut.cz/handle/10467/80366
.

---
 .../ctu/FSM_TXT_Buffer_user.png               | Bin 0 -> 174807 bytes
 .../device_drivers/ctu/ctucanfd-driver.rst    | 638 ++++++++++++++++++
 2 files changed, 638 insertions(+)
 create mode 100644 Documentation/networking/device_drivers/ctu/FSM_TXT_Buffer_user.png
 create mode 100644 Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst
Documentation/networking/device_drivers/ctu/FSM_TXT_Buffer_user.png new file binary +0 -0
new file mode 100644
index 0000000000000000000000000000000000000000..5dceb594fca1f668fbc2eb7c1fb5706e99137d28
GIT binary patch
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +638 -0

638 lines not on this page · raw message

Signature · 1 line
2.20.1
#18 lore raw

Re: [PATCH v6 6/6] docs: ctucanfd: CTU CAN FD open-source IP core documentation.

Quoted 7 lines · Pavel Pisa

CTU CAN FD IP core documentation based on Martin Jeřábek's diploma theses Open-source and Open-hardware CAN FD Protocol Support
https://dspace.cvut.cz/handle/10467/80366
.

---
 .../ctu/FSM_TXT_Buffer_user.png               | Bin 0 -> 174807 bytes

Maybe picture should stay on website, somewhere. It is rather big for kernel sources.

Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst line 46

Quoted 10 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +10 -0
+About SocketCAN
+---------------
+
+SocketCAN is a standard common interface for CAN devices in the Linux
+kernel. As the name suggests, the bus is accessed via sockets, similarly
+to common network devices. The reasoning behind this is in depth
+described in `Linux SocketCAN <https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/can.rst>`_.
+In short, it offers a
+natural way to implement and work with higher layer protocols over CAN,
+in the same way as, e.g., UDP/IP over Ethernet.

Drop? Or at least link directly to the file in kernel tree?

Quoted 8 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +8 -0
+Device probe
+~~~~~~~~~~~~
+
+Before going into detail about the structure of a CAN bus device driver,
+let's reiterate how the kernel gets to know about the device at all.
+Some buses, like PCI or PCIe, support device enumeration. That is, when
+the system boots, it discovers all the devices on the bus and reads
+their configuration. The kernel identifies the device via its vendor ID

Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst line 65

Quoted 10 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +10 -0
+and device ID, and if there is a driver registered for this identifier
+combination, its probe method is invoked to populate the driver's
+instance for the given hardware. A similar situation goes with USB, only
+it allows for device hot-plug.
+
+The situation is different for peripherals which are directly embedded
+in the SoC and connected to an internal system bus (AXI, APB, Avalon,
+and others). These buses do not support enumeration, and thus the kernel
+has to learn about the devices from elsewhere. This is exactly what the
+Device Tree was made for.

Dunno. Is it suitable? This is supposed to be ctu-can documentation, not "how hardware works" docs.

Quoted 22 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +22 -0
+Platform device driver
+^^^^^^^^^^^^^^^^^^^^^^
+
+In the case of Zynq, the core is connected via the AXI system bus, which
+does not have enumeration support, and the device must be specified in
+Device Tree. This kind of devices is called *platform device* in the
+kernel and is handled by a *platform device driver*\  [1]_.
+
+A platform device driver provides the following things:
+
+-  A *probe* function
+
+-  A *remove* function
+
+-  A table of *compatible* devices that the driver can handle
+
+The *probe* function is called exactly once when the device appears (or
+the driver is loaded, whichever happens later). If there are more
+devices handled by the same driver, the *probe* function is called for
+each one of them. Its role is to allocate and initialize resources
+required for handling the device, as well as set up low-level functions
+for the platform-independent layer, e.g., *read_reg* and *write_reg*.

Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst line 137

Quoted 10 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +10 -0
+After that, the driver registers the device to a higher layer, in our
+case as a *network device*.
+
+The *remove* function is called when the device disappears, or the
+driver is about to be unloaded. It serves to free the resources
+allocated in *probe* and to unregister the device from higher layers.
+
+Finally, the table of *compatible* devices states which devices the
+driver can handle. The Device Tree entry ``compatible`` is matched
+against the tables of all *platform drivers*.

And this is "how to write a kernel driver" documentation. Like, why not, but maybe it does not need to be in kernel tree, and certainly should be separate from real "what is ctucan and how to use it" docs.

Best regards,
Pavel

Signature · 1 line
http://www.livejournal.com/~pavelmachek
author maintainer
#19 lore raw

Re: [PATCH v6 6/6] docs: ctucanfd: CTU CAN FD open-source IP core documentation.

Hello Pavel,

thanks for review.

As for the documentation, my current intention is to keep/maintain the common driver documentation for CTU CAN FD site
and kernel source. The standalone driver documentation

http://canbus.pages.fel.cvut.cz/ctucanfd_ip_core/driver_doc/ctucanfd-driver.html

when the driver documentation moves to

https://www.kernel.org/doc/html/latest/

we may consider to drop standalone. But resource are limited and keeping and maintaining sync between slightly different files is error prone. I run manual kdiff3 updates
of both RST files because references to sources are different.

Quoted 11 lines · On Thursday 22 of October 2020 13:25:40 Pavel Machek wrote:
Quoted 7 lines · Pavel Pisa

CTU CAN FD IP core documentation based on Martin Jeřábek's diploma theses Open-source and Open-hardware CAN FD Protocol Support
https://dspace.cvut.cz/handle/10467/80366
.

---
 .../ctu/FSM_TXT_Buffer_user.png               | Bin 0 -> 174807 bytes

Maybe picture should stay on website, somewhere. It is rather big for kernel sources.

My sense is that it is proffered that documentation is self-contained without embedded references to "untrusted" third party sites. But we try to do something with it. I try reduce size or switch to SVG, our actual source is PDF prepared by Ondrej Ille as part of CTU CAN FD IP core architecture. I probably redraw image in inscape with little worse graphics style, fonts, smoothness etc. but in smaller and simpler SVG file size format. I expect that use of original PDF in vector form would not help much.

Quoted 5 lines
Quoted 5 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +5 -0
+About SocketCAN
+---------------
+
+SocketCAN is a standard common interface for CAN devices in the Linux
+kernel. As the name suggests, the bus is accessed via sockets, similarly
Quoted 8 lines

Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst line 46

Quoted 6 lines
(quoted diff) +2 -0
+to common network devices. The reasoning behind this is in depth
+described in `Linux SocketCAN

<https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Doc
umentation/networking/can.rst>`_. +In short, it offers a

Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +2 -0
+natural way to implement and work with higher layer protocols over CAN,
+in the same way as, e.g., UDP/IP over Ethernet.

Drop? Or at least link directly to the file in kernel tree?

Yes, this is another place where we need other diversion between standalone and kernel. I try to learn what is the right way to cross-reference Linux kernel manuals writtent n RST? If you can speedup it by hint/right done example I would be happy.

Quoted 13 lines
Quoted 13 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +13 -0
+Device probe
+~~~~~~~~~~~~
+
+Before going into detail about the structure of a CAN bus device driver,
+let's reiterate how the kernel gets to know about the device at all.
+Some buses, like PCI or PCIe, support device enumeration. That is, when
+the system boots, it discovers all the devices on the bus and reads
+their configuration. The kernel identifies the device via its vendor ID
+and device ID, and if there is a driver registered for this identifier
+combination, its probe method is invoked to populate the driver's
+instance for the given hardware. A similar situation goes with USB, only
+it allows for device hot-plug.
+
Quoted 8 lines

Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst line 65

Quoted 5 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +5 -0
+The situation is different for peripherals which are directly embedded
+in the SoC and connected to an internal system bus (AXI, APB, Avalon,
+and others). These buses do not support enumeration, and thus the kernel
+has to learn about the devices from elsewhere. This is exactly what the
+Device Tree was made for.

Dunno. Is it suitable? This is supposed to be ctu-can documentation, not "how hardware works" docs.

I think that this text is fully valid for standalone driver documentation, I understand that in the kernel tree this can be replaced by references to right places if we locate them.

Quoted 28 lines
Quoted 28 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +28 -0
+Platform device driver
+^^^^^^^^^^^^^^^^^^^^^^
+
+In the case of Zynq, the core is connected via the AXI system bus, which
+does not have enumeration support, and the device must be specified in
+Device Tree. This kind of devices is called *platform device* in the
+kernel and is handled by a *platform device driver*\  [1]_.
+
+A platform device driver provides the following things:
+
+-  A *probe* function
+
+-  A *remove* function
+
+-  A table of *compatible* devices that the driver can handle
+
+The *probe* function is called exactly once when the device appears (or
+the driver is loaded, whichever happens later). If there are more
+devices handled by the same driver, the *probe* function is called for
+each one of them. Its role is to allocate and initialize resources
+required for handling the device, as well as set up low-level functions
+for the platform-independent layer, e.g., *read_reg* and *write_reg*.
+After that, the driver registers the device to a higher layer, in our
+case as a *network device*.
+
+The *remove* function is called when the device disappears, or the
+driver is about to be unloaded. It serves to free the resources
+allocated in *probe* and to unregister the device from higher layers.
Quoted 8 lines

Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst line 137

Quoted 4 lines
Documentation/networking/device_drivers/ctu/ctucanfd-driver.rst new file +4 -0
+
+Finally, the table of *compatible* devices states which devices the
+driver can handle. The Device Tree entry ``compatible`` is matched
+against the tables of all *platform drivers*.

And this is "how to write a kernel driver" documentation. Like, why not, but maybe it does not need to be in kernel tree, and certainly should be separate from real "what is ctucan and how to use it" docs.

I agree, we try to find way how to separate the things and reference pieces already found in the kernel. But it probably means massive diversion of documentation sources which is yet another additional load during preparation for mainlining. So I probably drop updates of standalone documentation. Which can be problem for another university group which builds applications based on the core and needs to maintain and patch kernels now.

Best wishes,

Pavel
--

                Pavel Pisa
    phone:      +420 603531357
    e-mail:     [email protected]
    Department of Control Engineering FEE CVUT
    Karlovo namesti 13, 121 35, Prague 2
    university: http://dce.fel.cvut.cz/
    personal:   http://cmp.felk.cvut.cz/~pisa
    projects:   https://www.openhub.net/accounts/ppisa
    CAN related:http://canbus.pages.fel.cvut.cz/