linux-can-next-for-6.11-20240621

-----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEEUEC6huC2BN0pvD5fKDiiPnotvG8FAmZ1MB4THG1rbEBwZW5n
 dXRyb25peC5kZQAKCRAoOKI+ei28b+QQB/9wDkLdjgRsvI3c32IXxTrOmuX97Pm2
 jYaHXmH1QkOKK0CXkPLEGjzpxSVXO6/d+ooeINkKmeF9VrtxxYWuE9pEsulyPz4y
 dbeK5oAZdhtS6CEnArzbNHR6mdP1IcmJ3uKojsV71t+4GTdZw4WHe6LNgC4ua7n8
 oYOpgbEV/YP/AyP8vO1L65M+tI69/0jeDpidtDQkNgWepE/Kh0W0ASfqjYrBgvZq
 eycUmLTCigKNhG8fNJVHejyrnLynY2QBqwM7M5yYw1q8lX4W8Yf1y55VCqzPz63D
 RiYVdVdG720jk9Ux9ZqxAKBPyzACnV6CG/MnzIgIdpV3O1aEf1WDkU2Y
 =rRB9
 -----END PGP SIGNATURE-----

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

Marc Kleine-Budde says:

====================
pull-request: can-next 2024-06-21

The first 2 patches are by Andy Shevchenko, one cleans up the includes
in the mcp251x driver, the other one updates the sja100 plx_pci driver
to make use of predefines PCI subvendor ID.

Mans Rullgard's patch cleans up the Kconfig help text of for the slcan
driver.

Oliver Hartkopp provides a patch to update the documentation, which
removes the ISO 15675-2 specification version where possible.

The next 2 patches are by Harini T and update the documentation of the
xilinx_can driver.

Francesco Valla provides documentation for the ISO 15765-2 protocol.

A patch by Dr. David Alan Gilbert removes an unused struct from the
mscan driver.

12 patches are by Martin Jocic. The first three add support for 3 new
devices to the kvaser_usb driver. The remaining 9 first clean up the
kvaser_pciefd driver, and then add support for MSI.

Krzysztof Kozlowski contributes 3 patches simplifies the CAN SPI
drivers by making use of spi_get_device_match_data().

The last patch is by Martin Hundebøll, which reworks the m_can driver
to not enable the CAN transceiver during probe.

* tag 'linux-can-next-for-6.11-20240621' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next: (24 commits)
  can: m_can: don't enable transceiver when probing
  can: mcp251xfd: simplify with spi_get_device_match_data()
  can: mcp251x: simplify with spi_get_device_match_data()
  can: hi311x: simplify with spi_get_device_match_data()
  can: kvaser_pciefd: Add MSI interrupts
  can: kvaser_pciefd: Move reset of DMA RX buffers to the end of the ISR
  can: kvaser_pciefd: Change name of return code variable
  can: kvaser_pciefd: Rename board_irq to pci_irq
  can: kvaser_pciefd: Add unlikely
  can: kvaser_pciefd: Add inline
  can: kvaser_pciefd: Remove unnecessary comment
  can: kvaser_pciefd: Skip redundant NULL pointer check in ISR
  can: kvaser_pciefd: Group #defines together
  can: kvaser_usb: Add support for Kvaser Mini PCIe 1xCAN
  can: kvaser_usb: Add support for Kvaser USBcan Pro 5xCAN
  can: kvaser_usb: Add support for Vining 800
  can: mscan: remove unused struct 'mscan_state'
  Documentation: networking: document ISO 15765-2
  can: xilinx_can: Document driver description to list all supported IPs
  can: isotp: remove ISO 15675-2 specification version where possible
  ...
====================

Link: https://patch.msgid.link/20240621080201.305471-1-mkl@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2024-06-21 18:06:40 -07:00
commit e9212f9dd1
19 changed files with 612 additions and 172 deletions

View File

@ -5,7 +5,7 @@ $id: http://devicetree.org/schemas/net/can/xilinx,can.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title:
Xilinx Axi CAN/Zynq CANPS controller
Xilinx CAN and CANFD controller
maintainers:
- Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>

View File

@ -19,6 +19,7 @@ Contents:
caif/index
ethtool-netlink
ieee802154
iso15765-2
j1939
kapi
msg_zerocopy

View File

@ -0,0 +1,386 @@
.. SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
====================
ISO 15765-2 (ISO-TP)
====================
Overview
========
ISO 15765-2, also known as ISO-TP, is a transport protocol specifically defined
for diagnostic communication on CAN. It is widely used in the automotive
industry, for example as the transport protocol for UDSonCAN (ISO 14229-3) or
emission-related diagnostic services (ISO 15031-5).
ISO-TP can be used both on CAN CC (aka Classical CAN) and CAN FD (CAN with
Flexible Datarate) based networks. It is also designed to be compatible with a
CAN network using SAE J1939 as data link layer (however, this is not a
requirement).
Specifications used
-------------------
* ISO 15765-2:2024 : Road vehicles - Diagnostic communication over Controller
Area Network (DoCAN). Part 2: Transport protocol and network layer services.
Addressing
----------
In its simplest form, ISO-TP is based on two kinds of addressing modes for the
nodes connected to the same network:
* physical addressing is implemented by two node-specific addresses and is used
in 1-to-1 communication.
* functional addressing is implemented by one node-specific address and is used
in 1-to-N communication.
Three different addressing formats can be employed:
* "normal" : each address is represented simply by a CAN ID.
* "extended": each address is represented by a CAN ID plus the first byte of
the CAN payload; both the CAN ID and the byte inside the payload shall be
different between two addresses.
* "mixed": each address is represented by a CAN ID plus the first byte of
the CAN payload; the CAN ID is different between two addresses, but the
additional byte is the same.
Transport protocol and associated frame types
---------------------------------------------
When transmitting data using the ISO-TP protocol, the payload can either fit
inside one single CAN message or not, also considering the overhead the protocol
is generating and the optional extended addressing. In the first case, the data
is transmitted at once using a so-called Single Frame (SF). In the second case,
ISO-TP defines a multi-frame protocol, in which the sender provides (through a
First Frame - FF) the PDU length which is to be transmitted and also asks for a
Flow Control (FC) frame, which provides the maximum supported size of a macro
data block (``blocksize``) and the minimum time between the single CAN messages
composing such block (``stmin``). Once this information has been received, the
sender starts to send frames containing fragments of the data payload (called
Consecutive Frames - CF), stopping after every ``blocksize``-sized block to wait
confirmation from the receiver which should then send another Flow Control
frame to inform the sender about its availability to receive more data.
How to Use ISO-TP
=================
As with others CAN protocols, the ISO-TP stack support is built into the
Linux network subsystem for the CAN bus, aka. Linux-CAN or SocketCAN, and
thus follows the same socket API.
Creation and basic usage of an ISO-TP socket
--------------------------------------------
To use the ISO-TP stack, ``#include <linux/can/isotp.h>`` shall be used. A
socket can then be created using the ``PF_CAN`` protocol family, the
``SOCK_DGRAM`` type (as the underlying protocol is datagram-based by design)
and the ``CAN_ISOTP`` protocol:
.. code-block:: C
s = socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP);
After the socket has been successfully created, ``bind(2)`` shall be called to
bind the socket to the desired CAN interface; to do so:
* a TX CAN ID shall be specified as part of the sockaddr supplied to the call
itself.
* a RX CAN ID shall also be specified, unless broadcast flags have been set
through socket option (explained below).
Once bound to an interface, the socket can be read from and written to using
the usual ``read(2)`` and ``write(2)`` system calls, as well as ``send(2)``,
``sendmsg(2)``, ``recv(2)`` and ``recvmsg(2)``.
Unlike the CAN_RAW socket API, only the ISO-TP data field (the actual payload)
is sent and received by the userspace application using these calls. The address
information and the protocol information are automatically filled by the ISO-TP
stack using the configuration supplied during socket creation. In the same way,
the stack will use the transport mechanism when required (i.e., when the size
of the data payload exceeds the MTU of the underlying CAN bus).
The sockaddr structure used for SocketCAN has extensions for use with ISO-TP,
as specified below:
.. code-block:: C
struct sockaddr_can {
sa_family_t can_family;
int can_ifindex;
union {
struct { canid_t rx_id, tx_id; } tp;
...
} can_addr;
}
* ``can_family`` and ``can_ifindex`` serve the same purpose as for other
SocketCAN sockets.
* ``can_addr.tp.rx_id`` specifies the receive (RX) CAN ID and will be used as
a RX filter.
* ``can_addr.tp.tx_id`` specifies the transmit (TX) CAN ID
ISO-TP socket options
---------------------
When creating an ISO-TP socket, reasonable defaults are set. Some options can
be modified with ``setsockopt(2)`` and/or read back with ``getsockopt(2)``.
General options
~~~~~~~~~~~~~~~
General socket options can be passed using the ``CAN_ISOTP_OPTS`` optname:
.. code-block:: C
struct can_isotp_options opts;
ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts))
where the ``can_isotp_options`` structure has the following contents:
.. code-block:: C
struct can_isotp_options {
u32 flags;
u32 frame_txtime;
u8 ext_address;
u8 txpad_content;
u8 rxpad_content;
u8 rx_ext_address;
};
* ``flags``: modifiers to be applied to the default behaviour of the ISO-TP
stack. Following flags are available:
* ``CAN_ISOTP_LISTEN_MODE``: listen only (do not send FC frames); normally
used as a testing feature.
* ``CAN_ISOTP_EXTEND_ADDR``: use the byte specified in ``ext_address`` as an
additional address component. This enables the "mixed" addressing format if
used alone, or the "extended" addressing format if used in conjunction with
``CAN_ISOTP_RX_EXT_ADDR``.
* ``CAN_ISOTP_TX_PADDING``: enable padding for transmitted frames, using
``txpad_content`` as value for the padding bytes.
* ``CAN_ISOTP_RX_PADDING``: enable padding for the received frames, using
``rxpad_content`` as value for the padding bytes.
* ``CAN_ISOTP_CHK_PAD_LEN``: check for correct padding length on the received
frames.
* ``CAN_ISOTP_CHK_PAD_DATA``: check padding bytes on the received frames
against ``rxpad_content``; if ``CAN_ISOTP_RX_PADDING`` is not specified,
this flag is ignored.
* ``CAN_ISOTP_HALF_DUPLEX``: force ISO-TP socket in half duplex mode
(that is, transport mechanism can only be incoming or outgoing at the same
time, not both).
* ``CAN_ISOTP_FORCE_TXSTMIN``: ignore stmin from received FC; normally
used as a testing feature.
* ``CAN_ISOTP_FORCE_RXSTMIN``: ignore CFs depending on rx stmin; normally
used as a testing feature.
* ``CAN_ISOTP_RX_EXT_ADDR``: use ``rx_ext_address`` instead of ``ext_address``
as extended addressing byte on the reception path. If used in conjunction
with ``CAN_ISOTP_EXTEND_ADDR``, this flag effectively enables the "extended"
addressing format.
* ``CAN_ISOTP_WAIT_TX_DONE``: wait until the frame is sent before returning
from ``write(2)`` and ``send(2)`` calls (i.e., blocking write operations).
* ``CAN_ISOTP_SF_BROADCAST``: use 1-to-N functional addressing (cannot be
specified alongside ``CAN_ISOTP_CF_BROADCAST``).
* ``CAN_ISOTP_CF_BROADCAST``: use 1-to-N transmission without flow control
(cannot be specified alongside ``CAN_ISOTP_SF_BROADCAST``).
NOTE: this is not covered by the ISO 15765-2 standard.
* ``CAN_ISOTP_DYN_FC_PARMS``: enable dynamic update of flow control
parameters.
* ``frame_txtime``: frame transmission time (defined as N_As/N_Ar inside the
ISO standard); if ``0``, the default (or the last set value) is used.
To set the transmission time to ``0``, the ``CAN_ISOTP_FRAME_TXTIME_ZERO``
macro (equal to 0xFFFFFFFF) shall be used.
* ``ext_address``: extended addressing byte, used if the
``CAN_ISOTP_EXTEND_ADDR`` flag is specified.
* ``txpad_content``: byte used as padding value for transmitted frames.
* ``rxpad_content``: byte used as padding value for received frames.
* ``rx_ext_address``: extended addressing byte for the reception path, used if
the ``CAN_ISOTP_RX_EXT_ADDR`` flag is specified.
Flow Control options
~~~~~~~~~~~~~~~~~~~~
Flow Control (FC) options can be passed using the ``CAN_ISOTP_RECV_FC`` optname
to provide the communication parameters for receiving ISO-TP PDUs.
.. code-block:: C
struct can_isotp_fc_options fc_opts;
ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, &fc_opts, sizeof(fc_opts));
where the ``can_isotp_fc_options`` structure has the following contents:
.. code-block:: C
struct can_isotp_options {
u8 bs;
u8 stmin;
u8 wftmax;
};
* ``bs``: blocksize provided in flow control frames.
* ``stmin``: minimum separation time provided in flow control frames; can
have the following values (others are reserved):
* 0x00 - 0x7F : 0 - 127 ms
* 0xF1 - 0xF9 : 100 us - 900 us
* ``wftmax``: maximum number of wait frames provided in flow control frames.
Link Layer options
~~~~~~~~~~~~~~~~~~
Link Layer (LL) options can be passed using the ``CAN_ISOTP_LL_OPTS`` optname:
.. code-block:: C
struct can_isotp_ll_options ll_opts;
ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, &ll_opts, sizeof(ll_opts));
where the ``can_isotp_ll_options`` structure has the following contents:
.. code-block:: C
struct can_isotp_ll_options {
u8 mtu;
u8 tx_dl;
u8 tx_flags;
};
* ``mtu``: generated and accepted CAN frame type, can be equal to ``CAN_MTU``
for classical CAN frames or ``CANFD_MTU`` for CAN FD frames.
* ``tx_dl``: maximum payload length for transmitted frames, can have one value
among: 8, 12, 16, 20, 24, 32, 48, 64. Values above 8 only apply to CAN FD
traffic (i.e.: ``mtu = CANFD_MTU``).
* ``tx_flags``: flags set into ``struct canfd_frame.flags`` at frame creation.
Only applies to CAN FD traffic (i.e.: ``mtu = CANFD_MTU``).
Transmission stmin
~~~~~~~~~~~~~~~~~~
The transmission minimum separation time (stmin) can be forced using the
``CAN_ISOTP_TX_STMIN`` optname and providing an stmin value in microseconds as
a 32bit unsigned integer; this will overwrite the value sent by the receiver in
flow control frames:
.. code-block:: C
uint32_t stmin;
ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_TX_STMIN, &stmin, sizeof(stmin));
Reception stmin
~~~~~~~~~~~~~~~
The reception minimum separation time (stmin) can be forced using the
``CAN_ISOTP_RX_STMIN`` optname and providing an stmin value in microseconds as
a 32bit unsigned integer; received Consecutive Frames (CF) which timestamps
differ less than this value will be ignored:
.. code-block:: C
uint32_t stmin;
ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RX_STMIN, &stmin, sizeof(stmin));
Multi-frame transport support
-----------------------------
The ISO-TP stack contained inside the Linux kernel supports the multi-frame
transport mechanism defined by the standard, with the following constraints:
* the maximum size of a PDU is defined by a module parameter, with an hard
limit imposed at build time.
* when a transmission is in progress, subsequent calls to ``write(2)`` will
block, while calls to ``send(2)`` will either block or fail depending on the
presence of the ``MSG_DONTWAIT`` flag.
* no support is present for sending "wait frames": whether a PDU can be fully
received or not is decided when the First Frame is received.
Errors
------
Following errors are reported to userspace:
RX path errors
~~~~~~~~~~~~~~
============ ===============================================================
-ETIMEDOUT timeout of data reception
-EILSEQ sequence number mismatch during a multi-frame reception
-EBADMSG data reception with wrong padding
============ ===============================================================
TX path errors
~~~~~~~~~~~~~~
========== =================================================================
-ECOMM flow control reception timeout
-EMSGSIZE flow control reception overflow
-EBADMSG flow control reception with wrong layout/padding
========== =================================================================
Examples
========
Basic node example
------------------
Following example implements a node using "normal" physical addressing, with
RX ID equal to 0x18DAF142 and a TX ID equal to 0x18DA42F1. All options are left
to their default.
.. code-block:: C
int s;
struct sockaddr_can addr;
int ret;
s = socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP);
if (s < 0)
exit(1);
addr.can_family = AF_CAN;
addr.can_ifindex = if_nametoindex("can0");
addr.tp.tx_id = 0x18DA42F1 | CAN_EFF_FLAG;
addr.tp.rx_id = 0x18DAF142 | CAN_EFF_FLAG;
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0)
exit(1);
/* Data can now be received using read(s, ...) and sent using write(s, ...) */
Additional examples
-------------------
More complete (and complex) examples can be found inside the ``isotp*`` userland
tools, distributed as part of the ``can-utils`` utilities at:
https://github.com/linux-can/can-utils

View File

@ -4842,6 +4842,7 @@ W: https://github.com/linux-can
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git
F: Documentation/networking/can.rst
F: Documentation/networking/iso15765-2.rst
F: include/linux/can/can-ml.h
F: include/linux/can/core.h
F: include/linux/can/skb.h

View File

@ -187,9 +187,8 @@ config CAN_SLCAN
slcand) can be found in the can-utils at the linux-can project, see
https://github.com/linux-can/can-utils for details.
The slcan driver supports up to 10 CAN netdevices by default which
can be changed by the 'maxdev=xx' module option. This driver can
also be built as a module. If so, the module will be called slcan.
This driver can also be built as a module. If so, the module
will be called slcan.
config CAN_SUN4I
tristate "Allwinner A10 CAN controller"

View File

@ -29,10 +29,10 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
#define KVASER_PCIEFD_CAN_TX_MAX_COUNT 17U
#define KVASER_PCIEFD_MAX_CAN_CHANNELS 8UL
#define KVASER_PCIEFD_DMA_COUNT 2U
#define KVASER_PCIEFD_DMA_SIZE (4U * 1024U)
#define KVASER_PCIEFD_VENDOR 0x1a07
/* Altera based devices */
#define KVASER_PCIEFD_4HS_DEVICE_ID 0x000d
#define KVASER_PCIEFD_2HS_V2_DEVICE_ID 0x000e
@ -550,7 +550,7 @@ static void kvaser_pciefd_disable_err_gen(struct kvaser_pciefd_can *can)
spin_unlock_irqrestore(&can->lock, irq);
}
static void kvaser_pciefd_set_tx_irq(struct kvaser_pciefd_can *can)
static inline void kvaser_pciefd_set_tx_irq(struct kvaser_pciefd_can *can)
{
u32 msk;
@ -711,17 +711,17 @@ static void kvaser_pciefd_pwm_start(struct kvaser_pciefd_can *can)
static int kvaser_pciefd_open(struct net_device *netdev)
{
int err;
int ret;
struct kvaser_pciefd_can *can = netdev_priv(netdev);
err = open_candev(netdev);
if (err)
return err;
ret = open_candev(netdev);
if (ret)
return ret;
err = kvaser_pciefd_bus_on(can);
if (err) {
ret = kvaser_pciefd_bus_on(can);
if (ret) {
close_candev(netdev);
return err;
return ret;
}
return 0;
@ -1032,15 +1032,15 @@ static int kvaser_pciefd_reg_candev(struct kvaser_pciefd *pcie)
int i;
for (i = 0; i < pcie->nr_channels; i++) {
int err = register_candev(pcie->can[i]->can.dev);
int ret = register_candev(pcie->can[i]->can.dev);
if (err) {
if (ret) {
int j;
/* Unregister all successfully registered devices. */
for (j = 0; j < i; j++)
unregister_candev(pcie->can[j]->can.dev);
return err;
return ret;
}
}
@ -1619,7 +1619,7 @@ static int kvaser_pciefd_read_packet(struct kvaser_pciefd *pcie, int *start_pos,
/* Position does not point to the end of the package,
* corrupted packet size?
*/
if ((*start_pos + size) != pos)
if (unlikely((*start_pos + size) != pos))
return -EIO;
/* Point to the next packet header, if any */
@ -1640,31 +1640,24 @@ static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf)
return res;
}
static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
static u32 kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
{
u32 irq = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) {
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0)
kvaser_pciefd_read_buffer(pcie, 0);
/* Reset DMA buffer 0 */
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
}
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) {
if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1)
kvaser_pciefd_read_buffer(pcie, 1);
/* Reset DMA buffer 1 */
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
}
if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 ||
irq & KVASER_PCIEFD_SRB_IRQ_DOF1 ||
irq & KVASER_PCIEFD_SRB_IRQ_DUF0 ||
irq & KVASER_PCIEFD_SRB_IRQ_DUF1)
if (unlikely(irq & KVASER_PCIEFD_SRB_IRQ_DOF0 ||
irq & KVASER_PCIEFD_SRB_IRQ_DOF1 ||
irq & KVASER_PCIEFD_SRB_IRQ_DUF0 ||
irq & KVASER_PCIEFD_SRB_IRQ_DUF1))
dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq);
iowrite32(irq, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
return irq;
}
static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
@ -1691,27 +1684,33 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)
{
struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;
const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;
u32 board_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie));
u32 pci_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie));
u32 srb_irq = 0;
int i;
if (!(board_irq & irq_mask->all))
if (!(pci_irq & irq_mask->all))
return IRQ_NONE;
if (board_irq & irq_mask->kcan_rx0)
kvaser_pciefd_receive_irq(pcie);
if (pci_irq & irq_mask->kcan_rx0)
srb_irq = kvaser_pciefd_receive_irq(pcie);
for (i = 0; i < pcie->nr_channels; i++) {
if (!pcie->can[i]) {
dev_err(&pcie->pci->dev,
"IRQ mask points to unallocated controller\n");
break;
}
/* Check that mask matches channel (i) IRQ mask */
if (board_irq & irq_mask->kcan_tx[i])
if (pci_irq & irq_mask->kcan_tx[i])
kvaser_pciefd_transmit_irq(pcie->can[i]);
}
if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD0) {
/* Reset DMA buffer 0, may trigger new interrupt */
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
}
if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD1) {
/* Reset DMA buffer 1, may trigger new interrupt */
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
}
return IRQ_HANDLED;
}
@ -1733,7 +1732,7 @@ static void kvaser_pciefd_teardown_can_ctrls(struct kvaser_pciefd *pcie)
static int kvaser_pciefd_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int err;
int ret;
struct kvaser_pciefd *pcie;
const struct kvaser_pciefd_irq_mask *irq_mask;
void __iomem *irq_en_base;
@ -1747,39 +1746,52 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
pcie->driver_data = (const struct kvaser_pciefd_driver_data *)id->driver_data;
irq_mask = pcie->driver_data->irq_mask;
err = pci_enable_device(pdev);
if (err)
return err;
ret = pci_enable_device(pdev);
if (ret)
return ret;
err = pci_request_regions(pdev, KVASER_PCIEFD_DRV_NAME);
if (err)
ret = pci_request_regions(pdev, KVASER_PCIEFD_DRV_NAME);
if (ret)
goto err_disable_pci;
pcie->reg_base = pci_iomap(pdev, 0, 0);
if (!pcie->reg_base) {
err = -ENOMEM;
ret = -ENOMEM;
goto err_release_regions;
}
err = kvaser_pciefd_setup_board(pcie);
if (err)
ret = kvaser_pciefd_setup_board(pcie);
if (ret)
goto err_pci_iounmap;
err = kvaser_pciefd_setup_dma(pcie);
if (err)
ret = kvaser_pciefd_setup_dma(pcie);
if (ret)
goto err_pci_iounmap;
pci_set_master(pdev);
err = kvaser_pciefd_setup_can_ctrls(pcie);
if (err)
ret = kvaser_pciefd_setup_can_ctrls(pcie);
if (ret)
goto err_teardown_can_ctrls;
err = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler,
ret = pci_alloc_irq_vectors(pcie->pci, 1, 1, PCI_IRQ_INTX | PCI_IRQ_MSI);
if (ret < 0) {
dev_err(&pcie->pci->dev, "Failed to allocate IRQ vectors.\n");
goto err_teardown_can_ctrls;
}
ret = pci_irq_vector(pcie->pci, 0);
if (ret < 0)
goto err_pci_free_irq_vectors;
pcie->pci->irq = ret;
ret = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler,
IRQF_SHARED, KVASER_PCIEFD_DRV_NAME, pcie);
if (err)
goto err_teardown_can_ctrls;
if (ret) {
dev_err(&pcie->pci->dev, "Failed to request IRQ %d\n", pcie->pci->irq);
goto err_pci_free_irq_vectors;
}
iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1,
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
@ -1797,8 +1809,8 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
err = kvaser_pciefd_reg_candev(pcie);
if (err)
ret = kvaser_pciefd_reg_candev(pcie);
if (ret)
goto err_free_irq;
return 0;
@ -1808,6 +1820,9 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
iowrite32(0, irq_en_base);
free_irq(pcie->pci->irq, pcie);
err_pci_free_irq_vectors:
pci_free_irq_vectors(pcie->pci);
err_teardown_can_ctrls:
kvaser_pciefd_teardown_can_ctrls(pcie);
iowrite32(0, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CTRL_REG);
@ -1822,7 +1837,7 @@ static int kvaser_pciefd_probe(struct pci_dev *pdev,
err_disable_pci:
pci_disable_device(pdev);
return err;
return ret;
}
static void kvaser_pciefd_remove_all_ctrls(struct kvaser_pciefd *pcie)
@ -1853,7 +1868,7 @@ static void kvaser_pciefd_remove(struct pci_dev *pdev)
iowrite32(0, KVASER_PCIEFD_PCI_IEN_ADDR(pcie));
free_irq(pcie->pci->irq, pcie);
pci_free_irq_vectors(pcie->pci);
pci_iounmap(pdev, pcie->reg_base);
pci_release_regions(pdev);
pci_disable_device(pdev);

View File

@ -379,38 +379,72 @@ m_can_txe_fifo_read(struct m_can_classdev *cdev, u32 fgi, u32 offset, u32 *val)
return cdev->ops->read_fifo(cdev, addr_offset, val, 1);
}
static void m_can_config_endisable(struct m_can_classdev *cdev, bool enable)
static int m_can_cccr_update_bits(struct m_can_classdev *cdev, u32 mask, u32 val)
{
u32 cccr = m_can_read(cdev, M_CAN_CCCR);
u32 timeout = 10;
u32 val = 0;
u32 val_before = m_can_read(cdev, M_CAN_CCCR);
u32 val_after = (val_before & ~mask) | val;
size_t tries = 10;
/* Clear the Clock stop request if it was set */
if (cccr & CCCR_CSR)
cccr &= ~CCCR_CSR;
if (enable) {
/* enable m_can configuration */
m_can_write(cdev, M_CAN_CCCR, cccr | CCCR_INIT);
udelay(5);
/* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */
m_can_write(cdev, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE);
} else {
m_can_write(cdev, M_CAN_CCCR, cccr & ~(CCCR_INIT | CCCR_CCE));
if (!(mask & CCCR_INIT) && !(val_before & CCCR_INIT)) {
dev_err(cdev->dev,
"refusing to configure device when in normal mode\n");
return -EBUSY;
}
/* there's a delay for module initialization */
if (enable)
val = CCCR_INIT | CCCR_CCE;
/* The chip should be in standby mode when changing the CCCR register,
* and some chips set the CSR and CSA bits when in standby. Furthermore,
* the CSR and CSA bits should be written as zeros, even when they read
* ones.
*/
val_after &= ~(CCCR_CSR | CCCR_CSA);
while ((m_can_read(cdev, M_CAN_CCCR) & (CCCR_INIT | CCCR_CCE)) != val) {
if (timeout == 0) {
netdev_warn(cdev->net, "Failed to init module\n");
return;
}
timeout--;
udelay(1);
while (tries--) {
u32 val_read;
/* Write the desired value in each try, as setting some bits in
* the CCCR register require other bits to be set first. E.g.
* setting the NISO bit requires setting the CCE bit first.
*/
m_can_write(cdev, M_CAN_CCCR, val_after);
val_read = m_can_read(cdev, M_CAN_CCCR) & ~(CCCR_CSR | CCCR_CSA);
if (val_read == val_after)
return 0;
usleep_range(1, 5);
}
return -ETIMEDOUT;
}
static int m_can_config_enable(struct m_can_classdev *cdev)
{
int err;
/* CCCR_INIT must be set in order to set CCCR_CCE, but access to
* configuration registers should only be enabled when in standby mode,
* where CCCR_INIT is always set.
*/
err = m_can_cccr_update_bits(cdev, CCCR_CCE, CCCR_CCE);
if (err)
netdev_err(cdev->net, "failed to enable configuration mode\n");
return err;
}
static int m_can_config_disable(struct m_can_classdev *cdev)
{
int err;
/* Only clear CCCR_CCE, since CCCR_INIT cannot be cleared while in
* standby mode
*/
err = m_can_cccr_update_bits(cdev, CCCR_CCE, 0);
if (err)
netdev_err(cdev->net, "failed to disable configuration registers\n");
return err;
}
static void m_can_interrupt_enable(struct m_can_classdev *cdev, u32 interrupts)
@ -1403,7 +1437,9 @@ static int m_can_chip_config(struct net_device *dev)
interrupts &= ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TFE | IR_TCF |
IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N | IR_RF0F);
m_can_config_endisable(cdev, true);
err = m_can_config_enable(cdev);
if (err)
return err;
/* RX Buffer/FIFO Element Size 64 bytes data field */
m_can_write(cdev, M_CAN_RXESC,
@ -1521,7 +1557,9 @@ static int m_can_chip_config(struct net_device *dev)
FIELD_PREP(TSCC_TCP_MASK, 0xf) |
FIELD_PREP(TSCC_TSS_MASK, TSCC_TSS_INTERNAL));
m_can_config_endisable(cdev, false);
err = m_can_config_disable(cdev);
if (err)
return err;
if (cdev->ops->init)
cdev->ops->init(cdev);
@ -1550,7 +1588,11 @@ static int m_can_start(struct net_device *dev)
cdev->tx_fifo_putidx = FIELD_GET(TXFQS_TFQPI_MASK,
m_can_read(cdev, M_CAN_TXFQS));
return 0;
ret = m_can_cccr_update_bits(cdev, CCCR_INIT, 0);
if (ret)
netdev_err(dev, "failed to enter normal mode\n");
return ret;
}
static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
@ -1599,43 +1641,37 @@ static int m_can_check_core_release(struct m_can_classdev *cdev)
}
/* Selectable Non ISO support only in version 3.2.x
* This function checks if the bit is writable.
* Return 1 if the bit is writable, 0 if it is not, or negative on error.
*/
static bool m_can_niso_supported(struct m_can_classdev *cdev)
static int m_can_niso_supported(struct m_can_classdev *cdev)
{
u32 cccr_reg, cccr_poll = 0;
int niso_timeout = -ETIMEDOUT;
int i;
int ret, niso;
m_can_config_endisable(cdev, true);
cccr_reg = m_can_read(cdev, M_CAN_CCCR);
cccr_reg |= CCCR_NISO;
m_can_write(cdev, M_CAN_CCCR, cccr_reg);
ret = m_can_config_enable(cdev);
if (ret)
return ret;
for (i = 0; i <= 10; i++) {
cccr_poll = m_can_read(cdev, M_CAN_CCCR);
if (cccr_poll == cccr_reg) {
niso_timeout = 0;
break;
}
/* First try to set the NISO bit. */
niso = m_can_cccr_update_bits(cdev, CCCR_NISO, CCCR_NISO);
usleep_range(1, 5);
/* Then clear the it again. */
ret = m_can_cccr_update_bits(cdev, CCCR_NISO, 0);
if (ret) {
dev_err(cdev->dev, "failed to revert the NON-ISO bit in CCCR\n");
return ret;
}
/* Clear NISO */
cccr_reg &= ~(CCCR_NISO);
m_can_write(cdev, M_CAN_CCCR, cccr_reg);
ret = m_can_config_disable(cdev);
if (ret)
return ret;
m_can_config_endisable(cdev, false);
/* return false if time out (-ETIMEDOUT), else return true */
return !niso_timeout;
return niso == 0;
}
static int m_can_dev_setup(struct m_can_classdev *cdev)
{
struct net_device *dev = cdev->net;
int m_can_version, err;
int m_can_version, err, niso;
m_can_version = m_can_check_core_release(cdev);
/* return if unsupported version */
@ -1684,9 +1720,11 @@ static int m_can_dev_setup(struct m_can_classdev *cdev)
cdev->can.bittiming_const = &m_can_bittiming_const_31X;
cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X;
cdev->can.ctrlmode_supported |=
(m_can_niso_supported(cdev) ?
CAN_CTRLMODE_FD_NON_ISO : 0);
niso = m_can_niso_supported(cdev);
if (niso < 0)
return niso;
if (niso)
cdev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO;
break;
default:
dev_err(cdev->dev, "Unsupported version number: %2d",
@ -1694,21 +1732,26 @@ static int m_can_dev_setup(struct m_can_classdev *cdev)
return -EINVAL;
}
if (cdev->ops->init)
cdev->ops->init(cdev);
return 0;
/* Forcing standby mode should be redundant, as the chip should be in
* standby after a reset. Write the INIT bit anyways, should the chip
* be configured by previous stage.
*/
return m_can_cccr_update_bits(cdev, CCCR_INIT, CCCR_INIT);
}
static void m_can_stop(struct net_device *dev)
{
struct m_can_classdev *cdev = netdev_priv(dev);
int ret;
/* disable all interrupts */
m_can_disable_all_interrupts(cdev);
/* Set init mode to disengage from the network */
m_can_config_endisable(cdev, true);
ret = m_can_cccr_update_bits(cdev, CCCR_INIT, CCCR_INIT);
if (ret)
netdev_err(dev, "failed to enter standby mode: %pe\n",
ERR_PTR(ret));
/* set the state as STOPPED */
cdev->can.state = CAN_STATE_STOPPED;

View File

@ -453,10 +453,17 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
goto out_power;
}
ret = tcan4x5x_init(mcan_class);
tcan4x5x_check_wake(priv);
ret = tcan4x5x_write_tcan_reg(mcan_class, TCAN4X5X_INT_EN, 0);
if (ret) {
dev_err(&spi->dev, "tcan initialization failed %pe\n",
ERR_PTR(ret));
dev_err(&spi->dev, "Disabling interrupts failed %pe\n", ERR_PTR(ret));
goto out_power;
}
ret = tcan4x5x_clear_interrupts(mcan_class);
if (ret) {
dev_err(&spi->dev, "Clearing interrupts failed %pe\n", ERR_PTR(ret));
goto out_power;
}

View File

@ -34,12 +34,6 @@ static const struct can_bittiming_const mscan_bittiming_const = {
.brp_inc = 1,
};
struct mscan_state {
u8 mode;
u8 canrier;
u8 cantier;
};
static enum can_state state_map[] = {
CAN_STATE_ERROR_ACTIVE,
CAN_STATE_ERROR_WARNING,

View File

@ -122,7 +122,6 @@ struct plx_pci_card {
#define TEWS_PCI_VENDOR_ID 0x1498
#define TEWS_PCI_DEVICE_ID_TMPC810 0x032A
#define CTI_PCI_VENDOR_ID 0x12c4
#define CTI_PCI_DEVICE_ID_CRG001 0x0900
#define MOXA_PCI_VENDOR_ID 0x1393
@ -358,7 +357,7 @@ static const struct pci_device_id plx_pci_tbl[] = {
{
/* Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card */
PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
CTI_PCI_VENDOR_ID, CTI_PCI_DEVICE_ID_CRG001,
PCI_SUBVENDOR_ID_CONNECT_TECH, CTI_PCI_DEVICE_ID_CRG001,
0, 0,
(kernel_ulong_t)&plx_pci_card_info_cti
},

View File

@ -830,7 +830,6 @@ static int hi3110_can_probe(struct spi_device *spi)
struct device *dev = &spi->dev;
struct net_device *net;
struct hi3110_priv *priv;
const void *match;
struct clk *clk;
u32 freq;
int ret;
@ -874,11 +873,7 @@ static int hi3110_can_probe(struct spi_device *spi)
CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_BERR_REPORTING;
match = device_get_match_data(dev);
if (match)
priv->model = (enum hi3110_model)(uintptr_t)match;
else
priv->model = spi_get_device_id(spi)->driver_data;
priv->model = (enum hi3110_model)(uintptr_t)spi_get_device_match_data(spi);
priv->net = net;
priv->clk = clk;

View File

@ -28,7 +28,6 @@
#include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/freezer.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@ -482,9 +481,9 @@ static int mcp251x_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
{
if (mcp251x_gpio_is_input(offset))
return GPIOF_DIR_IN;
return GPIO_LINE_DIRECTION_IN;
return GPIOF_DIR_OUT;
return GPIO_LINE_DIRECTION_OUT;
}
static int mcp251x_gpio_get(struct gpio_chip *chip, unsigned int offset)
@ -1301,7 +1300,6 @@ MODULE_DEVICE_TABLE(spi, mcp251x_id_table);
static int mcp251x_can_probe(struct spi_device *spi)
{
const void *match = device_get_match_data(&spi->dev);
struct net_device *net;
struct mcp251x_priv *priv;
struct clk *clk;
@ -1339,10 +1337,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
priv->can.clock.freq = freq / 2;
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
if (match)
priv->model = (enum mcp251x_model)(uintptr_t)match;
else
priv->model = spi_get_device_id(spi)->driver_data;
priv->model = (enum mcp251x_model)(uintptr_t)spi_get_device_match_data(spi);
priv->net = net;
priv->clk = clk;

View File

@ -1989,7 +1989,6 @@ MODULE_DEVICE_TABLE(spi, mcp251xfd_id_table);
static int mcp251xfd_probe(struct spi_device *spi)
{
const void *match;
struct net_device *ndev;
struct mcp251xfd_priv *priv;
struct gpio_desc *rx_int;
@ -2081,13 +2080,7 @@ static int mcp251xfd_probe(struct spi_device *spi)
priv->pll_enable = pll_enable;
priv->reg_vdd = reg_vdd;
priv->reg_xceiver = reg_xceiver;
match = device_get_match_data(&spi->dev);
if (match)
priv->devtype_data = *(struct mcp251xfd_devtype_data *)match;
else
priv->devtype_data = *(struct mcp251xfd_devtype_data *)
spi_get_device_id(spi)->driver_data;
priv->devtype_data = *(struct mcp251xfd_devtype_data *)spi_get_device_match_data(spi);
/* Errata Reference:
* mcp2517fd: DS80000792C 5., mcp2518fd: DS80000789C 4.

View File

@ -91,6 +91,7 @@ config CAN_KVASER_USB
- Kvaser Leaf Light R v2
- Kvaser Mini PCI Express HS
- Kvaser Mini PCI Express 2xHS
- Kvaser Mini PCIe 1xCAN
- Kvaser USBcan Light 2xHS
- Kvaser USBcan II HS/HS
- Kvaser USBcan II HS/LS
@ -111,12 +112,14 @@ config CAN_KVASER_USB
- Kvaser USBcan Light 4xHS
- Kvaser USBcan Pro 2xHS v2
- Kvaser USBcan Pro 4xHS
- Kvaser USBcan Pro 5xCAN
- Kvaser USBcan Pro 5xHS
- Kvaser U100
- Kvaser U100P
- Kvaser U100S
- ATI Memorator Pro 2xHS v2
- ATI USBcan Pro 2xHS v2
- Vining 800
If unsure, say N.

View File

@ -89,6 +89,9 @@
#define USB_HYBRID_CANLIN_PRODUCT_ID 0x0115
#define USB_HYBRID_PRO_CANLIN_PRODUCT_ID 0x0116
#define USB_LEAF_V3_PRODUCT_ID 0x0117
#define USB_VINING_800_PRODUCT_ID 0x0119
#define USB_USBCAN_PRO_5XCAN_PRODUCT_ID 0x011A
#define USB_MINI_PCIE_1XCAN_PRODUCT_ID 0x011B
static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {
.quirks = KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP,
@ -238,6 +241,12 @@ static const struct usb_device_id kvaser_usb_table[] = {
.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_V3_PRODUCT_ID),
.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_VINING_800_PRODUCT_ID),
.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5XCAN_PRODUCT_ID),
.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_1XCAN_PRODUCT_ID),
.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
{ }
};
MODULE_DEVICE_TABLE(usb, kvaser_usb_table);

View File

@ -6,7 +6,7 @@
* Copyright (C) 2017 - 2018 Sandvik Mining and Construction Oy
*
* Description:
* This driver is developed for Axi CAN IP and for Zynq CANPS Controller.
* This driver is developed for AXI CAN IP, AXI CANFD IP, CANPS and CANFD PS Controller.
*/
#include <linux/bitfield.h>

View File

@ -2,7 +2,7 @@
/*
* linux/can/isotp.h
*
* Definitions for isotp CAN sockets (ISO 15765-2:2016)
* Definitions for ISO 15765-2 CAN transport protocol sockets
*
* Copyright (c) 2020 Volkswagen Group Electronic Research
* All rights reserved.

View File

@ -56,18 +56,17 @@ config CAN_GW
source "net/can/j1939/Kconfig"
config CAN_ISOTP
tristate "ISO 15765-2:2016 CAN transport protocol"
tristate "ISO 15765-2 CAN transport protocol"
help
CAN Transport Protocols offer support for segmented Point-to-Point
communication between CAN nodes via two defined CAN Identifiers.
This protocol driver implements segmented data transfers for CAN CC
(aka Classical CAN, CAN 2.0B) and CAN FD frame types which were
introduced with ISO 15765-2:2016.
As CAN frames can only transport a small amount of data bytes
(max. 8 bytes for 'classic' CAN and max. 64 bytes for CAN FD) this
(max. 8 bytes for CAN CC and max. 64 bytes for CAN FD) this
segmentation is needed to transport longer Protocol Data Units (PDU)
as needed e.g. for vehicle diagnosis (UDS, ISO 14229) or IP-over-CAN
traffic.
This protocol driver implements data transfers according to
ISO 15765-2:2016 for 'classic' CAN and CAN FD frame types.
If you want to perform automotive vehicle diagnostic services (UDS),
say 'y'.
endif

View File

@ -72,7 +72,7 @@
#include <net/sock.h>
#include <net/net_namespace.h>
MODULE_DESCRIPTION("PF_CAN isotp 15765-2:2016 protocol");
MODULE_DESCRIPTION("PF_CAN ISO 15765-2 transport protocol");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Oliver Hartkopp <socketcan@hartkopp.net>");
MODULE_ALIAS("can-proto-6");
@ -83,10 +83,11 @@ MODULE_ALIAS("can-proto-6");
(CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG) : \
(CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
/* ISO 15765-2:2016 supports more than 4095 byte per ISO PDU as the FF_DL can
* take full 32 bit values (4 Gbyte). We would need some good concept to handle
* this between user space and kernel space. For now set the static buffer to
* something about 8 kbyte to be able to test this new functionality.
/* Since ISO 15765-2:2016 the CAN isotp protocol supports more than 4095
* byte per ISO PDU as the FF_DL can take full 32 bit values (4 Gbyte).
* We would need some good concept to handle this between user space and
* kernel space. For now set the static buffer to something about 8 kbyte
* to be able to test this new functionality.
*/
#define DEFAULT_MAX_PDU_SIZE 8300