mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
Merge tag 'linux-can-next-for-4.19-20180727' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says: ==================== pull-request: can-next 2018-01-16 this is a pull request for net-next/master consisting of 38 patches. Dan Murphy's patch fixes the path to a file in the comment of the CAN Error Message Frame Mask structure. A patch by Colin Ian King fixes a typo in the cc770 driver. The next patch is by me an sorts the Kconfigand Makefile entries of the CAN-USB driver subdir alphabetically. The patch by Jakob Unterwurzacher adds support for the UCAN USB-CAN adapter. YueHaibing's patch replaces a open coded skb_put()+memset() by skb_put_zero() in the CAN-dev infrastructure. Zhu Yi provides a patch to enable multi-queue CAN devices. Three patches by Luc Van Oostenryck fix the return value of several driver's xmit function, I contribute a patch for the a fourth driver. Fabio Estevam's patch switches the flexcan driver to SPDX identifier. Two patches by Jia-Ju Bai replace the mdelay() by a usleep_range() in the sja1000 drivers. The next 6 patches are by Anssi Hannula and refactor the xilinx CAN driver and add support for the xilinx CAN FD core. A patch by Gustavo A. R. Silva adds fallthrough annotation to the peak_usb driver. 5 patches by Stephane Grosjean for the peak CANFD driver do some cleanups and provide more improvements for further firmware releases. The remaining 13 patches are by Jimmy Assarsson and the first clean up the kvaser_usb driver, so that the later patches add support for the Kvaser USB hydra family. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -2,20 +2,26 @@ Xilinx Axi CAN/Zynq CANPS controller Device Tree Bindings
|
||||
---------------------------------------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "xlnx,zynq-can-1.0" for Zynq CAN
|
||||
controllers and "xlnx,axi-can-1.00.a" for Axi CAN
|
||||
controllers.
|
||||
- reg : Physical base address and size of the Axi CAN/Zynq
|
||||
CANPS registers map.
|
||||
- compatible : Should be:
|
||||
- "xlnx,zynq-can-1.0" for Zynq CAN controllers
|
||||
- "xlnx,axi-can-1.00.a" for Axi CAN controllers
|
||||
- "xlnx,canfd-1.0" for CAN FD controllers
|
||||
- reg : Physical base address and size of the controller
|
||||
registers map.
|
||||
- interrupts : Property with a value describing the interrupt
|
||||
number.
|
||||
- interrupt-parent : Must be core interrupt controller
|
||||
- clock-names : List of input clock names - "can_clk", "pclk"
|
||||
(For CANPS), "can_clk" , "s_axi_aclk"(For AXI CAN)
|
||||
- clock-names : List of input clock names
|
||||
- "can_clk", "pclk" (For CANPS),
|
||||
- "can_clk", "s_axi_aclk" (For AXI CAN and CAN FD).
|
||||
(See clock bindings for details).
|
||||
- clocks : Clock phandles (see clock bindings for details).
|
||||
- tx-fifo-depth : Can Tx fifo depth.
|
||||
- rx-fifo-depth : Can Rx fifo depth.
|
||||
- tx-fifo-depth : Can Tx fifo depth (Zynq, Axi CAN).
|
||||
- rx-fifo-depth : Can Rx fifo depth (Zynq, Axi CAN, CAN FD in
|
||||
sequential Rx mode).
|
||||
- tx-mailbox-count : Can Tx mailbox buffer count (CAN FD).
|
||||
- rx-mailbox-count : Can Rx mailbox buffer count (CAN FD in mailbox Rx
|
||||
mode).
|
||||
|
||||
|
||||
Example:
|
||||
@@ -42,3 +48,14 @@ For Axi CAN Dts file:
|
||||
tx-fifo-depth = <0x40>;
|
||||
rx-fifo-depth = <0x40>;
|
||||
};
|
||||
For CAN FD Dts file:
|
||||
canfd_0: canfd@40000000 {
|
||||
compatible = "xlnx,canfd-1.0";
|
||||
clocks = <&clkc 0>, <&clkc 1>;
|
||||
clock-names = "can_clk", "s_axi_aclk";
|
||||
reg = <0x40000000 0x2000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 59 1>;
|
||||
tx-mailbox-count = <0x20>;
|
||||
rx-fifo-depth = <0x20>;
|
||||
};
|
||||
|
||||
332
Documentation/networking/can_ucan_protocol.rst
Normal file
332
Documentation/networking/can_ucan_protocol.rst
Normal file
@@ -0,0 +1,332 @@
|
||||
=================
|
||||
The UCAN Protocol
|
||||
=================
|
||||
|
||||
UCAN is the protocol used by the microcontroller-based USB-CAN
|
||||
adapter that is integrated on System-on-Modules from Theobroma Systems
|
||||
and that is also available as a standalone USB stick.
|
||||
|
||||
The UCAN protocol has been designed to be hardware-independent.
|
||||
It is modeled closely after how Linux represents CAN devices
|
||||
internally. All multi-byte integers are encoded as Little Endian.
|
||||
|
||||
All structures mentioned in this document are defined in
|
||||
``drivers/net/can/usb/ucan.c``.
|
||||
|
||||
USB Endpoints
|
||||
=============
|
||||
|
||||
UCAN devices use three USB endpoints:
|
||||
|
||||
CONTROL endpoint
|
||||
The driver sends device management commands on this endpoint
|
||||
|
||||
IN endpoint
|
||||
The device sends CAN data frames and CAN error frames
|
||||
|
||||
OUT endpoint
|
||||
The driver sends CAN data frames on the out endpoint
|
||||
|
||||
|
||||
CONTROL Messages
|
||||
================
|
||||
|
||||
UCAN devices are configured using vendor requests on the control pipe.
|
||||
|
||||
To support multiple CAN interfaces in a single USB device all
|
||||
configuration commands target the corresponding interface in the USB
|
||||
descriptor.
|
||||
|
||||
The driver uses ``ucan_ctrl_command_in/out`` and
|
||||
``ucan_device_request_in`` to deliver commands to the device.
|
||||
|
||||
Setup Packet
|
||||
------------
|
||||
|
||||
================= =====================================================
|
||||
``bmRequestType`` Direction | Vendor | (Interface or Device)
|
||||
``bRequest`` Command Number
|
||||
``wValue`` Subcommand Number (16 Bit) or 0 if not used
|
||||
``wIndex`` USB Interface Index (0 for device commands)
|
||||
``wLength`` * Host to Device - Number of bytes to transmit
|
||||
* Device to Host - Maximum Number of bytes to
|
||||
receive. If the device send less. Commom ZLP
|
||||
semantics are used.
|
||||
================= =====================================================
|
||||
|
||||
Error Handling
|
||||
--------------
|
||||
|
||||
The device indicates failed control commands by stalling the
|
||||
pipe.
|
||||
|
||||
Device Commands
|
||||
---------------
|
||||
|
||||
UCAN_DEVICE_GET_FW_STRING
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Dev2Host; optional*
|
||||
|
||||
Request the device firmware string.
|
||||
|
||||
|
||||
Interface Commands
|
||||
------------------
|
||||
|
||||
UCAN_COMMAND_START
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Host2Dev; mandatory*
|
||||
|
||||
Bring the CAN interface up.
|
||||
|
||||
Payload Format
|
||||
``ucan_ctl_payload_t.cmd_start``
|
||||
|
||||
==== ============================
|
||||
mode or mask of ``UCAN_MODE_*``
|
||||
==== ============================
|
||||
|
||||
UCAN_COMMAND_STOP
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Host2Dev; mandatory*
|
||||
|
||||
Stop the CAN interface
|
||||
|
||||
Payload Format
|
||||
*empty*
|
||||
|
||||
UCAN_COMMAND_RESET
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Host2Dev; mandatory*
|
||||
|
||||
Reset the CAN controller (including error counters)
|
||||
|
||||
Payload Format
|
||||
*empty*
|
||||
|
||||
UCAN_COMMAND_GET
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
*Host2Dev; mandatory*
|
||||
|
||||
Get Information from the Device
|
||||
|
||||
Subcommands
|
||||
^^^^^^^^^^^
|
||||
|
||||
UCAN_COMMAND_GET_INFO
|
||||
Request the device information structure ``ucan_ctl_payload_t.device_info``.
|
||||
|
||||
See the ``device_info`` field for details, and
|
||||
``uapi/linux/can/netlink.h`` for an explanation of the
|
||||
``can_bittiming fields``.
|
||||
|
||||
Payload Format
|
||||
``ucan_ctl_payload_t.device_info``
|
||||
|
||||
UCAN_COMMAND_GET_PROTOCOL_VERSION
|
||||
|
||||
Request the device protocol version
|
||||
``ucan_ctl_payload_t.protocol_version``. The current protocol version is 3.
|
||||
|
||||
Payload Format
|
||||
``ucan_ctl_payload_t.protocol_version``
|
||||
|
||||
.. note:: Devices that do not implement this command use the old
|
||||
protocol version 1
|
||||
|
||||
UCAN_COMMAND_SET_BITTIMING
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Host2Dev; mandatory*
|
||||
|
||||
Setup bittiming by sending the the structure
|
||||
``ucan_ctl_payload_t.cmd_set_bittiming`` (see ``struct bittiming`` for
|
||||
details)
|
||||
|
||||
Payload Format
|
||||
``ucan_ctl_payload_t.cmd_set_bittiming``.
|
||||
|
||||
UCAN_SLEEP/WAKE
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
*Host2Dev; optional*
|
||||
|
||||
Configure sleep and wake modes. Not yet supported by the driver.
|
||||
|
||||
UCAN_FILTER
|
||||
~~~~~~~~~~~
|
||||
|
||||
*Host2Dev; optional*
|
||||
|
||||
Setup hardware CAN filters. Not yet supported by the driver.
|
||||
|
||||
Allowed interface commands
|
||||
--------------------------
|
||||
|
||||
================== =================== ==================
|
||||
Legal Device State Command New Device State
|
||||
================== =================== ==================
|
||||
stopped SET_BITTIMING stopped
|
||||
stopped START started
|
||||
started STOP or RESET stopped
|
||||
stopped STOP or RESET stopped
|
||||
started RESTART started
|
||||
any GET *no change*
|
||||
================== =================== ==================
|
||||
|
||||
IN Message Format
|
||||
=================
|
||||
|
||||
A data packet on the USB IN endpoint contains one or more
|
||||
``ucan_message_in`` values. If multiple messages are batched in a USB
|
||||
data packet, the ``len`` field can be used to jump to the next
|
||||
``ucan_message_in`` value (take care to sanity-check the ``len`` value
|
||||
against the actual data size).
|
||||
|
||||
.. _can_ucan_in_message_len:
|
||||
|
||||
``len`` field
|
||||
-------------
|
||||
|
||||
Each ``ucan_message_in`` must be aligned to a 4-byte boundary (relative
|
||||
to the start of the start of the data buffer). That means that there
|
||||
may be padding bytes between multiple ``ucan_message_in`` values:
|
||||
|
||||
.. code::
|
||||
|
||||
+----------------------------+ < 0
|
||||
| |
|
||||
| struct ucan_message_in |
|
||||
| |
|
||||
+----------------------------+ < len
|
||||
[padding]
|
||||
+----------------------------+ < round_up(len, 4)
|
||||
| |
|
||||
| struct ucan_message_in |
|
||||
| |
|
||||
+----------------------------+
|
||||
[...]
|
||||
|
||||
``type`` field
|
||||
--------------
|
||||
|
||||
The ``type`` field specifies the type of the message.
|
||||
|
||||
UCAN_IN_RX
|
||||
~~~~~~~~~~
|
||||
|
||||
``subtype``
|
||||
zero
|
||||
|
||||
Data received from the CAN bus (ID + payload).
|
||||
|
||||
UCAN_IN_TX_COMPLETE
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``subtype``
|
||||
zero
|
||||
|
||||
The CAN device has sent a message to the CAN bus. It answers with a
|
||||
list of of tuples <echo-ids, flags>.
|
||||
|
||||
The echo-id identifies the frame from (echos the id from a previous
|
||||
UCAN_OUT_TX message). The flag indicates the result of the
|
||||
transmission. Whereas a set Bit 0 indicates success. All other bits
|
||||
are reserved and set to zero.
|
||||
|
||||
Flow Control
|
||||
------------
|
||||
|
||||
When receiving CAN messages there is no flow control on the USB
|
||||
buffer. The driver has to handle inbound message quickly enough to
|
||||
avoid drops. I case the device buffer overflow the condition is
|
||||
reported by sending corresponding error frames (see
|
||||
:ref:`can_ucan_error_handling`)
|
||||
|
||||
|
||||
OUT Message Format
|
||||
==================
|
||||
|
||||
A data packet on the USB OUT endpoint contains one or more ``struct
|
||||
ucan_message_out`` values. If multiple messages are batched into one
|
||||
data packet, the device uses the ``len`` field to jump to the next
|
||||
ucan_message_out value. Each ucan_message_out must be aligned to 4
|
||||
bytes (relative to the start of the data buffer). The mechanism is
|
||||
same as described in :ref:`can_ucan_in_message_len`.
|
||||
|
||||
.. code::
|
||||
|
||||
+----------------------------+ < 0
|
||||
| |
|
||||
| struct ucan_message_out |
|
||||
| |
|
||||
+----------------------------+ < len
|
||||
[padding]
|
||||
+----------------------------+ < round_up(len, 4)
|
||||
| |
|
||||
| struct ucan_message_out |
|
||||
| |
|
||||
+----------------------------+
|
||||
[...]
|
||||
|
||||
``type`` field
|
||||
--------------
|
||||
|
||||
In protocol version 3 only ``UCAN_OUT_TX`` is defined, others are used
|
||||
only by legacy devices (protocol version 1).
|
||||
|
||||
UCAN_OUT_TX
|
||||
~~~~~~~~~~~
|
||||
``subtype``
|
||||
echo id to be replied within a CAN_IN_TX_COMPLETE message
|
||||
|
||||
Transmit a CAN frame. (parameters: ``id``, ``data``)
|
||||
|
||||
Flow Control
|
||||
------------
|
||||
|
||||
When the device outbound buffers are full it starts sending *NAKs* on
|
||||
the *OUT* pipe until more buffers are available. The driver stops the
|
||||
queue when a certain threshold of out packets are incomplete.
|
||||
|
||||
.. _can_ucan_error_handling:
|
||||
|
||||
CAN Error Handling
|
||||
==================
|
||||
|
||||
If error reporting is turned on the device encodes errors into CAN
|
||||
error frames (see ``uapi/linux/can/error.h``) and sends it using the
|
||||
IN endpoint. The driver updates its error statistics and forwards
|
||||
it.
|
||||
|
||||
Although UCAN devices can suppress error frames completely, in Linux
|
||||
the driver is always interested. Hence, the device is always started with
|
||||
the ``UCAN_MODE_BERR_REPORT`` set. Filtering those messages for the
|
||||
user space is done by the driver.
|
||||
|
||||
Bus OFF
|
||||
-------
|
||||
|
||||
- The device does not recover from bus of automatically.
|
||||
- Bus OFF is indicated by an error frame (see ``uapi/linux/can/error.h``)
|
||||
- Bus OFF recovery is started by ``UCAN_COMMAND_RESTART``
|
||||
- Once Bus OFF recover is completed the device sends an error frame
|
||||
indicating that it is on ERROR-ACTIVE state.
|
||||
- During Bus OFF no frames are sent by the device.
|
||||
- During Bus OFF transmission requests from the host are completed
|
||||
immediately with the success bit left unset.
|
||||
|
||||
Example Conversation
|
||||
====================
|
||||
|
||||
#) Device is connected to USB
|
||||
#) Host sends command ``UCAN_COMMAND_RESET``, subcmd 0
|
||||
#) Host sends command ``UCAN_COMMAND_GET``, subcmd ``UCAN_COMMAND_GET_INFO``
|
||||
#) Device sends ``UCAN_IN_DEVICE_INFO``
|
||||
#) Host sends command ``UCAN_OUT_SET_BITTIMING``
|
||||
#) Host sends command ``UCAN_COMMAND_START``, subcmd 0, mode ``UCAN_MODE_BERR_REPORT``
|
||||
@@ -10,6 +10,7 @@ Contents:
|
||||
af_xdp
|
||||
batman-adv
|
||||
can
|
||||
can_ucan_protocol
|
||||
dpaa2/index
|
||||
e100
|
||||
e1000
|
||||
|
||||
@@ -73,7 +73,7 @@ MODULE_PARM_DESC(msgobj15_eff, "Extended 29-bit frames for message object 15 "
|
||||
|
||||
static int i82527_compat;
|
||||
module_param(i82527_compat, int, 0444);
|
||||
MODULE_PARM_DESC(i82527_compat, "Strict Intel 82527 comptibility mode "
|
||||
MODULE_PARM_DESC(i82527_compat, "Strict Intel 82527 compatibility mode "
|
||||
"without using additional functions");
|
||||
|
||||
/*
|
||||
|
||||
@@ -649,8 +649,7 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
|
||||
can_skb_prv(skb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
|
||||
*cf = skb_put(skb, sizeof(struct can_frame));
|
||||
memset(*cf, 0, sizeof(struct can_frame));
|
||||
*cf = skb_put_zero(skb, sizeof(struct can_frame));
|
||||
|
||||
return skb;
|
||||
}
|
||||
@@ -678,8 +677,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,
|
||||
can_skb_prv(skb)->ifindex = dev->ifindex;
|
||||
can_skb_prv(skb)->skbcnt = 0;
|
||||
|
||||
*cfd = skb_put(skb, sizeof(struct canfd_frame));
|
||||
memset(*cfd, 0, sizeof(struct canfd_frame));
|
||||
*cfd = skb_put_zero(skb, sizeof(struct canfd_frame));
|
||||
|
||||
return skb;
|
||||
}
|
||||
@@ -703,7 +701,8 @@ EXPORT_SYMBOL_GPL(alloc_can_err_skb);
|
||||
/*
|
||||
* Allocate and setup space for the CAN network device
|
||||
*/
|
||||
struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
|
||||
struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
|
||||
unsigned int txqs, unsigned int rxqs)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct can_priv *priv;
|
||||
@@ -715,7 +714,8 @@ struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
|
||||
else
|
||||
size = sizeof_priv;
|
||||
|
||||
dev = alloc_netdev(size, "can%d", NET_NAME_UNKNOWN, can_setup);
|
||||
dev = alloc_netdev_mqs(size, "can%d", NET_NAME_UNKNOWN, can_setup,
|
||||
txqs, rxqs);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
@@ -734,7 +734,7 @@ struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alloc_candev);
|
||||
EXPORT_SYMBOL_GPL(alloc_candev_mqs);
|
||||
|
||||
/*
|
||||
* Free space of the CAN network device
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
/*
|
||||
* flexcan.c - FLEXCAN CAN controller driver
|
||||
*
|
||||
* Copyright (c) 2005-2006 Varma Electronics Oy
|
||||
* Copyright (c) 2009 Sascha Hauer, Pengutronix
|
||||
* Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
|
||||
* Copyright (c) 2014 David Jander, Protonic Holland
|
||||
*
|
||||
* Based on code originally by Andrey Volkov <avolkov@varma-el.com>
|
||||
*
|
||||
* LICENCE:
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// flexcan.c - FLEXCAN CAN controller driver
|
||||
//
|
||||
// Copyright (c) 2005-2006 Varma Electronics Oy
|
||||
// Copyright (c) 2009 Sascha Hauer, Pengutronix
|
||||
// Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
|
||||
// Copyright (c) 2014 David Jander, Protonic Holland
|
||||
//
|
||||
// Based on code originally by Andrey Volkov <avolkov@varma-el.com>
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/can.h>
|
||||
@@ -523,7 +512,7 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
const struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||
|
||||
@@ -1684,7 +1684,7 @@ static int ican3_stop(struct net_device *ndev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ican3_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
static netdev_tx_t ican3_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
{
|
||||
struct ican3_dev *mod = netdev_priv(ndev);
|
||||
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||
|
||||
@@ -486,7 +486,7 @@ int peak_canfd_handle_msgs_list(struct peak_canfd_priv *priv,
|
||||
if (msg_size <= 0)
|
||||
break;
|
||||
|
||||
msg_ptr += msg_size;
|
||||
msg_ptr += ALIGN(msg_size, 4);
|
||||
}
|
||||
|
||||
if (msg_size < 0)
|
||||
|
||||
@@ -174,9 +174,6 @@ struct pciefd_page {
|
||||
u32 size;
|
||||
};
|
||||
|
||||
#define CANFD_IRQ_SET 0x00000001
|
||||
#define CANFD_TX_PATH_SET 0x00000002
|
||||
|
||||
/* CAN-FD channel object */
|
||||
struct pciefd_board;
|
||||
struct pciefd_can {
|
||||
@@ -418,7 +415,7 @@ static int pciefd_pre_cmd(struct peak_canfd_priv *ucan)
|
||||
break;
|
||||
|
||||
/* going into operational mode: setup IRQ handler */
|
||||
err = request_irq(priv->board->pci_dev->irq,
|
||||
err = request_irq(priv->ucan.ndev->irq,
|
||||
pciefd_irq_handler,
|
||||
IRQF_SHARED,
|
||||
PCIEFD_DRV_NAME,
|
||||
@@ -491,15 +488,18 @@ static int pciefd_post_cmd(struct peak_canfd_priv *ucan)
|
||||
|
||||
/* controller now in reset mode: */
|
||||
|
||||
/* stop and reset DMA addresses in Tx/Rx engines */
|
||||
pciefd_can_clear_tx_dma(priv);
|
||||
pciefd_can_clear_rx_dma(priv);
|
||||
|
||||
/* disable IRQ for this CAN */
|
||||
pciefd_can_writereg(priv, CANFD_CTL_IEN_BIT,
|
||||
PCIEFD_REG_CAN_RX_CTL_CLR);
|
||||
|
||||
free_irq(priv->board->pci_dev->irq, priv);
|
||||
/* stop and reset DMA addresses in Tx/Rx engines */
|
||||
pciefd_can_clear_tx_dma(priv);
|
||||
pciefd_can_clear_rx_dma(priv);
|
||||
|
||||
/* wait for above commands to complete (read cycle) */
|
||||
(void)pciefd_sys_readreg(priv->board, PCIEFD_REG_SYS_VER1);
|
||||
|
||||
free_irq(priv->ucan.ndev->irq, priv);
|
||||
|
||||
ucan->can.state = CAN_STATE_STOPPED;
|
||||
|
||||
@@ -638,7 +638,7 @@ static int pciefd_can_probe(struct pciefd_board *pciefd)
|
||||
GFP_KERNEL);
|
||||
if (!priv->tx_dma_vaddr) {
|
||||
dev_err(&pciefd->pci_dev->dev,
|
||||
"Tx dmaim_alloc_coherent(%u) failure\n",
|
||||
"Tx dmam_alloc_coherent(%u) failure\n",
|
||||
PCIEFD_TX_DMA_SIZE);
|
||||
goto err_free_candev;
|
||||
}
|
||||
@@ -691,7 +691,7 @@ static int pciefd_can_probe(struct pciefd_board *pciefd)
|
||||
pciefd->can[pciefd->can_count] = priv;
|
||||
|
||||
dev_info(&pciefd->pci_dev->dev, "%s at reg_base=0x%p irq=%d\n",
|
||||
ndev->name, priv->reg_base, pciefd->pci_dev->irq);
|
||||
ndev->name, priv->reg_base, ndev->irq);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -608,7 +608,7 @@ static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
writeb(0x00, cfg_base + PITA_GPIOICR);
|
||||
/* Toggle reset */
|
||||
writeb(0x05, cfg_base + PITA_MISC + 3);
|
||||
mdelay(5);
|
||||
usleep_range(5000, 6000);
|
||||
/* Leave parport mux mode */
|
||||
writeb(0x04, cfg_base + PITA_MISC + 3);
|
||||
|
||||
|
||||
@@ -530,7 +530,7 @@ static int pcan_add_channels(struct pcan_pccard *card)
|
||||
pcan_write_reg(card, PCC_CCR, ccr);
|
||||
|
||||
/* wait 2ms before unresetting channels */
|
||||
mdelay(2);
|
||||
usleep_range(2000, 3000);
|
||||
|
||||
ccr &= ~PCC_CCR_RST_ALL;
|
||||
pcan_write_reg(card, PCC_CCR, ccr);
|
||||
|
||||
@@ -409,7 +409,7 @@ static int sun4ican_set_mode(struct net_device *dev, enum can_mode mode)
|
||||
* xx xx xx xx ff ll 00 11 22 33 44 55 66 77
|
||||
* [ can_id ] [flags] [len] [can data (up to 8 bytes]
|
||||
*/
|
||||
static int sun4ican_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
static netdev_tx_t sun4ican_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct sun4ican_priv *priv = netdev_priv(dev);
|
||||
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
menu "CAN USB interfaces"
|
||||
depends on USB
|
||||
|
||||
config CAN_8DEV_USB
|
||||
tristate "8 devices USB2CAN interface"
|
||||
---help---
|
||||
This driver supports the USB2CAN interface
|
||||
from 8 devices (http://www.8devices.com).
|
||||
|
||||
config CAN_EMS_USB
|
||||
tristate "EMS CPC-USB/ARM7 CAN/USB interface"
|
||||
---help---
|
||||
@@ -26,7 +32,7 @@ config CAN_KVASER_USB
|
||||
tristate "Kvaser CAN/USB interface"
|
||||
---help---
|
||||
This driver adds support for Kvaser CAN/USB devices like Kvaser
|
||||
Leaf Light and Kvaser USBcan II.
|
||||
Leaf Light, Kvaser USBcan II and Kvaser Memorator Pro 5xHS.
|
||||
|
||||
The driver provides support for the following devices:
|
||||
- Kvaser Leaf Light
|
||||
@@ -55,12 +61,30 @@ config CAN_KVASER_USB
|
||||
- Kvaser Memorator HS/HS
|
||||
- Kvaser Memorator HS/LS
|
||||
- Scania VCI2 (if you have the Kvaser logo on top)
|
||||
- Kvaser BlackBird v2
|
||||
- Kvaser Leaf Pro HS v2
|
||||
- Kvaser Hybrid 2xCAN/LIN
|
||||
- Kvaser Hybrid Pro 2xCAN/LIN
|
||||
- Kvaser Memorator 2xHS v2
|
||||
- Kvaser Memorator Pro 2xHS v2
|
||||
- Kvaser Memorator Pro 5xHS
|
||||
- Kvaser USBcan Light 4xHS
|
||||
- Kvaser USBcan Pro 2xHS v2
|
||||
- Kvaser USBcan Pro 5xHS
|
||||
- ATI Memorator Pro 2xHS v2
|
||||
- ATI USBcan Pro 2xHS v2
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called kvaser_usb.
|
||||
|
||||
config CAN_MCBA_USB
|
||||
tristate "Microchip CAN BUS Analyzer interface"
|
||||
---help---
|
||||
This driver supports the CAN BUS Analyzer interface
|
||||
from Microchip (http://www.microchip.com/development-tools/).
|
||||
|
||||
config CAN_PEAK_USB
|
||||
tristate "PEAK PCAN-USB/USB Pro interfaces for CAN 2.0b/CAN-FD"
|
||||
---help---
|
||||
@@ -77,16 +101,26 @@ config CAN_PEAK_USB
|
||||
|
||||
(see also http://www.peak-system.com).
|
||||
|
||||
config CAN_8DEV_USB
|
||||
tristate "8 devices USB2CAN interface"
|
||||
---help---
|
||||
This driver supports the USB2CAN interface
|
||||
from 8 devices (http://www.8devices.com).
|
||||
|
||||
config CAN_MCBA_USB
|
||||
tristate "Microchip CAN BUS Analyzer interface"
|
||||
---help---
|
||||
This driver supports the CAN BUS Analyzer interface
|
||||
from Microchip (http://www.microchip.com/development-tools/).
|
||||
|
||||
config CAN_UCAN
|
||||
tristate "Theobroma Systems UCAN interface"
|
||||
---help---
|
||||
This driver supports the Theobroma Systems
|
||||
UCAN USB-CAN interface.
|
||||
|
||||
The UCAN driver supports the microcontroller-based USB/CAN
|
||||
adapters from Theobroma Systems. There are two form-factors
|
||||
that run essentially the same firmware:
|
||||
|
||||
* Seal: standalone USB stick
|
||||
https://www.theobroma-systems.com/seal)
|
||||
* Mule: integrated on the PCB of various System-on-Modules
|
||||
from Theobroma Systems like the A31-µQ7 and the RK3399-Q7
|
||||
(https://www.theobroma-systems.com/rk3399-q7)
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
# Makefile for the Linux Controller Area Network USB drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o
|
||||
obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
|
||||
obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o
|
||||
obj-$(CONFIG_CAN_GS_USB) += gs_usb.o
|
||||
obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o
|
||||
obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/
|
||||
obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o
|
||||
obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb/
|
||||
obj-$(CONFIG_CAN_MCBA_USB) += mcba_usb.o
|
||||
obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/
|
||||
obj-$(CONFIG_CAN_UCAN) += ucan.o
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2
drivers/net/can/usb/kvaser_usb/Makefile
Normal file
2
drivers/net/can/usb/kvaser_usb/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o
|
||||
kvaser_usb-y = kvaser_usb_core.o kvaser_usb_leaf.o kvaser_usb_hydra.o
|
||||
188
drivers/net/can/usb/kvaser_usb/kvaser_usb.h
Normal file
188
drivers/net/can/usb/kvaser_usb/kvaser_usb.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Parts of this driver are based on the following:
|
||||
* - Kvaser linux leaf driver (version 4.78)
|
||||
* - CAN driver for esd CAN-USB/2
|
||||
* - Kvaser linux usbcanII driver (version 5.3)
|
||||
* - Kvaser linux mhydra driver (version 5.24)
|
||||
*
|
||||
* Copyright (C) 2002-2018 KVASER AB, Sweden. All rights reserved.
|
||||
* Copyright (C) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
|
||||
* Copyright (C) 2012 Olivier Sobrie <olivier@sobrie.be>
|
||||
* Copyright (C) 2015 Valeo S.A.
|
||||
*/
|
||||
|
||||
#ifndef KVASER_USB_H
|
||||
#define KVASER_USB_H
|
||||
|
||||
/* Kvaser USB CAN dongles are divided into three major platforms:
|
||||
* - Hydra: Running firmware labeled as 'mhydra'
|
||||
* - Leaf: Based on Renesas M32C or Freescale i.MX28, running firmware labeled
|
||||
* as 'filo'
|
||||
* - UsbcanII: Based on Renesas M16C, running firmware labeled as 'helios'
|
||||
*/
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
|
||||
#define KVASER_USB_MAX_RX_URBS 4
|
||||
#define KVASER_USB_MAX_TX_URBS 128
|
||||
#define KVASER_USB_TIMEOUT 1000 /* msecs */
|
||||
#define KVASER_USB_RX_BUFFER_SIZE 3072
|
||||
#define KVASER_USB_MAX_NET_DEVICES 5
|
||||
|
||||
/* USB devices features */
|
||||
#define KVASER_USB_HAS_SILENT_MODE BIT(0)
|
||||
#define KVASER_USB_HAS_TXRX_ERRORS BIT(1)
|
||||
|
||||
/* Device capabilities */
|
||||
#define KVASER_USB_CAP_BERR_CAP 0x01
|
||||
#define KVASER_USB_CAP_EXT_CAP 0x02
|
||||
#define KVASER_USB_HYDRA_CAP_EXT_CMD 0x04
|
||||
|
||||
struct kvaser_usb_dev_cfg;
|
||||
|
||||
enum kvaser_usb_leaf_family {
|
||||
KVASER_LEAF,
|
||||
KVASER_USBCAN,
|
||||
};
|
||||
|
||||
#define KVASER_USB_HYDRA_MAX_CMD_LEN 128
|
||||
struct kvaser_usb_dev_card_data_hydra {
|
||||
u8 channel_to_he[KVASER_USB_MAX_NET_DEVICES];
|
||||
u8 sysdbg_he;
|
||||
spinlock_t transid_lock; /* lock for transid */
|
||||
u16 transid;
|
||||
/* lock for usb_rx_leftover and usb_rx_leftover_len */
|
||||
spinlock_t usb_rx_leftover_lock;
|
||||
u8 usb_rx_leftover[KVASER_USB_HYDRA_MAX_CMD_LEN];
|
||||
u8 usb_rx_leftover_len;
|
||||
};
|
||||
struct kvaser_usb_dev_card_data {
|
||||
u32 ctrlmode_supported;
|
||||
u32 capabilities;
|
||||
union {
|
||||
struct {
|
||||
enum kvaser_usb_leaf_family family;
|
||||
} leaf;
|
||||
struct kvaser_usb_dev_card_data_hydra hydra;
|
||||
};
|
||||
};
|
||||
|
||||
/* Context for an outstanding, not yet ACKed, transmission */
|
||||
struct kvaser_usb_tx_urb_context {
|
||||
struct kvaser_usb_net_priv *priv;
|
||||
u32 echo_index;
|
||||
int dlc;
|
||||
};
|
||||
|
||||
struct kvaser_usb {
|
||||
struct usb_device *udev;
|
||||
struct usb_interface *intf;
|
||||
struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES];
|
||||
const struct kvaser_usb_dev_ops *ops;
|
||||
const struct kvaser_usb_dev_cfg *cfg;
|
||||
|
||||
struct usb_endpoint_descriptor *bulk_in, *bulk_out;
|
||||
struct usb_anchor rx_submitted;
|
||||
|
||||
/* @max_tx_urbs: Firmware-reported maximum number of outstanding,
|
||||
* not yet ACKed, transmissions on this device. This value is
|
||||
* also used as a sentinel for marking free tx contexts.
|
||||
*/
|
||||
u32 fw_version;
|
||||
unsigned int nchannels;
|
||||
unsigned int max_tx_urbs;
|
||||
struct kvaser_usb_dev_card_data card_data;
|
||||
|
||||
bool rxinitdone;
|
||||
void *rxbuf[KVASER_USB_MAX_RX_URBS];
|
||||
dma_addr_t rxbuf_dma[KVASER_USB_MAX_RX_URBS];
|
||||
};
|
||||
|
||||
struct kvaser_usb_net_priv {
|
||||
struct can_priv can;
|
||||
struct can_berr_counter bec;
|
||||
|
||||
struct kvaser_usb *dev;
|
||||
struct net_device *netdev;
|
||||
int channel;
|
||||
|
||||
struct completion start_comp, stop_comp, flush_comp;
|
||||
struct usb_anchor tx_submitted;
|
||||
|
||||
spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */
|
||||
int active_tx_contexts;
|
||||
struct kvaser_usb_tx_urb_context tx_contexts[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct kvaser_usb_dev_ops - Device specific functions
|
||||
* @dev_set_mode: used for can.do_set_mode
|
||||
* @dev_set_bittiming: used for can.do_set_bittiming
|
||||
* @dev_set_data_bittiming: used for can.do_set_data_bittiming
|
||||
* @dev_get_berr_counter: used for can.do_get_berr_counter
|
||||
*
|
||||
* @dev_setup_endpoints: setup USB in and out endpoints
|
||||
* @dev_init_card: initialize card
|
||||
* @dev_get_software_info: get software info
|
||||
* @dev_get_software_details: get software details
|
||||
* @dev_get_card_info: get card info
|
||||
* @dev_get_capabilities: discover device capabilities
|
||||
*
|
||||
* @dev_set_opt_mode: set ctrlmod
|
||||
* @dev_start_chip: start the CAN controller
|
||||
* @dev_stop_chip: stop the CAN controller
|
||||
* @dev_reset_chip: reset the CAN controller
|
||||
* @dev_flush_queue: flush outstanding CAN messages
|
||||
* @dev_read_bulk_callback: handle incoming commands
|
||||
* @dev_frame_to_cmd: translate struct can_frame into device command
|
||||
*/
|
||||
struct kvaser_usb_dev_ops {
|
||||
int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode);
|
||||
int (*dev_set_bittiming)(struct net_device *netdev);
|
||||
int (*dev_set_data_bittiming)(struct net_device *netdev);
|
||||
int (*dev_get_berr_counter)(const struct net_device *netdev,
|
||||
struct can_berr_counter *bec);
|
||||
int (*dev_setup_endpoints)(struct kvaser_usb *dev);
|
||||
int (*dev_init_card)(struct kvaser_usb *dev);
|
||||
int (*dev_get_software_info)(struct kvaser_usb *dev);
|
||||
int (*dev_get_software_details)(struct kvaser_usb *dev);
|
||||
int (*dev_get_card_info)(struct kvaser_usb *dev);
|
||||
int (*dev_get_capabilities)(struct kvaser_usb *dev);
|
||||
int (*dev_set_opt_mode)(const struct kvaser_usb_net_priv *priv);
|
||||
int (*dev_start_chip)(struct kvaser_usb_net_priv *priv);
|
||||
int (*dev_stop_chip)(struct kvaser_usb_net_priv *priv);
|
||||
int (*dev_reset_chip)(struct kvaser_usb *dev, int channel);
|
||||
int (*dev_flush_queue)(struct kvaser_usb_net_priv *priv);
|
||||
void (*dev_read_bulk_callback)(struct kvaser_usb *dev, void *buf,
|
||||
int len);
|
||||
void *(*dev_frame_to_cmd)(const struct kvaser_usb_net_priv *priv,
|
||||
const struct sk_buff *skb, int *frame_len,
|
||||
int *cmd_len, u16 transid);
|
||||
};
|
||||
|
||||
struct kvaser_usb_dev_cfg {
|
||||
const struct can_clock clock;
|
||||
const unsigned int timestamp_freq;
|
||||
const struct can_bittiming_const * const bittiming_const;
|
||||
const struct can_bittiming_const * const data_bittiming_const;
|
||||
};
|
||||
|
||||
extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops;
|
||||
extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops;
|
||||
|
||||
int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len,
|
||||
int *actual_len);
|
||||
|
||||
int kvaser_usb_send_cmd(const struct kvaser_usb *dev, void *cmd, int len);
|
||||
|
||||
int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd,
|
||||
int len);
|
||||
|
||||
int kvaser_usb_can_rx_over_error(struct net_device *netdev);
|
||||
#endif /* KVASER_USB_H */
|
||||
835
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
Normal file
835
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
Normal file
File diff suppressed because it is too large
Load Diff
2028
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
Normal file
2028
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
Normal file
File diff suppressed because it is too large
Load Diff
1358
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
Normal file
1358
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user