linux-can-next-for-5.11-20201120
-----BEGIN PGP SIGNATURE-----
iQFHBAABCgAxFiEEK3kIWJt9yTYMP3ehqclaivrt76kFAl+3q+gTHG1rbEBwZW5n
dXRyb25peC5kZQAKCRCpyVqK+u3vqYdjB/46Qv583QBIbM8YaXN+XTSfxSufp0Ku
G0R88mJKdOalgeiD58TaZ3hAegjOW44nCMmZP64mQB7XNvRiyNk8j69VDsRy+4Zy
r86Hi0TIlpeM5oNHb84SpvIO01elmuYNlaoU9t7NQV5YlKA2Lq+kcmMLGa7Z1zVk
IZ2KF2eF2V83p/4A5t1cgQV6LRlDBgAeoe/9pyG0mNX3Fv8lI3WIqjRkuevSm6iJ
XMEuc7kjUZ8Yd59Vvnipm89teD5lCyIpxeJ2hrOsiUlkwyosdCxewMeohJ596a2L
t5DoiT+3nJLOBQ/IKCYe5RoCf7sFZ8nfjqcNYeOm7Yw1CbXg9KwGZTU7
=BedD
-----END PGP SIGNATURE-----
Merge tag 'linux-can-next-for-5.11-20201120' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says:
====================
pull-request: can-next 2020-11-20
The first patch is by Yegor Yefremov and he improves the j1939 documentaton by
adding tables for the CAN identifier and its fields.
Then there are 8 patches by Oliver Hartkopp targeting the CAN driver
infrastructure and drivers. These add support for optional DLC element to the
Classical CAN frame structure. See patch ea7800565a
("can: add optional DLC
element to Classical CAN frame structure") for details. Oliver's last patch
adds len8_dlc support to several drivers. Stefan Mätje provides a patch to add
len8_dlc support to the esd_usb2 driver.
The next patch is by Oliver Hartkopp, too and adds support for modification of
Classical CAN DLCs to CAN GW sockets.
The next 3 patches target the nxp,flexcan DT bindings. One patch by my adds the
missing uint32 reference to the clock-frequency property. Joakim Zhang's
patches fix the fsl,clk-source property and add the IMX_SC_R_CAN() macro to the
imx firmware header file, which will be used in the flexcan driver later.
Another patch by Joakim Zhang prepares the flexcan driver for SCU based
stop-mode, by giving the existing, GPR based stop-mode, a _GPR postfix.
The next 5 patches are by me, target the flexcan driver, and clean up the
.ndo_open and .ndo_stop callbacks. These patches try to fix a sporadically
hanging flexcan_close() during simultanious ifdown, sending of CAN messages and
probably open CAN bus. I was never able to reproduce, but these seem to fix the
problem at the reporting user. As these changes are rather big, I'd like to
mainline them via net-next/master.
The next patches are by Jimmy Assarsson and Christer Beskow, they add support
for new USB devices to the existing kvaser_usb driver.
The last patch is by Kaixu Xia and simplifies the return in the
mcp251xfd_chip_softreset() function in the mcp251xfd driver.
* tag 'linux-can-next-for-5.11-20201120' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next: (25 commits)
can: mcp251xfd: remove useless code in mcp251xfd_chip_softreset
can: kvaser_usb: Add new Kvaser hydra devices
can: kvaser_usb: kvaser_usb_hydra: Add support for new device variant
can: kvaser_usb: Add new Kvaser Leaf v2 devices
can: kvaser_usb: Add USB_{LEAF,HYDRA}_PRODUCT_ID_END defines
can: flexcan: flexcan_close(): change order if commands to properly shut down the controller
can: flexcan: flexcan_open(): completely initialize controller before requesting IRQ
can: flexcan: flexcan_rx_offload_setup(): factor out mailbox and rx-offload setup into separate function
can: flexcan: move enabling/disabling of interrupts from flexcan_chip_{start,stop}() to callers
can: flexcan: factor out enabling and disabling of interrupts into separate function
can: flexcan: rename macro FLEXCAN_QUIRK_SETUP_STOP_MODE -> FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR
dt-bindings: firmware: add IMX_SC_R_CAN(x) macro for CAN
dt-bindings: can: fsl,flexcan: fix fsl,clk-source property
dt-bindings: can: fsl,flexcan: add uint32 reference to clock-frequency property
can: gw: support modification of Classical CAN DLCs
can: drivers: add len8_dlc support for esd_usb2 CAN adapter
can: drivers: add len8_dlc support for various CAN adapters
can: drivers: introduce helpers to access Classical CAN DLC values
can: update documentation for DLC usage in Classical CAN
can: rename CAN FD related can_len2dlc and can_dlc2len helpers
...
====================
Link: https://lore.kernel.org/r/20201120133318.3428231-1-mkl@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Коммит
5e08723967
|
@ -57,6 +57,7 @@ properties:
|
|||
- const: per
|
||||
|
||||
clock-frequency:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
The oscillator frequency driving the flexcan device, filled in by the
|
||||
boot loader. This property should only be used the used operating system
|
||||
|
@ -99,7 +100,7 @@ properties:
|
|||
by default.
|
||||
0: clock source 0 (oscillator clock)
|
||||
1: clock source 1 (peripheral clock)
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
$ref: /schemas/types.yaml#/definitions/uint8
|
||||
default: 1
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
|
@ -124,7 +125,7 @@ examples:
|
|||
interrupts = <48 0x2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
clock-frequency = <200000000>;
|
||||
fsl,clk-source = <0>;
|
||||
fsl,clk-source = /bits/ 8 <0>;
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
|
|
@ -228,20 +228,36 @@ send(2), sendto(2), sendmsg(2) and the recv* counterpart operations
|
|||
on the socket as usual. There are also CAN specific socket options
|
||||
described below.
|
||||
|
||||
The basic CAN frame structure and the sockaddr structure are defined
|
||||
in include/linux/can.h:
|
||||
The Classical CAN frame structure (aka CAN 2.0B), the CAN FD frame structure
|
||||
and the sockaddr structure are defined in include/linux/can.h:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
struct can_frame {
|
||||
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
|
||||
__u8 can_dlc; /* frame payload length in byte (0 .. 8) */
|
||||
union {
|
||||
/* CAN frame payload length in byte (0 .. CAN_MAX_DLEN)
|
||||
* was previously named can_dlc so we need to carry that
|
||||
* name for legacy support
|
||||
*/
|
||||
__u8 len;
|
||||
__u8 can_dlc; /* deprecated */
|
||||
};
|
||||
__u8 __pad; /* padding */
|
||||
__u8 __res0; /* reserved / padding */
|
||||
__u8 __res1; /* reserved / padding */
|
||||
__u8 len8_dlc; /* optional DLC for 8 byte payload length (9 .. 15) */
|
||||
__u8 data[8] __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
Remark: The len element contains the payload length in bytes and should be
|
||||
used instead of can_dlc. The deprecated can_dlc was misleadingly named as
|
||||
it always contained the plain payload length in bytes and not the so called
|
||||
'data length code' (DLC).
|
||||
|
||||
To pass the raw DLC from/to a Classical CAN network device the len8_dlc
|
||||
element can contain values 9 .. 15 when the len element is 8 (the real
|
||||
payload length for all DLC values greater or equal to 8).
|
||||
|
||||
The alignment of the (linear) payload data[] to a 64bit boundary
|
||||
allows the user to define their own structs and unions to easily access
|
||||
the CAN payload. There is no given byteorder on the CAN bus by
|
||||
|
@ -260,6 +276,23 @@ PF_PACKET socket, that also binds to a specific interface:
|
|||
/* transport protocol class address info (e.g. ISOTP) */
|
||||
struct { canid_t rx_id, tx_id; } tp;
|
||||
|
||||
/* J1939 address information */
|
||||
struct {
|
||||
/* 8 byte name when using dynamic addressing */
|
||||
__u64 name;
|
||||
|
||||
/* pgn:
|
||||
* 8 bit: PS in PDU2 case, else 0
|
||||
* 8 bit: PF
|
||||
* 1 bit: DP
|
||||
* 1 bit: reserved
|
||||
*/
|
||||
__u32 pgn;
|
||||
|
||||
/* 1 byte address */
|
||||
__u8 addr;
|
||||
} j1939;
|
||||
|
||||
/* reserved for future CAN protocols address information */
|
||||
} can_addr;
|
||||
};
|
||||
|
@ -371,7 +404,7 @@ kernel interfaces (ABI) which heavily rely on the CAN frame with fixed eight
|
|||
bytes of payload (struct can_frame) like the CAN_RAW socket. Therefore e.g.
|
||||
the CAN_RAW socket supports a new socket option CAN_RAW_FD_FRAMES that
|
||||
switches the socket into a mode that allows the handling of CAN FD frames
|
||||
and (legacy) CAN frames simultaneously (see :ref:`socketcan-rawfd`).
|
||||
and Classical CAN frames simultaneously (see :ref:`socketcan-rawfd`).
|
||||
|
||||
The struct canfd_frame is defined in include/linux/can.h:
|
||||
|
||||
|
@ -397,7 +430,7 @@ code (DLC) of the struct can_frame was used as a length information as the
|
|||
length and the DLC has a 1:1 mapping in the range of 0 .. 8. To preserve
|
||||
the easy handling of the length information the canfd_frame.len element
|
||||
contains a plain length value from 0 .. 64. So both canfd_frame.len and
|
||||
can_frame.can_dlc are equal and contain a length information and no DLC.
|
||||
can_frame.len are equal and contain a length information and no DLC.
|
||||
For details about the distinction of CAN and CAN FD capable devices and
|
||||
the mapping to the bus-relevant data length code (DLC), see :ref:`socketcan-can-fd-driver`.
|
||||
|
||||
|
@ -407,7 +440,7 @@ definitions are specified for CAN specific MTUs in include/linux/can.h:
|
|||
|
||||
.. code-block:: C
|
||||
|
||||
#define CAN_MTU (sizeof(struct can_frame)) == 16 => 'legacy' CAN frame
|
||||
#define CAN_MTU (sizeof(struct can_frame)) == 16 => Classical CAN frame
|
||||
#define CANFD_MTU (sizeof(struct canfd_frame)) == 72 => CAN FD frame
|
||||
|
||||
|
||||
|
@ -609,7 +642,7 @@ Example:
|
|||
printf("got CAN FD frame with length %d\n", cfd.len);
|
||||
/* cfd.flags contains valid data */
|
||||
} else if (nbytes == CAN_MTU) {
|
||||
printf("got legacy CAN frame with length %d\n", cfd.len);
|
||||
printf("got Classical CAN frame with length %d\n", cfd.len);
|
||||
/* cfd.flags is undefined */
|
||||
} else {
|
||||
fprintf(stderr, "read: invalid CAN(FD) frame\n");
|
||||
|
@ -623,7 +656,7 @@ Example:
|
|||
printf("%02X ", cfd.data[i]);
|
||||
|
||||
When reading with size CANFD_MTU only returns CAN_MTU bytes that have
|
||||
been received from the socket a legacy CAN frame has been read into the
|
||||
been received from the socket a Classical CAN frame has been read into the
|
||||
provided CAN FD structure. Note that the canfd_frame.flags data field is
|
||||
not specified in the struct can_frame and therefore it is only valid in
|
||||
CANFD_MTU sized CAN FD frames.
|
||||
|
@ -633,7 +666,7 @@ Implementation hint for new CAN applications:
|
|||
To build a CAN FD aware application use struct canfd_frame as basic CAN
|
||||
data structure for CAN_RAW based applications. When the application is
|
||||
executed on an older Linux kernel and switching the CAN_RAW_FD_FRAMES
|
||||
socket option returns an error: No problem. You'll get legacy CAN frames
|
||||
socket option returns an error: No problem. You'll get Classical CAN frames
|
||||
or CAN FD frames and can process them the same way.
|
||||
|
||||
When sending to CAN devices make sure that the device is capable to handle
|
||||
|
@ -842,6 +875,8 @@ TX_RESET_MULTI_IDX:
|
|||
RX_RTR_FRAME:
|
||||
Send reply for RTR-request (placed in op->frames[0]).
|
||||
|
||||
CAN_FD_FRAME:
|
||||
The CAN frames following the bcm_msg_head are struct canfd_frame's
|
||||
|
||||
Broadcast Manager Transmission Timers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -1026,7 +1061,7 @@ Additional procfs files in /proc/net/can::
|
|||
|
||||
stats - SocketCAN core statistics (rx/tx frames, match ratios, ...)
|
||||
reset_stats - manual statistic reset
|
||||
version - prints the SocketCAN core version and the ABI version
|
||||
version - prints SocketCAN core and ABI version (removed in Linux 5.10)
|
||||
|
||||
|
||||
Writing Own CAN Protocol Modules
|
||||
|
@ -1070,7 +1105,7 @@ General Settings
|
|||
dev->type = ARPHRD_CAN; /* the netdevice hardware type */
|
||||
dev->flags = IFF_NOARP; /* CAN has no arp */
|
||||
|
||||
dev->mtu = CAN_MTU; /* sizeof(struct can_frame) -> legacy CAN interface */
|
||||
dev->mtu = CAN_MTU; /* sizeof(struct can_frame) -> Classical CAN interface */
|
||||
|
||||
or alternative, when the controller supports CAN with flexible data rate:
|
||||
dev->mtu = CANFD_MTU; /* sizeof(struct canfd_frame) -> CAN FD interface */
|
||||
|
@ -1184,6 +1219,7 @@ Setting CAN device properties::
|
|||
[ fd { on | off } ]
|
||||
[ fd-non-iso { on | off } ]
|
||||
[ presume-ack { on | off } ]
|
||||
[ cc-len8-dlc { on | off } ]
|
||||
|
||||
[ restart-ms TIME-MS ]
|
||||
[ restart ]
|
||||
|
@ -1326,22 +1362,22 @@ arbitration phase and the payload phase of the CAN FD frame. Therefore a
|
|||
second bit timing has to be specified in order to enable the CAN FD bitrate.
|
||||
|
||||
Additionally CAN FD capable CAN controllers support up to 64 bytes of
|
||||
payload. The representation of this length in can_frame.can_dlc and
|
||||
payload. The representation of this length in can_frame.len and
|
||||
canfd_frame.len for userspace applications and inside the Linux network
|
||||
layer is a plain value from 0 .. 64 instead of the CAN 'data length code'.
|
||||
The data length code was a 1:1 mapping to the payload length in the legacy
|
||||
The data length code was a 1:1 mapping to the payload length in the Classical
|
||||
CAN frames anyway. The payload length to the bus-relevant DLC mapping is
|
||||
only performed inside the CAN drivers, preferably with the helper
|
||||
functions can_dlc2len() and can_len2dlc().
|
||||
functions can_fd_dlc2len() and can_fd_len2dlc().
|
||||
|
||||
The CAN netdevice driver capabilities can be distinguished by the network
|
||||
devices maximum transfer unit (MTU)::
|
||||
|
||||
MTU = 16 (CAN_MTU) => sizeof(struct can_frame) => 'legacy' CAN device
|
||||
MTU = 16 (CAN_MTU) => sizeof(struct can_frame) => Classical CAN device
|
||||
MTU = 72 (CANFD_MTU) => sizeof(struct canfd_frame) => CAN FD capable device
|
||||
|
||||
The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall.
|
||||
N.B. CAN FD capable devices can also handle and send legacy CAN frames.
|
||||
N.B. CAN FD capable devices can also handle and send Classical CAN frames.
|
||||
|
||||
When configuring CAN FD capable CAN controllers an additional 'data' bitrate
|
||||
has to be set. This bitrate for the data phase of the CAN FD frame has to be
|
||||
|
|
|
@ -69,18 +69,56 @@ J1939 concepts
|
|||
PGN
|
||||
---
|
||||
|
||||
The J1939 protocol uses the 29-bit CAN identifier with the following structure:
|
||||
|
||||
============ ============== ====================
|
||||
29 bit CAN-ID
|
||||
--------------------------------------------------
|
||||
Bit positions within the CAN-ID
|
||||
--------------------------------------------------
|
||||
28 ... 26 25 ... 8 7 ... 0
|
||||
============ ============== ====================
|
||||
Priority PGN SA (Source Address)
|
||||
============ ============== ====================
|
||||
|
||||
The PGN (Parameter Group Number) is a number to identify a packet. The PGN
|
||||
is composed as follows:
|
||||
1 bit : Reserved Bit
|
||||
1 bit : Data Page
|
||||
8 bits : PF (PDU Format)
|
||||
8 bits : PS (PDU Specific)
|
||||
|
||||
============ ============== ================= =================
|
||||
PGN
|
||||
------------------------------------------------------------------
|
||||
Bit positions within the CAN-ID
|
||||
------------------------------------------------------------------
|
||||
25 24 23 ... 16 15 ... 8
|
||||
============ ============== ================= =================
|
||||
R (Reserved) DP (Data Page) PF (PDU Format) PS (PDU Specific)
|
||||
============ ============== ================= =================
|
||||
|
||||
In J1939-21 distinction is made between PDU1 format (where PF < 240) and PDU2
|
||||
format (where PF >= 240). Furthermore, when using the PDU2 format, the PS-field
|
||||
contains a so-called Group Extension, which is part of the PGN. When using PDU2
|
||||
format, the Group Extension is set in the PS-field.
|
||||
|
||||
============== ========================
|
||||
PDU1 Format (specific) (peer to peer)
|
||||
----------------------------------------
|
||||
Bit positions within the CAN-ID
|
||||
----------------------------------------
|
||||
23 ... 16 15 ... 8
|
||||
============== ========================
|
||||
00h ... EFh DA (Destination address)
|
||||
============== ========================
|
||||
|
||||
============== ========================
|
||||
PDU2 Format (global) (broadcast)
|
||||
----------------------------------------
|
||||
Bit positions within the CAN-ID
|
||||
----------------------------------------
|
||||
23 ... 16 15 ... 8
|
||||
============== ========================
|
||||
F0h ... FFh GE (Group Extenstion)
|
||||
============== ========================
|
||||
|
||||
On the other hand, when using PDU1 format, the PS-field contains a so-called
|
||||
Destination Address, which is _not_ part of the PGN. When communicating a PGN
|
||||
from user space to kernel (or vice versa) and PDU2 format is used, the PS-field
|
||||
|
|
|
@ -468,7 +468,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
reg_mid = at91_can_id_to_reg_mid(cf->can_id);
|
||||
reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) |
|
||||
(cf->can_dlc << 16) | AT91_MCR_MTCR;
|
||||
(cf->len << 16) | AT91_MCR_MTCR;
|
||||
|
||||
/* disable MB while writing ID (see datasheet) */
|
||||
set_mb_mode(priv, mb, AT91_MB_MODE_DISABLED);
|
||||
|
@ -481,7 +481,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
/* This triggers transmission */
|
||||
at91_write(priv, AT91_MCR(mb), reg_mcr);
|
||||
|
||||
stats->tx_bytes += cf->can_dlc;
|
||||
stats->tx_bytes += cf->len;
|
||||
|
||||
/* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */
|
||||
can_put_echo_skb(skb, dev, mb - get_mb_tx_first(priv));
|
||||
|
@ -554,7 +554,7 @@ static void at91_rx_overflow_err(struct net_device *dev)
|
|||
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
|
||||
|
@ -580,7 +580,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb,
|
|||
cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK;
|
||||
|
||||
reg_msr = at91_read(priv, AT91_MSR(mb));
|
||||
cf->can_dlc = get_can_dlc((reg_msr >> 16) & 0xf);
|
||||
cf->len = can_cc_dlc2len((reg_msr >> 16) & 0xf);
|
||||
|
||||
if (reg_msr & AT91_MSR_MRTR)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
|
@ -619,7 +619,7 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb)
|
|||
at91_read_mb(dev, mb, cf);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
can_led_event(dev, CAN_LED_EVENT_RX);
|
||||
|
@ -780,7 +780,7 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
|
|||
at91_poll_err_frame(dev, cf, reg_sr);
|
||||
|
||||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += cf->can_dlc;
|
||||
dev->stats.rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
return 1;
|
||||
|
@ -1047,7 +1047,7 @@ static void at91_irq_err(struct net_device *dev)
|
|||
at91_irq_err_state(dev, cf, new_state);
|
||||
|
||||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += cf->can_dlc;
|
||||
dev->stats.rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
priv->can.state = new_state;
|
||||
|
|
|
@ -306,7 +306,7 @@ static void c_can_setup_tx_object(struct net_device *dev, int iface,
|
|||
struct can_frame *frame, int idx)
|
||||
{
|
||||
struct c_can_priv *priv = netdev_priv(dev);
|
||||
u16 ctrl = IF_MCONT_TX | frame->can_dlc;
|
||||
u16 ctrl = IF_MCONT_TX | frame->len;
|
||||
bool rtr = frame->can_id & CAN_RTR_FLAG;
|
||||
u32 arb = IF_ARB_MSGVAL;
|
||||
int i;
|
||||
|
@ -339,7 +339,7 @@ static void c_can_setup_tx_object(struct net_device *dev, int iface,
|
|||
if (priv->type == BOSCH_D_CAN) {
|
||||
u32 data = 0, dreg = C_CAN_IFACE(DATA1_REG, iface);
|
||||
|
||||
for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
|
||||
for (i = 0; i < frame->len; i += 4, dreg += 2) {
|
||||
data = (u32)frame->data[i];
|
||||
data |= (u32)frame->data[i + 1] << 8;
|
||||
data |= (u32)frame->data[i + 2] << 16;
|
||||
|
@ -347,7 +347,7 @@ static void c_can_setup_tx_object(struct net_device *dev, int iface,
|
|||
priv->write_reg32(priv, dreg, data);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < frame->can_dlc; i += 2) {
|
||||
for (i = 0; i < frame->len; i += 2) {
|
||||
priv->write_reg(priv,
|
||||
C_CAN_IFACE(DATA1_REG, iface) + i / 2,
|
||||
frame->data[i] |
|
||||
|
@ -397,7 +397,7 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frame->can_dlc = get_can_dlc(ctrl & 0x0F);
|
||||
frame->len = can_cc_dlc2len(ctrl & 0x0F);
|
||||
|
||||
arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
|
||||
|
||||
|
@ -412,7 +412,7 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
|
|||
int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
|
||||
|
||||
if (priv->type == BOSCH_D_CAN) {
|
||||
for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
|
||||
for (i = 0; i < frame->len; i += 4, dreg += 2) {
|
||||
data = priv->read_reg32(priv, dreg);
|
||||
frame->data[i] = data;
|
||||
frame->data[i + 1] = data >> 8;
|
||||
|
@ -420,7 +420,7 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
|
|||
frame->data[i + 3] = data >> 24;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < frame->can_dlc; i += 2, dreg++) {
|
||||
for (i = 0; i < frame->len; i += 2, dreg++) {
|
||||
data = priv->read_reg(priv, dreg);
|
||||
frame->data[i] = data;
|
||||
frame->data[i + 1] = data >> 8;
|
||||
|
@ -429,7 +429,7 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += frame->can_dlc;
|
||||
stats->rx_bytes += frame->len;
|
||||
|
||||
netif_receive_skb(skb);
|
||||
return 0;
|
||||
|
@ -475,7 +475,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
|
|||
* transmit as we might race against do_tx().
|
||||
*/
|
||||
c_can_setup_tx_object(dev, IF_TX, frame, idx);
|
||||
priv->dlc[idx] = frame->can_dlc;
|
||||
priv->dlc[idx] = frame->len;
|
||||
can_put_echo_skb(skb, dev, idx);
|
||||
|
||||
/* Update the active bits */
|
||||
|
@ -977,7 +977,7 @@ static int c_can_handle_state_change(struct net_device *dev,
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
return 1;
|
||||
|
@ -1047,7 +1047,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -390,7 +390,7 @@ static void cc770_tx(struct net_device *dev, int mo)
|
|||
u32 id;
|
||||
int i;
|
||||
|
||||
dlc = cf->can_dlc;
|
||||
dlc = cf->len;
|
||||
id = cf->can_id;
|
||||
rtr = cf->can_id & CAN_RTR_FLAG ? 0 : MSGCFG_DIR;
|
||||
|
||||
|
@ -470,7 +470,7 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
|
|||
cf->can_id = CAN_RTR_FLAG;
|
||||
if (config & MSGCFG_XTD)
|
||||
cf->can_id |= CAN_EFF_FLAG;
|
||||
cf->can_dlc = 0;
|
||||
cf->len = 0;
|
||||
} else {
|
||||
if (config & MSGCFG_XTD) {
|
||||
id = cc770_read_reg(priv, msgobj[mo].id[3]);
|
||||
|
@ -486,13 +486,13 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
|
|||
}
|
||||
|
||||
cf->can_id = id;
|
||||
cf->can_dlc = get_can_dlc((config & 0xf0) >> 4);
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
cf->len = can_cc_dlc2len((config & 0xf0) >> 4);
|
||||
for (i = 0; i < cf->len; i++)
|
||||
cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]);
|
||||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -572,7 +572,7 @@ static int cc770_err(struct net_device *dev, u8 status)
|
|||
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
return 0;
|
||||
|
@ -699,7 +699,7 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
|
|||
}
|
||||
|
||||
cf = (struct can_frame *)priv->tx_skb->data;
|
||||
stats->tx_bytes += cf->can_dlc;
|
||||
stats->tx_bytes += cf->len;
|
||||
stats->tx_packets++;
|
||||
|
||||
can_put_echo_skb(priv->tx_skb, dev, 0);
|
||||
|
|
|
@ -30,12 +30,12 @@ MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
|
|||
static const u8 dlc2len[] = {0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 12, 16, 20, 24, 32, 48, 64};
|
||||
|
||||
/* get data length from can_dlc with sanitized can_dlc */
|
||||
u8 can_dlc2len(u8 can_dlc)
|
||||
/* get data length from raw data length code (DLC) */
|
||||
u8 can_fd_dlc2len(u8 dlc)
|
||||
{
|
||||
return dlc2len[can_dlc & 0x0F];
|
||||
return dlc2len[dlc & 0x0F];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(can_dlc2len);
|
||||
EXPORT_SYMBOL_GPL(can_fd_dlc2len);
|
||||
|
||||
static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, /* 0 - 8 */
|
||||
9, 9, 9, 9, /* 9 - 12 */
|
||||
|
@ -49,14 +49,14 @@ static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, /* 0 - 8 */
|
|||
15, 15, 15, 15, 15, 15, 15, 15}; /* 57 - 64 */
|
||||
|
||||
/* map the sanitized data length to an appropriate data length code */
|
||||
u8 can_len2dlc(u8 len)
|
||||
u8 can_fd_len2dlc(u8 len)
|
||||
{
|
||||
if (unlikely(len > 64))
|
||||
return 0xF;
|
||||
|
||||
return len2dlc[len];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(can_len2dlc);
|
||||
EXPORT_SYMBOL_GPL(can_fd_len2dlc);
|
||||
|
||||
#ifdef CONFIG_CAN_CALC_BITTIMING
|
||||
#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
|
||||
|
@ -595,7 +595,7 @@ static void can_restart(struct net_device *dev)
|
|||
netif_rx_ni(skb);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
|
||||
restart:
|
||||
netdev_dbg(dev, "restarted\n");
|
||||
|
@ -737,7 +737,7 @@ struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
|
|||
return NULL;
|
||||
|
||||
(*cf)->can_id = CAN_ERR_FLAG;
|
||||
(*cf)->can_dlc = CAN_ERR_DLC;
|
||||
(*cf)->len = CAN_ERR_DLC;
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
|
|
@ -236,8 +236,8 @@
|
|||
#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6)
|
||||
/* default to BE register access */
|
||||
#define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7)
|
||||
/* Setup stop mode to support wakeup */
|
||||
#define FLEXCAN_QUIRK_SETUP_STOP_MODE BIT(8)
|
||||
/* Setup stop mode with GPR to support wakeup */
|
||||
#define FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR BIT(8)
|
||||
/* Support CAN-FD mode */
|
||||
#define FLEXCAN_QUIRK_SUPPORT_FD BIT(9)
|
||||
/* support memory detection and correction */
|
||||
|
@ -381,7 +381,7 @@ static const struct flexcan_devtype_data fsl_imx28_devtype_data = {
|
|||
static const struct flexcan_devtype_data fsl_imx6q_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
|
||||
FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE |
|
||||
FLEXCAN_QUIRK_SETUP_STOP_MODE,
|
||||
FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR,
|
||||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_imx8qm_devtype_data = {
|
||||
|
@ -393,7 +393,7 @@ static const struct flexcan_devtype_data fsl_imx8qm_devtype_data = {
|
|||
static struct flexcan_devtype_data fsl_imx8mp_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
|
||||
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP |
|
||||
FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE |
|
||||
FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR |
|
||||
FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC,
|
||||
};
|
||||
|
||||
|
@ -746,7 +746,7 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de
|
|||
struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
|
||||
u32 can_id;
|
||||
u32 data;
|
||||
u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_len2dlc(cfd->len)) << 16);
|
||||
u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_fd_len2dlc(cfd->len)) << 16);
|
||||
int i;
|
||||
|
||||
if (can_dropped_invalid_skb(dev, skb))
|
||||
|
@ -1000,12 +1000,12 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
|
|||
cfd->can_id = (reg_id >> 18) & CAN_SFF_MASK;
|
||||
|
||||
if (reg_ctrl & FLEXCAN_MB_CNT_EDL) {
|
||||
cfd->len = can_dlc2len(get_canfd_dlc((reg_ctrl >> 16) & 0xf));
|
||||
cfd->len = can_fd_dlc2len((reg_ctrl >> 16) & 0xf);
|
||||
|
||||
if (reg_ctrl & FLEXCAN_MB_CNT_BRS)
|
||||
cfd->flags |= CANFD_BRS;
|
||||
} else {
|
||||
cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf);
|
||||
cfd->len = can_cc_dlc2len((reg_ctrl >> 16) & 0xf);
|
||||
|
||||
if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
|
||||
cfd->can_id |= CAN_RTR_FLAG;
|
||||
|
@ -1346,6 +1346,72 @@ static void flexcan_ram_init(struct net_device *dev)
|
|||
priv->write(reg_ctrl2, ®s->ctrl2);
|
||||
}
|
||||
|
||||
static int flexcan_rx_offload_setup(struct net_device *dev)
|
||||
{
|
||||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
|
||||
priv->mb_size = sizeof(struct flexcan_mb) + CANFD_MAX_DLEN;
|
||||
else
|
||||
priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN;
|
||||
priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) +
|
||||
(sizeof(priv->regs->mb[1]) / priv->mb_size);
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
|
||||
priv->tx_mb_reserved =
|
||||
flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP);
|
||||
else
|
||||
priv->tx_mb_reserved =
|
||||
flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO);
|
||||
priv->tx_mb_idx = priv->mb_count - 1;
|
||||
priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx);
|
||||
priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
|
||||
|
||||
priv->offload.mailbox_read = flexcan_mailbox_read;
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
|
||||
priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST;
|
||||
priv->offload.mb_last = priv->mb_count - 2;
|
||||
|
||||
priv->rx_mask = GENMASK_ULL(priv->offload.mb_last,
|
||||
priv->offload.mb_first);
|
||||
err = can_rx_offload_add_timestamp(dev, &priv->offload);
|
||||
} else {
|
||||
priv->rx_mask = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
|
||||
FLEXCAN_IFLAG_RX_FIFO_AVAILABLE;
|
||||
err = can_rx_offload_add_fifo(dev, &priv->offload,
|
||||
FLEXCAN_NAPI_WEIGHT);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void flexcan_chip_interrupts_enable(const struct net_device *dev)
|
||||
{
|
||||
const struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
u64 reg_imask;
|
||||
|
||||
disable_irq(dev->irq);
|
||||
priv->write(priv->reg_ctrl_default, ®s->ctrl);
|
||||
reg_imask = priv->rx_mask | priv->tx_mask;
|
||||
priv->write(upper_32_bits(reg_imask), ®s->imask2);
|
||||
priv->write(lower_32_bits(reg_imask), ®s->imask1);
|
||||
enable_irq(dev->irq);
|
||||
}
|
||||
|
||||
static void flexcan_chip_interrupts_disable(const struct net_device *dev)
|
||||
{
|
||||
const struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
|
||||
priv->write(0, ®s->imask2);
|
||||
priv->write(0, ®s->imask1);
|
||||
priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
|
||||
®s->ctrl);
|
||||
}
|
||||
|
||||
/* flexcan_chip_start
|
||||
*
|
||||
* this functions is entered with clocks enabled
|
||||
|
@ -1356,7 +1422,6 @@ static int flexcan_chip_start(struct net_device *dev)
|
|||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr;
|
||||
u64 reg_imask;
|
||||
int err, i;
|
||||
struct flexcan_mb __iomem *mb;
|
||||
|
||||
|
@ -1574,14 +1639,6 @@ static int flexcan_chip_start(struct net_device *dev)
|
|||
|
||||
priv->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
|
||||
/* enable interrupts atomically */
|
||||
disable_irq(dev->irq);
|
||||
priv->write(priv->reg_ctrl_default, ®s->ctrl);
|
||||
reg_imask = priv->rx_mask | priv->tx_mask;
|
||||
priv->write(upper_32_bits(reg_imask), ®s->imask2);
|
||||
priv->write(lower_32_bits(reg_imask), ®s->imask1);
|
||||
enable_irq(dev->irq);
|
||||
|
||||
/* print chip status */
|
||||
netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
|
||||
priv->read(®s->mcr), priv->read(®s->ctrl));
|
||||
|
@ -1600,7 +1657,6 @@ static int flexcan_chip_start(struct net_device *dev)
|
|||
static int __flexcan_chip_stop(struct net_device *dev, bool disable_on_error)
|
||||
{
|
||||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
int err;
|
||||
|
||||
/* freeze + disable module */
|
||||
|
@ -1611,12 +1667,6 @@ static int __flexcan_chip_stop(struct net_device *dev, bool disable_on_error)
|
|||
if (err && !disable_on_error)
|
||||
goto out_chip_unfreeze;
|
||||
|
||||
/* Disable all interrupts */
|
||||
priv->write(0, ®s->imask2);
|
||||
priv->write(0, ®s->imask1);
|
||||
priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
|
||||
®s->ctrl);
|
||||
|
||||
priv->can.state = CAN_STATE_STOPPED;
|
||||
|
||||
return 0;
|
||||
|
@ -1662,61 +1712,33 @@ static int flexcan_open(struct net_device *dev)
|
|||
if (err)
|
||||
goto out_close;
|
||||
|
||||
err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev);
|
||||
err = flexcan_rx_offload_setup(dev);
|
||||
if (err)
|
||||
goto out_transceiver_disable;
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
|
||||
priv->mb_size = sizeof(struct flexcan_mb) + CANFD_MAX_DLEN;
|
||||
else
|
||||
priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN;
|
||||
priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) +
|
||||
(sizeof(priv->regs->mb[1]) / priv->mb_size);
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
|
||||
priv->tx_mb_reserved =
|
||||
flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP);
|
||||
else
|
||||
priv->tx_mb_reserved =
|
||||
flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO);
|
||||
priv->tx_mb_idx = priv->mb_count - 1;
|
||||
priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx);
|
||||
priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
|
||||
|
||||
priv->offload.mailbox_read = flexcan_mailbox_read;
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
|
||||
priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST;
|
||||
priv->offload.mb_last = priv->mb_count - 2;
|
||||
|
||||
priv->rx_mask = GENMASK_ULL(priv->offload.mb_last,
|
||||
priv->offload.mb_first);
|
||||
err = can_rx_offload_add_timestamp(dev, &priv->offload);
|
||||
} else {
|
||||
priv->rx_mask = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
|
||||
FLEXCAN_IFLAG_RX_FIFO_AVAILABLE;
|
||||
err = can_rx_offload_add_fifo(dev, &priv->offload,
|
||||
FLEXCAN_NAPI_WEIGHT);
|
||||
}
|
||||
if (err)
|
||||
goto out_free_irq;
|
||||
|
||||
/* start chip and queuing */
|
||||
err = flexcan_chip_start(dev);
|
||||
if (err)
|
||||
goto out_offload_del;
|
||||
goto out_can_rx_offload_del;
|
||||
|
||||
can_rx_offload_enable(&priv->offload);
|
||||
|
||||
err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev);
|
||||
if (err)
|
||||
goto out_can_rx_offload_disable;
|
||||
|
||||
flexcan_chip_interrupts_enable(dev);
|
||||
|
||||
can_led_event(dev, CAN_LED_EVENT_OPEN);
|
||||
|
||||
can_rx_offload_enable(&priv->offload);
|
||||
netif_start_queue(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
out_offload_del:
|
||||
out_can_rx_offload_disable:
|
||||
can_rx_offload_disable(&priv->offload);
|
||||
flexcan_chip_stop(dev);
|
||||
out_can_rx_offload_del:
|
||||
can_rx_offload_del(&priv->offload);
|
||||
out_free_irq:
|
||||
free_irq(dev->irq, dev);
|
||||
out_transceiver_disable:
|
||||
flexcan_transceiver_disable(priv);
|
||||
out_close:
|
||||
|
@ -1732,14 +1754,15 @@ static int flexcan_close(struct net_device *dev)
|
|||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
flexcan_chip_interrupts_disable(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
can_rx_offload_disable(&priv->offload);
|
||||
flexcan_chip_stop_disable_on_error(dev);
|
||||
|
||||
can_rx_offload_del(&priv->offload);
|
||||
free_irq(dev->irq, dev);
|
||||
flexcan_transceiver_disable(priv);
|
||||
|
||||
close_candev(dev);
|
||||
|
||||
pm_runtime_put(priv->dev);
|
||||
|
||||
can_led_event(dev, CAN_LED_EVENT_STOP);
|
||||
|
@ -1757,6 +1780,8 @@ static int flexcan_set_mode(struct net_device *dev, enum can_mode mode)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
flexcan_chip_interrupts_enable(dev);
|
||||
|
||||
netif_wake_queue(dev);
|
||||
break;
|
||||
|
||||
|
@ -2047,7 +2072,7 @@ static int flexcan_probe(struct platform_device *pdev)
|
|||
of_can_transceiver(dev);
|
||||
devm_can_led_init(dev);
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE) {
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) {
|
||||
err = flexcan_setup_stop_mode(pdev);
|
||||
if (err)
|
||||
dev_dbg(&pdev->dev, "failed to setup stop-mode\n");
|
||||
|
@ -2095,6 +2120,8 @@ static int __maybe_unused flexcan_suspend(struct device *device)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
flexcan_chip_interrupts_disable(dev);
|
||||
|
||||
err = pinctrl_pm_select_sleep_state(device);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -2130,6 +2157,8 @@ static int __maybe_unused flexcan_resume(struct device *device)
|
|||
err = flexcan_chip_start(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
flexcan_chip_interrupts_enable(dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1201,12 +1201,12 @@ static int grcan_receive(struct net_device *dev, int budget)
|
|||
cf->can_id = ((slot[0] & GRCAN_MSG_BID)
|
||||
>> GRCAN_MSG_BID_BIT);
|
||||
}
|
||||
cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
|
||||
cf->len = can_cc_dlc2len((slot[1] & GRCAN_MSG_DLC)
|
||||
>> GRCAN_MSG_DLC_BIT);
|
||||
if (rtr) {
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
} else {
|
||||
for (i = 0; i < cf->can_dlc; i++) {
|
||||
for (i = 0; i < cf->len; i++) {
|
||||
j = GRCAN_MSG_DATA_SLOT_INDEX(i);
|
||||
shift = GRCAN_MSG_DATA_SHIFT(i);
|
||||
cf->data[i] = (u8)(slot[j] >> shift);
|
||||
|
@ -1215,7 +1215,7 @@ static int grcan_receive(struct net_device *dev, int budget)
|
|||
|
||||
/* Update statistics and read pointer */
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
|
||||
|
@ -1399,7 +1399,7 @@ static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
|
|||
eff = cf->can_id & CAN_EFF_FLAG;
|
||||
rtr = cf->can_id & CAN_RTR_FLAG;
|
||||
id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
|
||||
dlc = cf->can_dlc;
|
||||
dlc = cf->len;
|
||||
if (eff)
|
||||
tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
|
||||
else
|
||||
|
@ -1447,7 +1447,7 @@ static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
|
|||
* can_put_echo_skb would be an error unless other measures are
|
||||
* taken.
|
||||
*/
|
||||
priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
|
||||
priv->txdlc[slotindex] = cf->len; /* Store dlc for statistics */
|
||||
can_put_echo_skb(skb, dev, slotindex);
|
||||
|
||||
/* Make sure everything is written before allowing hardware to
|
||||
|
|
|
@ -271,9 +271,9 @@ static void ifi_canfd_read_fifo(struct net_device *ndev)
|
|||
dlc = (rxdlc >> IFI_CANFD_RXFIFO_DLC_DLC_OFFSET) &
|
||||
IFI_CANFD_RXFIFO_DLC_DLC_MASK;
|
||||
if (rxdlc & IFI_CANFD_RXFIFO_DLC_EDL)
|
||||
cf->len = can_dlc2len(dlc);
|
||||
cf->len = can_fd_dlc2len(dlc);
|
||||
else
|
||||
cf->len = get_can_dlc(dlc);
|
||||
cf->len = can_cc_dlc2len(dlc);
|
||||
|
||||
rxid = readl(priv->base + IFI_CANFD_RXFIFO_ID);
|
||||
id = (rxid >> IFI_CANFD_RXFIFO_ID_ID_OFFSET);
|
||||
|
@ -431,7 +431,7 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
|
|||
writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
return 1;
|
||||
|
@ -523,7 +523,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
return 1;
|
||||
|
@ -900,7 +900,7 @@ static netdev_tx_t ifi_canfd_start_xmit(struct sk_buff *skb,
|
|||
txid = cf->can_id & CAN_SFF_MASK;
|
||||
}
|
||||
|
||||
txdlc = can_len2dlc(cf->len);
|
||||
txdlc = can_fd_len2dlc(cf->len);
|
||||
if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) {
|
||||
txdlc |= IFI_CANFD_TXFIFO_DLC_EDL;
|
||||
if (cf->flags & CANFD_BRS)
|
||||
|
|
|
@ -916,10 +916,10 @@ static void ican3_to_can_frame(struct ican3_dev *mod,
|
|||
|
||||
cf->can_id |= desc->data[0] << 3;
|
||||
cf->can_id |= (desc->data[1] & 0xe0) >> 5;
|
||||
cf->can_dlc = get_can_dlc(desc->data[1] & ICAN3_CAN_DLC_MASK);
|
||||
memcpy(cf->data, &desc->data[2], cf->can_dlc);
|
||||
cf->len = can_cc_dlc2len(desc->data[1] & ICAN3_CAN_DLC_MASK);
|
||||
memcpy(cf->data, &desc->data[2], cf->len);
|
||||
} else {
|
||||
cf->can_dlc = get_can_dlc(desc->data[0] & ICAN3_CAN_DLC_MASK);
|
||||
cf->len = can_cc_dlc2len(desc->data[0] & ICAN3_CAN_DLC_MASK);
|
||||
if (desc->data[0] & ICAN3_EFF_RTR)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
|
||||
|
@ -934,7 +934,7 @@ static void ican3_to_can_frame(struct ican3_dev *mod,
|
|||
cf->can_id |= desc->data[3] >> 5; /* 2-0 */
|
||||
}
|
||||
|
||||
memcpy(cf->data, &desc->data[6], cf->can_dlc);
|
||||
memcpy(cf->data, &desc->data[6], cf->len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -947,7 +947,7 @@ static void can_frame_to_ican3(struct ican3_dev *mod,
|
|||
|
||||
/* we always use the extended format, with the ECHO flag set */
|
||||
desc->command = ICAN3_CAN_TYPE_EFF;
|
||||
desc->data[0] |= cf->can_dlc;
|
||||
desc->data[0] |= cf->len;
|
||||
desc->data[1] |= ICAN3_ECHO;
|
||||
|
||||
/* support single transmission (no retries) mode */
|
||||
|
@ -970,7 +970,7 @@ static void can_frame_to_ican3(struct ican3_dev *mod,
|
|||
}
|
||||
|
||||
/* copy the data bits into the descriptor */
|
||||
memcpy(&desc->data[6], cf->data, cf->can_dlc);
|
||||
memcpy(&desc->data[6], cf->data, cf->len);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1294,7 +1294,7 @@ static unsigned int ican3_get_echo_skb(struct ican3_dev *mod)
|
|||
}
|
||||
|
||||
cf = (struct can_frame *)skb->data;
|
||||
dlc = cf->can_dlc;
|
||||
dlc = cf->len;
|
||||
|
||||
/* check flag whether this packet has to be looped back */
|
||||
if (skb->pkt_type != PACKET_LOOPBACK) {
|
||||
|
@ -1332,10 +1332,10 @@ static bool ican3_echo_skb_matches(struct ican3_dev *mod, struct sk_buff *skb)
|
|||
if (cf->can_id != echo_cf->can_id)
|
||||
return false;
|
||||
|
||||
if (cf->can_dlc != echo_cf->can_dlc)
|
||||
if (cf->len != echo_cf->len)
|
||||
return false;
|
||||
|
||||
return memcmp(cf->data, echo_cf->data, cf->can_dlc) == 0;
|
||||
return memcmp(cf->data, echo_cf->data, cf->len) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1421,7 +1421,7 @@ static int ican3_recv_skb(struct ican3_dev *mod)
|
|||
|
||||
/* update statistics, receive the skb */
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
err_noalloc:
|
||||
|
|
|
@ -740,7 +740,7 @@ static int kvaser_pciefd_prepare_tx_packet(struct kvaser_pciefd_tx_packet *p,
|
|||
p->header[0] |= KVASER_PCIEFD_RPACKET_IDE;
|
||||
|
||||
p->header[0] |= cf->can_id & CAN_EFF_MASK;
|
||||
p->header[1] |= can_len2dlc(cf->len) << KVASER_PCIEFD_RPACKET_DLC_SHIFT;
|
||||
p->header[1] |= can_fd_len2dlc(cf->len) << KVASER_PCIEFD_RPACKET_DLC_SHIFT;
|
||||
p->header[1] |= KVASER_PCIEFD_TPACKET_AREQ;
|
||||
|
||||
if (can_is_canfd_skb(skb)) {
|
||||
|
@ -1174,7 +1174,7 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,
|
|||
if (p->header[0] & KVASER_PCIEFD_RPACKET_IDE)
|
||||
cf->can_id |= CAN_EFF_FLAG;
|
||||
|
||||
cf->len = can_dlc2len(p->header[1] >> KVASER_PCIEFD_RPACKET_DLC_SHIFT);
|
||||
cf->len = can_fd_dlc2len(p->header[1] >> KVASER_PCIEFD_RPACKET_DLC_SHIFT);
|
||||
|
||||
if (p->header[0] & KVASER_PCIEFD_RPACKET_RTR)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
|
@ -1299,7 +1299,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
|
|||
cf->data[7] = bec.rxerr;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
|
||||
netif_rx(skb);
|
||||
return 0;
|
||||
|
@ -1498,7 +1498,7 @@ static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can,
|
|||
|
||||
if (skb) {
|
||||
cf->can_id |= CAN_ERR_BUSERROR;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
stats->rx_packets++;
|
||||
netif_rx(skb);
|
||||
} else {
|
||||
|
@ -1600,7 +1600,7 @@ static int kvaser_pciefd_read_packet(struct kvaser_pciefd *pcie, int *start_pos,
|
|||
if (!(p->header[0] & KVASER_PCIEFD_RPACKET_RTR)) {
|
||||
u8 data_len;
|
||||
|
||||
data_len = can_dlc2len(p->header[1] >>
|
||||
data_len = can_fd_dlc2len(p->header[1] >>
|
||||
KVASER_PCIEFD_RPACKET_DLC_SHIFT);
|
||||
pos += DIV_ROUND_UP(data_len, 4);
|
||||
}
|
||||
|
|
|
@ -457,9 +457,9 @@ static void m_can_read_fifo(struct net_device *dev, u32 rxfs)
|
|||
}
|
||||
|
||||
if (dlc & RX_BUF_FDF)
|
||||
cf->len = can_dlc2len((dlc >> 16) & 0x0F);
|
||||
cf->len = can_fd_dlc2len((dlc >> 16) & 0x0F);
|
||||
else
|
||||
cf->len = get_can_dlc((dlc >> 16) & 0x0F);
|
||||
cf->len = can_cc_dlc2len((dlc >> 16) & 0x0F);
|
||||
|
||||
id = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_ID);
|
||||
if (id & RX_BUF_XTD)
|
||||
|
@ -596,7 +596,7 @@ static int m_can_handle_lec_err(struct net_device *dev,
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
return 1;
|
||||
|
@ -723,7 +723,7 @@ static int m_can_handle_state_change(struct net_device *dev,
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
return 1;
|
||||
|
@ -1489,7 +1489,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev)
|
|||
/* message ram configuration */
|
||||
m_can_fifo_write(cdev, 0, M_CAN_FIFO_ID, id);
|
||||
m_can_fifo_write(cdev, 0, M_CAN_FIFO_DLC,
|
||||
can_len2dlc(cf->len) << 16);
|
||||
can_fd_len2dlc(cf->len) << 16);
|
||||
|
||||
for (i = 0; i < cf->len; i += 4)
|
||||
m_can_fifo_write(cdev, 0,
|
||||
|
@ -1557,7 +1557,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev)
|
|||
m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DLC,
|
||||
((putidx << TX_BUF_MM_SHIFT) &
|
||||
TX_BUF_MM_MASK) |
|
||||
(can_len2dlc(cf->len) << 16) |
|
||||
(can_fd_len2dlc(cf->len) << 16) |
|
||||
fdflags | TX_BUF_EFC);
|
||||
|
||||
for (i = 0; i < cf->len; i += 4)
|
||||
|
|
|
@ -250,16 +250,16 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
void __iomem *data = ®s->tx.dsr1_0;
|
||||
u16 *payload = (u16 *)frame->data;
|
||||
|
||||
for (i = 0; i < frame->can_dlc / 2; i++) {
|
||||
for (i = 0; i < frame->len / 2; i++) {
|
||||
out_be16(data, *payload++);
|
||||
data += 2 + _MSCAN_RESERVED_DSR_SIZE;
|
||||
}
|
||||
/* write remaining byte if necessary */
|
||||
if (frame->can_dlc & 1)
|
||||
out_8(data, frame->data[frame->can_dlc - 1]);
|
||||
if (frame->len & 1)
|
||||
out_8(data, frame->data[frame->len - 1]);
|
||||
}
|
||||
|
||||
out_8(®s->tx.dlr, frame->can_dlc);
|
||||
out_8(®s->tx.dlr, frame->len);
|
||||
out_8(®s->tx.tbpr, priv->cur_pri);
|
||||
|
||||
/* Start transmission. */
|
||||
|
@ -312,19 +312,19 @@ static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
|
|||
if (can_id & 1)
|
||||
frame->can_id |= CAN_RTR_FLAG;
|
||||
|
||||
frame->can_dlc = get_can_dlc(in_8(®s->rx.dlr) & 0xf);
|
||||
frame->len = can_cc_dlc2len(in_8(®s->rx.dlr) & 0xf);
|
||||
|
||||
if (!(frame->can_id & CAN_RTR_FLAG)) {
|
||||
void __iomem *data = ®s->rx.dsr1_0;
|
||||
u16 *payload = (u16 *)frame->data;
|
||||
|
||||
for (i = 0; i < frame->can_dlc / 2; i++) {
|
||||
for (i = 0; i < frame->len / 2; i++) {
|
||||
*payload++ = in_be16(data);
|
||||
data += 2 + _MSCAN_RESERVED_DSR_SIZE;
|
||||
}
|
||||
/* read remaining byte if necessary */
|
||||
if (frame->can_dlc & 1)
|
||||
frame->data[frame->can_dlc - 1] = in_8(data);
|
||||
if (frame->len & 1)
|
||||
frame->data[frame->len - 1] = in_8(data);
|
||||
}
|
||||
|
||||
out_8(®s->canrflg, MSCAN_RXF);
|
||||
|
@ -372,7 +372,7 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
|
|||
}
|
||||
}
|
||||
priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
|
||||
frame->can_dlc = CAN_ERR_DLC;
|
||||
frame->len = CAN_ERR_DLC;
|
||||
out_8(®s->canrflg, MSCAN_ERR_IF);
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota)
|
|||
mscan_get_err_frame(dev, frame, canrflg);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += frame->can_dlc;
|
||||
stats->rx_bytes += frame->len;
|
||||
work_done++;
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
|
|
|
@ -563,7 +563,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
|
|||
netif_receive_skb(skb);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
}
|
||||
|
||||
static irqreturn_t pch_can_interrupt(int irq, void *dev_id)
|
||||
|
@ -683,10 +683,10 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
|
|||
if (id2 & PCH_ID2_DIR)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
|
||||
cf->can_dlc = get_can_dlc((ioread32(&priv->regs->
|
||||
cf->len = can_cc_dlc2len((ioread32(&priv->regs->
|
||||
ifregs[0].mcont)) & 0xF);
|
||||
|
||||
for (i = 0; i < cf->can_dlc; i += 2) {
|
||||
for (i = 0; i < cf->len; i += 2) {
|
||||
data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]);
|
||||
cf->data[i] = data_reg;
|
||||
cf->data[i + 1] = data_reg >> 8;
|
||||
|
@ -696,7 +696,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
|
|||
rcv_pkts++;
|
||||
stats->rx_packets++;
|
||||
quota--;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
|
||||
pch_fifo_thresh(priv, obj_num);
|
||||
obj_num++;
|
||||
|
@ -715,7 +715,7 @@ static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat)
|
|||
iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND,
|
||||
&priv->regs->ifregs[1].cmask);
|
||||
pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, int_stat);
|
||||
dlc = get_can_dlc(ioread32(&priv->regs->ifregs[1].mcont) &
|
||||
dlc = can_cc_dlc2len(ioread32(&priv->regs->ifregs[1].mcont) &
|
||||
PCH_IF_MCONT_DLC);
|
||||
stats->tx_bytes += dlc;
|
||||
stats->tx_packets++;
|
||||
|
@ -919,7 +919,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||
iowrite32(id2, &priv->regs->ifregs[1].id2);
|
||||
|
||||
/* Copy data to register */
|
||||
for (i = 0; i < cf->can_dlc; i += 2) {
|
||||
for (i = 0; i < cf->len; i += 2) {
|
||||
iowrite16(cf->data[i] | (cf->data[i + 1] << 8),
|
||||
&priv->regs->ifregs[1].data[i / 2]);
|
||||
}
|
||||
|
@ -927,7 +927,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||
can_put_echo_skb(skb, ndev, tx_obj_no - PCH_RX_OBJ_END - 1);
|
||||
|
||||
/* Set the size of the data. Update if2_mcont */
|
||||
iowrite32(cf->can_dlc | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT |
|
||||
iowrite32(cf->len | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT |
|
||||
PCH_IF_MCONT_TXIE, &priv->regs->ifregs[1].mcont);
|
||||
|
||||
pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no);
|
||||
|
|
|
@ -257,9 +257,9 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,
|
|||
u8 cf_len;
|
||||
|
||||
if (rx_msg_flags & PUCAN_MSG_EXT_DATA_LEN)
|
||||
cf_len = can_dlc2len(get_canfd_dlc(pucan_msg_get_dlc(msg)));
|
||||
cf_len = can_fd_dlc2len(pucan_msg_get_dlc(msg));
|
||||
else
|
||||
cf_len = get_can_dlc(pucan_msg_get_dlc(msg));
|
||||
cf_len = can_cc_dlc2len(pucan_msg_get_dlc(msg));
|
||||
|
||||
/* if this frame is an echo, */
|
||||
if (rx_msg_flags & PUCAN_MSG_LOOPED_BACK) {
|
||||
|
@ -410,7 +410,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
pucan_netif_rx(skb, msg->ts_low, msg->ts_high);
|
||||
|
||||
return 0;
|
||||
|
@ -438,7 +438,7 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv)
|
|||
cf->data[6] = priv->bec.txerr;
|
||||
cf->data[7] = priv->bec.rxerr;
|
||||
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
stats->rx_packets++;
|
||||
netif_rx(skb);
|
||||
|
||||
|
@ -652,7 +652,7 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
|
|||
unsigned long flags;
|
||||
bool should_stop_tx_queue;
|
||||
int room_left;
|
||||
u8 can_dlc;
|
||||
u8 len;
|
||||
|
||||
if (can_dropped_invalid_skb(ndev, skb))
|
||||
return NETDEV_TX_OK;
|
||||
|
@ -682,7 +682,7 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
|
|||
|
||||
if (can_is_canfd_skb(skb)) {
|
||||
/* CAN FD frame format */
|
||||
can_dlc = can_len2dlc(cf->len);
|
||||
len = can_fd_len2dlc(cf->len);
|
||||
|
||||
msg_flags |= PUCAN_MSG_EXT_DATA_LEN;
|
||||
|
||||
|
@ -693,7 +693,7 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
|
|||
msg_flags |= PUCAN_MSG_ERROR_STATE_IND;
|
||||
} else {
|
||||
/* CAN 2.0 frame format */
|
||||
can_dlc = cf->len;
|
||||
len = cf->len;
|
||||
|
||||
if (cf->can_id & CAN_RTR_FLAG)
|
||||
msg_flags |= PUCAN_MSG_RTR;
|
||||
|
@ -707,7 +707,7 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
|
|||
msg_flags |= PUCAN_MSG_SELF_RECEIVE;
|
||||
|
||||
msg->flags = cpu_to_le16(msg_flags);
|
||||
msg->channel_dlc = PUCAN_MSG_CHANNEL_DLC(priv->index, can_dlc);
|
||||
msg->channel_dlc = PUCAN_MSG_CHANNEL_DLC(priv->index, len);
|
||||
memcpy(msg->d, cf->data, cf->len);
|
||||
|
||||
/* struct msg client field is used as an index in the echo skbs ring */
|
||||
|
|
|
@ -364,7 +364,7 @@ static void rcar_can_error(struct net_device *ndev)
|
|||
|
||||
if (skb) {
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
}
|
||||
|
@ -607,16 +607,16 @@ static netdev_tx_t rcar_can_start_xmit(struct sk_buff *skb,
|
|||
if (cf->can_id & CAN_RTR_FLAG) { /* Remote transmission request */
|
||||
data |= RCAR_CAN_RTR;
|
||||
} else {
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
writeb(cf->data[i],
|
||||
&priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].data[i]);
|
||||
}
|
||||
|
||||
writel(data, &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].id);
|
||||
|
||||
writeb(cf->can_dlc, &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].dlc);
|
||||
writeb(cf->len, &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].dlc);
|
||||
|
||||
priv->tx_dlc[priv->tx_head % RCAR_CAN_FIFO_DEPTH] = cf->can_dlc;
|
||||
priv->tx_dlc[priv->tx_head % RCAR_CAN_FIFO_DEPTH] = cf->len;
|
||||
can_put_echo_skb(skb, ndev, priv->tx_head % RCAR_CAN_FIFO_DEPTH);
|
||||
priv->tx_head++;
|
||||
/* Start Tx: write 0xff to the TFPCR register to increment
|
||||
|
@ -659,18 +659,18 @@ static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
|
|||
cf->can_id = (data >> RCAR_CAN_SID_SHIFT) & CAN_SFF_MASK;
|
||||
|
||||
dlc = readb(&priv->regs->mb[RCAR_CAN_RX_FIFO_MBX].dlc);
|
||||
cf->can_dlc = get_can_dlc(dlc);
|
||||
cf->len = can_cc_dlc2len(dlc);
|
||||
if (data & RCAR_CAN_RTR) {
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
} else {
|
||||
for (dlc = 0; dlc < cf->can_dlc; dlc++)
|
||||
for (dlc = 0; dlc < cf->len; dlc++)
|
||||
cf->data[dlc] =
|
||||
readb(&priv->regs->mb[RCAR_CAN_RX_FIFO_MBX].data[dlc]);
|
||||
}
|
||||
|
||||
can_led_event(priv->ndev, CAN_LED_EVENT_RX);
|
||||
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
stats->rx_packets++;
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
|
|
|
@ -1025,7 +1025,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
|
|||
rcar_canfd_write(priv->base, RCANFD_CERFL(ch),
|
||||
RCANFD_CERFL_ERR(~cerfl));
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -1134,7 +1134,7 @@ static void rcar_canfd_state_change(struct net_device *ndev,
|
|||
|
||||
can_change_state(ndev, cf, tx_state, rx_state);
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
}
|
||||
|
@ -1357,7 +1357,7 @@ static netdev_tx_t rcar_canfd_start_xmit(struct sk_buff *skb,
|
|||
if (cf->can_id & CAN_RTR_FLAG)
|
||||
id |= RCANFD_CFID_CFRTR;
|
||||
|
||||
dlc = RCANFD_CFPTR_CFDLC(can_len2dlc(cf->len));
|
||||
dlc = RCANFD_CFPTR_CFDLC(can_fd_len2dlc(cf->len));
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
|
||||
rcar_canfd_write(priv->base,
|
||||
|
@ -1446,9 +1446,9 @@ static void rcar_canfd_rx_pkt(struct rcar_canfd_channel *priv)
|
|||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
|
||||
if (sts & RCANFD_RFFDSTS_RFFDF)
|
||||
cf->len = can_dlc2len(RCANFD_RFPTR_RFDLC(dlc));
|
||||
cf->len = can_fd_dlc2len(RCANFD_RFPTR_RFDLC(dlc));
|
||||
else
|
||||
cf->len = get_can_dlc(RCANFD_RFPTR_RFDLC(dlc));
|
||||
cf->len = can_cc_dlc2len(RCANFD_RFPTR_RFDLC(dlc));
|
||||
|
||||
if (sts & RCANFD_RFFDSTS_RFESI) {
|
||||
cf->flags |= CANFD_ESI;
|
||||
|
@ -1464,7 +1464,7 @@ static void rcar_canfd_rx_pkt(struct rcar_canfd_channel *priv)
|
|||
rcar_canfd_get_data(priv, cf, RCANFD_F_RFDF(ridx, 0));
|
||||
}
|
||||
} else {
|
||||
cf->len = get_can_dlc(RCANFD_RFPTR_RFDLC(dlc));
|
||||
cf->len = can_cc_dlc2len(RCANFD_RFPTR_RFDLC(dlc));
|
||||
if (id & RCANFD_RFID_RFRTR)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
else
|
||||
|
|
|
@ -55,7 +55,7 @@ static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota)
|
|||
|
||||
work_done++;
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -284,7 +284,6 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
|
|||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||
uint8_t fi;
|
||||
uint8_t dlc;
|
||||
canid_t id;
|
||||
uint8_t dreg;
|
||||
u8 cmd_reg_val = 0x00;
|
||||
|
@ -295,7 +294,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
|
|||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
fi = dlc = cf->can_dlc;
|
||||
fi = can_get_cc_dlc(cf, priv->can.ctrlmode);
|
||||
id = cf->can_id;
|
||||
|
||||
if (id & CAN_RTR_FLAG)
|
||||
|
@ -316,7 +315,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
|
|||
priv->write_reg(priv, SJA1000_ID2, (id & 0x00000007) << 5);
|
||||
}
|
||||
|
||||
for (i = 0; i < dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
priv->write_reg(priv, dreg++, cf->data[i]);
|
||||
|
||||
can_put_echo_skb(skb, dev, 0);
|
||||
|
@ -367,11 +366,11 @@ static void sja1000_rx(struct net_device *dev)
|
|||
| (priv->read_reg(priv, SJA1000_ID2) >> 5);
|
||||
}
|
||||
|
||||
cf->can_dlc = get_can_dlc(fi & 0x0F);
|
||||
can_frame_set_cc_len(cf, fi & 0x0F, priv->can.ctrlmode);
|
||||
if (fi & SJA1000_FI_RTR) {
|
||||
id |= CAN_RTR_FLAG;
|
||||
} else {
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
cf->data[i] = priv->read_reg(priv, dreg++);
|
||||
}
|
||||
|
||||
|
@ -381,7 +380,7 @@ static void sja1000_rx(struct net_device *dev)
|
|||
sja1000_write_cmdreg(priv, CMD_RRB);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
can_led_event(dev, CAN_LED_EVENT_RX);
|
||||
|
@ -490,7 +489,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
return 0;
|
||||
|
@ -638,7 +637,8 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
|
|||
CAN_CTRLMODE_3_SAMPLES |
|
||||
CAN_CTRLMODE_ONE_SHOT |
|
||||
CAN_CTRLMODE_BERR_REPORTING |
|
||||
CAN_CTRLMODE_PRESUME_ACK;
|
||||
CAN_CTRLMODE_PRESUME_ACK |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC;
|
||||
|
||||
spin_lock_init(&priv->cmdreg_lock);
|
||||
|
||||
|
|
|
@ -106,8 +106,8 @@ static struct net_device **slcan_devs;
|
|||
|
||||
/*
|
||||
* A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
|
||||
* frame format) a data length code (can_dlc) which can be from 0 to 8
|
||||
* and up to <can_dlc> data bytes as payload.
|
||||
* frame format) a data length code (len) which can be from 0 to 8
|
||||
* and up to <len> data bytes as payload.
|
||||
* Additionally a CAN frame may become a remote transmission frame if the
|
||||
* RTR-bit is set. This causes another ECU to send a CAN frame with the
|
||||
* given can_id.
|
||||
|
@ -128,10 +128,10 @@ static struct net_device **slcan_devs;
|
|||
*
|
||||
* Examples:
|
||||
*
|
||||
* t1230 : can_id 0x123, can_dlc 0, no data
|
||||
* t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33
|
||||
* T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55
|
||||
* r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request
|
||||
* t1230 : can_id 0x123, len 0, no data
|
||||
* t4563112233 : can_id 0x456, len 3, data 0x11 0x22 0x33
|
||||
* T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, len 2, data 0xAA 0x55
|
||||
* r1230 : can_id 0x123, len 0, no data, remote transmission request
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -156,7 +156,7 @@ static void slc_bump(struct slcan *sl)
|
|||
fallthrough;
|
||||
case 't':
|
||||
/* store dlc ASCII value and terminate SFF CAN ID string */
|
||||
cf.can_dlc = sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN];
|
||||
cf.len = sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN];
|
||||
sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN] = 0;
|
||||
/* point to payload data behind the dlc */
|
||||
cmd += SLC_CMD_LEN + SLC_SFF_ID_LEN + 1;
|
||||
|
@ -167,7 +167,7 @@ static void slc_bump(struct slcan *sl)
|
|||
case 'T':
|
||||
cf.can_id |= CAN_EFF_FLAG;
|
||||
/* store dlc ASCII value and terminate EFF CAN ID string */
|
||||
cf.can_dlc = sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN];
|
||||
cf.len = sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN];
|
||||
sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN] = 0;
|
||||
/* point to payload data behind the dlc */
|
||||
cmd += SLC_CMD_LEN + SLC_EFF_ID_LEN + 1;
|
||||
|
@ -181,15 +181,15 @@ static void slc_bump(struct slcan *sl)
|
|||
|
||||
cf.can_id |= tmpid;
|
||||
|
||||
/* get can_dlc from sanitized ASCII value */
|
||||
if (cf.can_dlc >= '0' && cf.can_dlc < '9')
|
||||
cf.can_dlc -= '0';
|
||||
/* get len from sanitized ASCII value */
|
||||
if (cf.len >= '0' && cf.len < '9')
|
||||
cf.len -= '0';
|
||||
else
|
||||
return;
|
||||
|
||||
/* RTR frames may have a dlc > 0 but they never have any data bytes */
|
||||
if (!(cf.can_id & CAN_RTR_FLAG)) {
|
||||
for (i = 0; i < cf.can_dlc; i++) {
|
||||
for (i = 0; i < cf.len; i++) {
|
||||
tmp = hex_to_bin(*cmd++);
|
||||
if (tmp < 0)
|
||||
return;
|
||||
|
@ -218,7 +218,7 @@ static void slc_bump(struct slcan *sl)
|
|||
skb_put_data(skb, &cf, sizeof(struct can_frame));
|
||||
|
||||
sl->dev->stats.rx_packets++;
|
||||
sl->dev->stats.rx_bytes += cf.can_dlc;
|
||||
sl->dev->stats.rx_bytes += cf.len;
|
||||
netif_rx_ni(skb);
|
||||
}
|
||||
|
||||
|
@ -282,11 +282,11 @@ static void slc_encaps(struct slcan *sl, struct can_frame *cf)
|
|||
|
||||
pos += (cf->can_id & CAN_EFF_FLAG) ? SLC_EFF_ID_LEN : SLC_SFF_ID_LEN;
|
||||
|
||||
*pos++ = cf->can_dlc + '0';
|
||||
*pos++ = cf->len + '0';
|
||||
|
||||
/* RTR frames may have a dlc > 0 but they never have any data bytes */
|
||||
if (!(cf->can_id & CAN_RTR_FLAG)) {
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
pos = hex_byte_pack_upper(pos, cf->data[i]);
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,7 @@ static void slc_encaps(struct slcan *sl, struct can_frame *cf)
|
|||
actual = sl->tty->ops->write(sl->tty, sl->xbuff, pos - sl->xbuff);
|
||||
sl->xleft = (pos - sl->xbuff) - actual;
|
||||
sl->xhead = sl->xbuff + actual;
|
||||
sl->dev->stats.tx_bytes += cf->can_dlc;
|
||||
sl->dev->stats.tx_bytes += cf->len;
|
||||
}
|
||||
|
||||
/* Write out any remaining transmit buffer. Scheduled when tty is writable */
|
||||
|
|
|
@ -624,7 +624,7 @@ int softing_startstop(struct net_device *dev, int up)
|
|||
*/
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
|
||||
msg.can_dlc = CAN_ERR_DLC;
|
||||
msg.len = CAN_ERR_DLC;
|
||||
for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
|
||||
if (!(bus_bitmask_start & (1 << j)))
|
||||
continue;
|
||||
|
|
|
@ -84,7 +84,7 @@ static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb,
|
|||
if (priv->index)
|
||||
*ptr |= CMD_BUS2;
|
||||
++ptr;
|
||||
*ptr++ = cf->can_dlc;
|
||||
*ptr++ = cf->len;
|
||||
*ptr++ = (cf->can_id >> 0);
|
||||
*ptr++ = (cf->can_id >> 8);
|
||||
if (cf->can_id & CAN_EFF_FLAG) {
|
||||
|
@ -95,7 +95,7 @@ static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb,
|
|||
ptr += 1;
|
||||
}
|
||||
if (!(cf->can_id & CAN_RTR_FLAG))
|
||||
memcpy(ptr, &cf->data[0], cf->can_dlc);
|
||||
memcpy(ptr, &cf->data[0], cf->len);
|
||||
memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr],
|
||||
buf, DPRAM_TX_SIZE);
|
||||
if (++fifo_wr >= DPRAM_TX_CNT)
|
||||
|
@ -167,7 +167,7 @@ static int softing_handle_1(struct softing *card)
|
|||
iowrite8(0, &card->dpram[DPRAM_RX_LOST]);
|
||||
/* prepare msg */
|
||||
msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL;
|
||||
msg.can_dlc = CAN_ERR_DLC;
|
||||
msg.len = CAN_ERR_DLC;
|
||||
msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
|
||||
/*
|
||||
* service to all buses, we don't know which it was applicable
|
||||
|
@ -218,7 +218,7 @@ static int softing_handle_1(struct softing *card)
|
|||
state = *ptr++;
|
||||
|
||||
msg.can_id = CAN_ERR_FLAG;
|
||||
msg.can_dlc = CAN_ERR_DLC;
|
||||
msg.len = CAN_ERR_DLC;
|
||||
|
||||
if (state & SF_MASK_BUSOFF) {
|
||||
can_state = CAN_STATE_BUS_OFF;
|
||||
|
@ -261,7 +261,7 @@ static int softing_handle_1(struct softing *card)
|
|||
} else {
|
||||
if (cmd & CMD_RTR)
|
||||
msg.can_id |= CAN_RTR_FLAG;
|
||||
msg.can_dlc = get_can_dlc(*ptr++);
|
||||
msg.len = can_cc_dlc2len(*ptr++);
|
||||
if (cmd & CMD_XTD) {
|
||||
msg.can_id |= CAN_EFF_FLAG;
|
||||
msg.can_id |= le32_to_cpup((void *)ptr);
|
||||
|
@ -294,7 +294,7 @@ static int softing_handle_1(struct softing *card)
|
|||
--card->tx.pending;
|
||||
++netdev->stats.tx_packets;
|
||||
if (!(msg.can_id & CAN_RTR_FLAG))
|
||||
netdev->stats.tx_bytes += msg.can_dlc;
|
||||
netdev->stats.tx_bytes += msg.len;
|
||||
} else {
|
||||
int ret;
|
||||
|
||||
|
@ -302,7 +302,7 @@ static int softing_handle_1(struct softing *card)
|
|||
if (ret == NET_RX_SUCCESS) {
|
||||
++netdev->stats.rx_packets;
|
||||
if (!(msg.can_id & CAN_RTR_FLAG))
|
||||
netdev->stats.rx_bytes += msg.can_dlc;
|
||||
netdev->stats.rx_bytes += msg.len;
|
||||
} else {
|
||||
++netdev->stats.rx_dropped;
|
||||
}
|
||||
|
|
|
@ -277,13 +277,13 @@ static void hi3110_hw_tx(struct spi_device *spi, struct can_frame *frame)
|
|||
((frame->can_id & CAN_EFF_MASK) << 1) |
|
||||
((frame->can_id & CAN_RTR_FLAG) ? 1 : 0);
|
||||
|
||||
buf[HI3110_FIFO_EXT_DLC_OFF] = frame->can_dlc;
|
||||
buf[HI3110_FIFO_EXT_DLC_OFF] = frame->len;
|
||||
|
||||
memcpy(buf + HI3110_FIFO_EXT_DATA_OFF,
|
||||
frame->data, frame->can_dlc);
|
||||
frame->data, frame->len);
|
||||
|
||||
hi3110_hw_tx_frame(spi, buf, HI3110_TX_EXT_BUF_LEN -
|
||||
(HI3110_CAN_MAX_DATA_LEN - frame->can_dlc));
|
||||
(HI3110_CAN_MAX_DATA_LEN - frame->len));
|
||||
} else {
|
||||
/* Standard frame */
|
||||
buf[HI3110_FIFO_ID_OFF] = (frame->can_id & CAN_SFF_MASK) >> 3;
|
||||
|
@ -291,13 +291,13 @@ static void hi3110_hw_tx(struct spi_device *spi, struct can_frame *frame)
|
|||
((frame->can_id & CAN_SFF_MASK) << 5) |
|
||||
((frame->can_id & CAN_RTR_FLAG) ? (1 << 4) : 0);
|
||||
|
||||
buf[HI3110_FIFO_STD_DLC_OFF] = frame->can_dlc;
|
||||
buf[HI3110_FIFO_STD_DLC_OFF] = frame->len;
|
||||
|
||||
memcpy(buf + HI3110_FIFO_STD_DATA_OFF,
|
||||
frame->data, frame->can_dlc);
|
||||
frame->data, frame->len);
|
||||
|
||||
hi3110_hw_tx_frame(spi, buf, HI3110_TX_STD_BUF_LEN -
|
||||
(HI3110_CAN_MAX_DATA_LEN - frame->can_dlc));
|
||||
(HI3110_CAN_MAX_DATA_LEN - frame->len));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,16 +341,16 @@ static void hi3110_hw_rx(struct spi_device *spi)
|
|||
}
|
||||
|
||||
/* Data length */
|
||||
frame->can_dlc = get_can_dlc(buf[HI3110_FIFO_WOTIME_DLC_OFF] & 0x0F);
|
||||
frame->len = can_cc_dlc2len(buf[HI3110_FIFO_WOTIME_DLC_OFF] & 0x0F);
|
||||
|
||||
if (buf[HI3110_FIFO_WOTIME_ID_OFF + 3] & HI3110_FIFO_WOTIME_ID_RTR)
|
||||
frame->can_id |= CAN_RTR_FLAG;
|
||||
else
|
||||
memcpy(frame->data, buf + HI3110_FIFO_WOTIME_DAT_OFF,
|
||||
frame->can_dlc);
|
||||
frame->len);
|
||||
|
||||
priv->net->stats.rx_packets++;
|
||||
priv->net->stats.rx_bytes += frame->can_dlc;
|
||||
priv->net->stats.rx_bytes += frame->len;
|
||||
|
||||
can_led_event(priv->net, CAN_LED_EVENT_RX);
|
||||
|
||||
|
@ -585,7 +585,7 @@ static void hi3110_tx_work_handler(struct work_struct *ws)
|
|||
} else {
|
||||
frame = (struct can_frame *)priv->tx_skb->data;
|
||||
hi3110_hw_tx(spi, frame);
|
||||
priv->tx_len = 1 + frame->can_dlc;
|
||||
priv->tx_len = 1 + frame->len;
|
||||
can_put_echo_skb(priv->tx_skb, net, 0);
|
||||
priv->tx_skb = NULL;
|
||||
}
|
||||
|
|
|
@ -644,9 +644,9 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
|
|||
((eid >> SIDL_EID_SHIFT) & SIDL_EID_MASK);
|
||||
buf[TXBEID8_OFF] = GET_BYTE(eid, 1);
|
||||
buf[TXBEID0_OFF] = GET_BYTE(eid, 0);
|
||||
buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;
|
||||
memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);
|
||||
mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
|
||||
buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->len;
|
||||
memcpy(buf + TXBDAT_OFF, frame->data, frame->len);
|
||||
mcp251x_hw_tx_frame(spi, buf, frame->len, tx_buf_idx);
|
||||
|
||||
/* use INSTRUCTION_RTS, to avoid "repeated frame problem" */
|
||||
priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx);
|
||||
|
@ -664,7 +664,7 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
|
|||
for (i = 1; i < RXBDAT_OFF; i++)
|
||||
buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
|
||||
|
||||
len = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
|
||||
len = can_cc_dlc2len(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
|
||||
for (; i < (RXBDAT_OFF + len); i++)
|
||||
buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
|
||||
} else {
|
||||
|
@ -720,11 +720,11 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
|
|||
frame->can_id |= CAN_RTR_FLAG;
|
||||
}
|
||||
/* Data length */
|
||||
frame->can_dlc = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
|
||||
memcpy(frame->data, buf + RXBDAT_OFF, frame->can_dlc);
|
||||
frame->len = can_cc_dlc2len(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
|
||||
memcpy(frame->data, buf + RXBDAT_OFF, frame->len);
|
||||
|
||||
priv->net->stats.rx_packets++;
|
||||
priv->net->stats.rx_bytes += frame->can_dlc;
|
||||
priv->net->stats.rx_bytes += frame->len;
|
||||
|
||||
can_led_event(priv->net, CAN_LED_EVENT_RX);
|
||||
|
||||
|
@ -998,10 +998,10 @@ static void mcp251x_tx_work_handler(struct work_struct *ws)
|
|||
} else {
|
||||
frame = (struct can_frame *)priv->tx_skb->data;
|
||||
|
||||
if (frame->can_dlc > CAN_FRAME_MAX_DATA_LEN)
|
||||
frame->can_dlc = CAN_FRAME_MAX_DATA_LEN;
|
||||
if (frame->len > CAN_FRAME_MAX_DATA_LEN)
|
||||
frame->len = CAN_FRAME_MAX_DATA_LEN;
|
||||
mcp251x_hw_tx(spi, frame, 0);
|
||||
priv->tx_len = 1 + frame->can_dlc;
|
||||
priv->tx_len = 1 + frame->len;
|
||||
can_put_echo_skb(priv->tx_skb, net, 0);
|
||||
priv->tx_skb = NULL;
|
||||
}
|
||||
|
|
|
@ -644,10 +644,7 @@ static int mcp251xfd_chip_softreset(const struct mcp251xfd_priv *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return -ETIMEDOUT;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mcp251xfd_chip_clock_init(const struct mcp251xfd_priv *priv)
|
||||
|
@ -1405,12 +1402,12 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv,
|
|||
cfd->flags |= CANFD_BRS;
|
||||
|
||||
dlc = FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC, hw_rx_obj->flags);
|
||||
cfd->len = can_dlc2len(get_canfd_dlc(dlc));
|
||||
cfd->len = can_fd_dlc2len(dlc);
|
||||
} else {
|
||||
if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)
|
||||
cfd->can_id |= CAN_RTR_FLAG;
|
||||
|
||||
cfd->len = get_can_dlc(FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC,
|
||||
cfd->len = can_cc_dlc2len(FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC,
|
||||
hw_rx_obj->flags));
|
||||
}
|
||||
|
||||
|
@ -2244,7 +2241,7 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv,
|
|||
* harm, only the lower 7 bits will be transferred into the
|
||||
* TEF object.
|
||||
*/
|
||||
dlc = can_len2dlc(cfd->len);
|
||||
dlc = can_fd_len2dlc(cfd->len);
|
||||
flags |= FIELD_PREP(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, seq) |
|
||||
FIELD_PREP(MCP251XFD_OBJ_FLAGS_DLC, dlc);
|
||||
|
||||
|
@ -2273,7 +2270,7 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv,
|
|||
|
||||
/* Clear data at end of CAN frame */
|
||||
offset = round_down(cfd->len, sizeof(u32));
|
||||
len = round_up(can_dlc2len(dlc), sizeof(u32)) - offset;
|
||||
len = round_up(can_fd_dlc2len(dlc), sizeof(u32)) - offset;
|
||||
if (MCP251XFD_SANITIZE_CAN && len)
|
||||
memset(hw_tx_obj->data + offset, 0x0, len);
|
||||
memcpy(hw_tx_obj->data, cfd->data, cfd->len);
|
||||
|
@ -2281,7 +2278,7 @@ mcp251xfd_tx_obj_from_skb(const struct mcp251xfd_priv *priv,
|
|||
/* Number of bytes to be written into the RAM of the controller */
|
||||
len = sizeof(hw_tx_obj->id) + sizeof(hw_tx_obj->flags);
|
||||
if (MCP251XFD_SANITIZE_CAN)
|
||||
len += round_up(can_dlc2len(dlc), sizeof(u32));
|
||||
len += round_up(can_fd_dlc2len(dlc), sizeof(u32));
|
||||
else
|
||||
len += round_up(cfd->len, sizeof(u32));
|
||||
|
||||
|
|
|
@ -424,7 +424,7 @@ static netdev_tx_t sun4ican_start_xmit(struct sk_buff *skb, struct net_device *d
|
|||
netif_stop_queue(dev);
|
||||
|
||||
id = cf->can_id;
|
||||
dlc = cf->can_dlc;
|
||||
dlc = cf->len;
|
||||
msg_flag_n = dlc;
|
||||
|
||||
if (id & CAN_RTR_FLAG)
|
||||
|
@ -475,7 +475,7 @@ static void sun4i_can_rx(struct net_device *dev)
|
|||
return;
|
||||
|
||||
fi = readl(priv->base + SUN4I_REG_BUF0_ADDR);
|
||||
cf->can_dlc = get_can_dlc(fi & 0x0F);
|
||||
cf->len = can_cc_dlc2len(fi & 0x0F);
|
||||
if (fi & SUN4I_MSG_EFF_FLAG) {
|
||||
dreg = SUN4I_REG_BUF5_ADDR;
|
||||
id = (readl(priv->base + SUN4I_REG_BUF1_ADDR) << 21) |
|
||||
|
@ -493,7 +493,7 @@ static void sun4i_can_rx(struct net_device *dev)
|
|||
if (fi & SUN4I_MSG_RTR_FLAG)
|
||||
id |= CAN_RTR_FLAG;
|
||||
else
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
cf->data[i] = readl(priv->base + dreg + i * 4);
|
||||
|
||||
cf->can_id = id;
|
||||
|
@ -501,7 +501,7 @@ static void sun4i_can_rx(struct net_device *dev)
|
|||
sun4i_can_write_cmdreg(priv, SUN4I_CMD_RELEASE_RBUF);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
can_led_event(dev, CAN_LED_EVENT_RX);
|
||||
|
@ -625,7 +625,7 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
|
|||
|
||||
if (likely(skb)) {
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
} else {
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -496,7 +496,7 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||
spin_unlock_irqrestore(&priv->mbx_lock, flags);
|
||||
|
||||
/* Prepare mailbox for transmission */
|
||||
data = cf->can_dlc | (get_tx_head_prio(priv) << 8);
|
||||
data = cf->len | (get_tx_head_prio(priv) << 8);
|
||||
if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */
|
||||
data |= HECC_CANMCF_RTR;
|
||||
hecc_write_mbx(priv, mbxno, HECC_CANMCF, data);
|
||||
|
@ -508,7 +508,7 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||
hecc_write_mbx(priv, mbxno, HECC_CANMID, data);
|
||||
hecc_write_mbx(priv, mbxno, HECC_CANMDL,
|
||||
be32_to_cpu(*(__be32 *)(cf->data)));
|
||||
if (cf->can_dlc > 4)
|
||||
if (cf->len > 4)
|
||||
hecc_write_mbx(priv, mbxno, HECC_CANMDH,
|
||||
be32_to_cpu(*(__be32 *)(cf->data + 4)));
|
||||
else
|
||||
|
@ -566,11 +566,11 @@ static struct sk_buff *ti_hecc_mailbox_read(struct can_rx_offload *offload,
|
|||
data = hecc_read_mbx(priv, mbxno, HECC_CANMCF);
|
||||
if (data & HECC_CANMCF_RTR)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
cf->can_dlc = get_can_dlc(data & 0xF);
|
||||
cf->len = can_cc_dlc2len(data & 0xF);
|
||||
|
||||
data = hecc_read_mbx(priv, mbxno, HECC_CANMDL);
|
||||
*(__be32 *)(cf->data) = cpu_to_be32(data);
|
||||
if (cf->can_dlc > 4) {
|
||||
if (cf->len > 4) {
|
||||
data = hecc_read_mbx(priv, mbxno, HECC_CANMDH);
|
||||
*(__be32 *)(cf->data + 4) = cpu_to_be32(data);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,9 @@ config CAN_KVASER_USB
|
|||
- Kvaser Leaf Light "China"
|
||||
- Kvaser BlackBird SemiPro
|
||||
- Kvaser USBcan R
|
||||
- Kvaser USBcan R v2
|
||||
- Kvaser Leaf Light v2
|
||||
- Kvaser Leaf Light R v2
|
||||
- Kvaser Mini PCI Express HS
|
||||
- Kvaser Mini PCI Express 2xHS
|
||||
- Kvaser USBcan Light 2xHS
|
||||
|
@ -72,6 +74,9 @@ config CAN_KVASER_USB
|
|||
- Kvaser USBcan Light 4xHS
|
||||
- Kvaser USBcan Pro 2xHS v2
|
||||
- Kvaser USBcan Pro 5xHS
|
||||
- Kvaser U100
|
||||
- Kvaser U100P
|
||||
- Kvaser U100S
|
||||
- ATI Memorator Pro 2xHS v2
|
||||
- ATI USBcan Pro 2xHS v2
|
||||
|
||||
|
|
|
@ -306,7 +306,7 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
|
|||
return;
|
||||
|
||||
cf->can_id = le32_to_cpu(msg->msg.can_msg.id);
|
||||
cf->can_dlc = get_can_dlc(msg->msg.can_msg.length & 0xF);
|
||||
cf->len = can_cc_dlc2len(msg->msg.can_msg.length & 0xF);
|
||||
|
||||
if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME ||
|
||||
msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME)
|
||||
|
@ -316,12 +316,12 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
|
|||
msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) {
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
} else {
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
cf->data[i] = msg->msg.can_msg.msg[i];
|
||||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
|
|||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -755,7 +755,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
|
|||
msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE];
|
||||
|
||||
msg->msg.can_msg.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
|
||||
msg->msg.can_msg.length = cf->can_dlc;
|
||||
msg->msg.can_msg.length = cf->len;
|
||||
|
||||
if (cf->can_id & CAN_RTR_FLAG) {
|
||||
msg->type = cf->can_id & CAN_EFF_FLAG ?
|
||||
|
@ -766,10 +766,10 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
|
|||
msg->type = cf->can_id & CAN_EFF_FLAG ?
|
||||
CPC_CMD_TYPE_EXT_CAN_FRAME : CPC_CMD_TYPE_CAN_FRAME;
|
||||
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
msg->msg.can_msg.msg[i] = cf->data[i];
|
||||
|
||||
msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc;
|
||||
msg->length = CPC_CAN_MSG_MIN_SIZE + cf->len;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_TX_URBS; i++) {
|
||||
|
@ -794,7 +794,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
|
|||
|
||||
context->dev = dev;
|
||||
context->echo_index = i;
|
||||
context->dlc = cf->can_dlc;
|
||||
context->dlc = cf->len;
|
||||
|
||||
usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf,
|
||||
size, ems_usb_write_bulk_callback, context);
|
||||
|
|
|
@ -183,7 +183,7 @@ struct esd_usb2_net_priv;
|
|||
struct esd_tx_urb_context {
|
||||
struct esd_usb2_net_priv *priv;
|
||||
u32 echo_index;
|
||||
int dlc;
|
||||
int len; /* CAN payload length */
|
||||
};
|
||||
|
||||
struct esd_usb2 {
|
||||
|
@ -292,7 +292,7 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
|
|||
priv->bec.rxerr = rxerr;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +321,8 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
|
|||
}
|
||||
|
||||
cf->can_id = id & ESD_IDMASK;
|
||||
cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR);
|
||||
can_frame_set_cc_len(cf, msg->msg.rx.dlc & ~ESD_RTR,
|
||||
priv->can.ctrlmode);
|
||||
|
||||
if (id & ESD_EXTID)
|
||||
cf->can_id |= CAN_EFF_FLAG;
|
||||
|
@ -329,12 +330,12 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
|
|||
if (msg->msg.rx.dlc & ESD_RTR) {
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
} else {
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
cf->data[i] = msg->msg.rx.data[i];
|
||||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -355,7 +356,7 @@ static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv,
|
|||
|
||||
if (!msg->msg.txdone.status) {
|
||||
stats->tx_packets++;
|
||||
stats->tx_bytes += context->dlc;
|
||||
stats->tx_bytes += context->len;
|
||||
can_get_echo_skb(netdev, context->echo_index);
|
||||
} else {
|
||||
stats->tx_errors++;
|
||||
|
@ -737,7 +738,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
|
|||
msg->msg.hdr.len = 3; /* minimal length */
|
||||
msg->msg.hdr.cmd = CMD_CAN_TX;
|
||||
msg->msg.tx.net = priv->index;
|
||||
msg->msg.tx.dlc = cf->can_dlc;
|
||||
msg->msg.tx.dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
|
||||
msg->msg.tx.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
|
||||
|
||||
if (cf->can_id & CAN_RTR_FLAG)
|
||||
|
@ -746,10 +747,10 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
|
|||
if (cf->can_id & CAN_EFF_FLAG)
|
||||
msg->msg.tx.id |= cpu_to_le32(ESD_EXTID);
|
||||
|
||||
for (i = 0; i < cf->can_dlc; i++)
|
||||
for (i = 0; i < cf->len; i++)
|
||||
msg->msg.tx.data[i] = cf->data[i];
|
||||
|
||||
msg->msg.hdr.len += (cf->can_dlc + 3) >> 2;
|
||||
msg->msg.hdr.len += (cf->len + 3) >> 2;
|
||||
|
||||
for (i = 0; i < MAX_TX_URBS; i++) {
|
||||
if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
|
||||
|
@ -769,7 +770,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
|
|||
|
||||
context->priv = priv;
|
||||
context->echo_index = i;
|
||||
context->dlc = cf->can_dlc;
|
||||
context->len = cf->len;
|
||||
|
||||
/* hnd must not be 0 - MSB is stripped in txdone handling */
|
||||
msg->msg.tx.hnd = 0x80000000 | i; /* returned in TX done message */
|
||||
|
@ -988,7 +989,8 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index)
|
|||
priv->index = index;
|
||||
|
||||
priv->can.state = CAN_STATE_STOPPED;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC;
|
||||
|
||||
if (le16_to_cpu(dev->udev->descriptor.idProduct) ==
|
||||
USB_CANUSBM_PRODUCT_ID)
|
||||
|
|
|
@ -331,7 +331,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
|
|||
|
||||
cf->can_id = hf->can_id;
|
||||
|
||||
cf->can_dlc = get_can_dlc(hf->can_dlc);
|
||||
can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode);
|
||||
memcpy(cf->data, hf->data, 8);
|
||||
|
||||
/* ERROR frames tell us information about the controller */
|
||||
|
@ -378,7 +378,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
|
|||
goto resubmit_urb;
|
||||
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->can_dlc = CAN_ERR_DLC;
|
||||
cf->len = CAN_ERR_DLC;
|
||||
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
|
||||
stats->rx_over_errors++;
|
||||
stats->rx_errors++;
|
||||
|
@ -504,8 +504,9 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
|
|||
cf = (struct can_frame *)skb->data;
|
||||
|
||||
hf->can_id = cf->can_id;
|
||||
hf->can_dlc = cf->can_dlc;
|
||||
memcpy(hf->data, cf->data, cf->can_dlc);
|
||||
hf->can_dlc = can_get_cc_dlc(cf, dev->can.ctrlmode);
|
||||
|
||||
memcpy(hf->data, cf->data, cf->len);
|
||||
|
||||
usb_fill_bulk_urb(urb, dev->udev,
|
||||
usb_sndbulkpipe(dev->udev, GSUSB_ENDPOINT_OUT),
|
||||
|
@ -858,7 +859,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
|
|||
dev->can.bittiming_const = &dev->bt_const;
|
||||
dev->can.do_set_bittiming = gs_usb_set_bittiming;
|
||||
|
||||
dev->can.ctrlmode_supported = 0;
|
||||
dev->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC;
|
||||
|
||||
if (bt_const->feature & GS_CAN_FEATURE_LISTEN_ONLY)
|
||||
dev->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY;
|
||||
|
|
|
@ -58,6 +58,11 @@
|
|||
#define USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID 290
|
||||
#define USB_USBCAN_LIGHT_2HS_PRODUCT_ID 291
|
||||
#define USB_MINI_PCIE_2HS_PRODUCT_ID 292
|
||||
#define USB_USBCAN_R_V2_PRODUCT_ID 294
|
||||
#define USB_LEAF_LIGHT_R_V2_PRODUCT_ID 295
|
||||
#define USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID 296
|
||||
#define USB_LEAF_PRODUCT_ID_END \
|
||||
USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID
|
||||
|
||||
/* Kvaser USBCan-II devices product ids */
|
||||
#define USB_USBCAN_REVB_PRODUCT_ID 2
|
||||
|
@ -78,13 +83,18 @@
|
|||
#define USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID 268
|
||||
#define USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID 269
|
||||
#define USB_HYBRID_PRO_CANLIN_PRODUCT_ID 270
|
||||
#define USB_U100_PRODUCT_ID 273
|
||||
#define USB_U100P_PRODUCT_ID 274
|
||||
#define USB_U100S_PRODUCT_ID 275
|
||||
#define USB_HYDRA_PRODUCT_ID_END \
|
||||
USB_U100S_PRODUCT_ID
|
||||
|
||||
static inline bool kvaser_is_leaf(const struct usb_device_id *id)
|
||||
{
|
||||
return (id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID &&
|
||||
id->idProduct <= USB_CAN_R_PRODUCT_ID) ||
|
||||
(id->idProduct >= USB_LEAF_LITE_V2_PRODUCT_ID &&
|
||||
id->idProduct <= USB_MINI_PCIE_2HS_PRODUCT_ID);
|
||||
id->idProduct <= USB_LEAF_PRODUCT_ID_END);
|
||||
}
|
||||
|
||||
static inline bool kvaser_is_usbcan(const struct usb_device_id *id)
|
||||
|
@ -96,7 +106,7 @@ static inline bool kvaser_is_usbcan(const struct usb_device_id *id)
|
|||
static inline bool kvaser_is_hydra(const struct usb_device_id *id)
|
||||
{
|
||||
return id->idProduct >= USB_BLACKBIRD_V2_PRODUCT_ID &&
|
||||
id->idProduct <= USB_HYBRID_PRO_CANLIN_PRODUCT_ID;
|
||||
id->idProduct <= USB_HYDRA_PRODUCT_ID_END;
|
||||
}
|
||||
|
||||
static const struct usb_device_id kvaser_usb_table[] = {
|
||||
|
@ -153,6 +163,9 @@ static const struct usb_device_id kvaser_usb_table[] = {
|
|||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID) },
|
||||
|
||||
/* USBCANII USB product IDs */
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID),
|
||||
|
@ -177,6 +190,9 @@ static const struct usb_device_id kvaser_usb_table[] = {
|
|||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID) },
|
||||
{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, kvaser_usb_table);
|
||||
|
@ -258,7 +274,7 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev)
|
|||
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
/* Forward declarations */
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_kcan;
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc;
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt;
|
||||
|
||||
#define KVASER_USB_HYDRA_BULK_EP_IN_ADDR 0x82
|
||||
#define KVASER_USB_HYDRA_BULK_EP_OUT_ADDR 0x02
|
||||
|
@ -135,6 +136,7 @@ struct kvaser_cmd_sw_detail_req {
|
|||
#define KVASER_USB_HYDRA_SW_FLAG_CANFD BIT(10)
|
||||
#define KVASER_USB_HYDRA_SW_FLAG_NONISO BIT(11)
|
||||
#define KVASER_USB_HYDRA_SW_FLAG_EXT_CAP BIT(12)
|
||||
#define KVASER_USB_HYDRA_SW_FLAG_CAN_FREQ_80M BIT(13)
|
||||
struct kvaser_cmd_sw_detail_res {
|
||||
__le32 sw_flags;
|
||||
__le32 sw_version;
|
||||
|
@ -383,6 +385,30 @@ static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = {
|
|||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const kvaser_usb_hydra_rt_bittiming_c = {
|
||||
.name = "kvaser_usb_rt",
|
||||
.tseg1_min = 2,
|
||||
.tseg1_max = 96,
|
||||
.tseg2_min = 2,
|
||||
.tseg2_max = 32,
|
||||
.sjw_max = 32,
|
||||
.brp_min = 1,
|
||||
.brp_max = 1024,
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const kvaser_usb_hydra_rtd_bittiming_c = {
|
||||
.name = "kvaser_usb_rt",
|
||||
.tseg1_min = 2,
|
||||
.tseg1_max = 39,
|
||||
.tseg2_min = 2,
|
||||
.tseg2_max = 8,
|
||||
.sjw_max = 8,
|
||||
.brp_min = 1,
|
||||
.brp_max = 1024,
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
#define KVASER_USB_HYDRA_TRANSID_BITS 12
|
||||
#define KVASER_USB_HYDRA_TRANSID_MASK \
|
||||
GENMASK(KVASER_USB_HYDRA_TRANSID_BITS - 1, 0)
|
||||
|
@ -895,7 +921,7 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
|
|||
|
||||
stats = &netdev->stats;
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -1049,7 +1075,7 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
|
|||
cf->data[7] = bec.rxerr;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
priv->bec.txerr = bec.txerr;
|
||||
|
@ -1084,7 +1110,7 @@ static void kvaser_usb_hydra_one_shot_fail(struct kvaser_usb_net_priv *priv,
|
|||
|
||||
stats->tx_errors++;
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -1120,7 +1146,7 @@ static void kvaser_usb_hydra_tx_acknowledge(const struct kvaser_usb *dev,
|
|||
struct net_device_stats *stats = &priv->netdev->stats;
|
||||
|
||||
stats->tx_packets++;
|
||||
stats->tx_bytes += can_dlc2len(context->dlc);
|
||||
stats->tx_bytes += can_fd_dlc2len(context->dlc);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->tx_contexts_lock, irq_flags);
|
||||
|
@ -1180,15 +1206,15 @@ static void kvaser_usb_hydra_rx_msg_std(const struct kvaser_usb *dev,
|
|||
if (flags & KVASER_USB_HYDRA_CF_FLAG_OVERRUN)
|
||||
kvaser_usb_can_rx_over_error(priv->netdev);
|
||||
|
||||
cf->can_dlc = get_can_dlc(cmd->rx_can.dlc);
|
||||
cf->len = can_cc_dlc2len(cmd->rx_can.dlc);
|
||||
|
||||
if (flags & KVASER_USB_HYDRA_CF_FLAG_REMOTE_FRAME)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
else
|
||||
memcpy(cf->data, cmd->rx_can.data, cf->can_dlc);
|
||||
memcpy(cf->data, cmd->rx_can.data, cf->len);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -1251,13 +1277,13 @@ static void kvaser_usb_hydra_rx_msg_ext(const struct kvaser_usb *dev,
|
|||
kvaser_usb_can_rx_over_error(priv->netdev);
|
||||
|
||||
if (flags & KVASER_USB_HYDRA_CF_FLAG_FDF) {
|
||||
cf->len = can_dlc2len(get_canfd_dlc(dlc));
|
||||
cf->len = can_fd_dlc2len(dlc);
|
||||
if (flags & KVASER_USB_HYDRA_CF_FLAG_BRS)
|
||||
cf->flags |= CANFD_BRS;
|
||||
if (flags & KVASER_USB_HYDRA_CF_FLAG_ESI)
|
||||
cf->flags |= CANFD_ESI;
|
||||
} else {
|
||||
cf->len = get_can_dlc(dlc);
|
||||
cf->len = can_cc_dlc2len(dlc);
|
||||
}
|
||||
|
||||
if (flags & KVASER_USB_HYDRA_CF_FLAG_REMOTE_FRAME)
|
||||
|
@ -1351,7 +1377,7 @@ kvaser_usb_hydra_frame_to_cmd_ext(const struct kvaser_usb_net_priv *priv,
|
|||
struct kvaser_usb *dev = priv->dev;
|
||||
struct kvaser_cmd_ext *cmd;
|
||||
struct canfd_frame *cf = (struct canfd_frame *)skb->data;
|
||||
u8 dlc = can_len2dlc(cf->len);
|
||||
u8 dlc = can_fd_len2dlc(cf->len);
|
||||
u8 nbr_of_bytes = cf->len;
|
||||
u32 flags;
|
||||
u32 id;
|
||||
|
@ -1434,7 +1460,7 @@ kvaser_usb_hydra_frame_to_cmd_std(const struct kvaser_usb_net_priv *priv,
|
|||
u32 flags;
|
||||
u32 id;
|
||||
|
||||
*frame_len = cf->can_dlc;
|
||||
*frame_len = cf->len;
|
||||
|
||||
cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_ATOMIC);
|
||||
if (!cmd)
|
||||
|
@ -1455,7 +1481,7 @@ kvaser_usb_hydra_frame_to_cmd_std(const struct kvaser_usb_net_priv *priv,
|
|||
id = cf->can_id & CAN_SFF_MASK;
|
||||
}
|
||||
|
||||
cmd->tx_can.dlc = cf->can_dlc;
|
||||
cmd->tx_can.dlc = cf->len;
|
||||
|
||||
flags = (cf->can_id & CAN_EFF_FLAG ?
|
||||
KVASER_USB_HYDRA_CF_FLAG_EXTENDED_ID : 0);
|
||||
|
@ -1727,6 +1753,8 @@ static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev)
|
|||
|
||||
if (flags & KVASER_USB_HYDRA_SW_FLAG_FREQ_80M)
|
||||
dev->cfg = &kvaser_usb_hydra_dev_cfg_kcan;
|
||||
else if (flags & KVASER_USB_HYDRA_SW_FLAG_CAN_FREQ_80M)
|
||||
dev->cfg = &kvaser_usb_hydra_dev_cfg_rt;
|
||||
else
|
||||
dev->cfg = &kvaser_usb_hydra_dev_cfg_flexc;
|
||||
|
||||
|
@ -2026,3 +2054,12 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc = {
|
|||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt = {
|
||||
.clock = {
|
||||
.freq = 80000000,
|
||||
},
|
||||
.timestamp_freq = 24,
|
||||
.bittiming_const = &kvaser_usb_hydra_rt_bittiming_c,
|
||||
.data_bittiming_const = &kvaser_usb_hydra_rtd_bittiming_c,
|
||||
};
|
||||
|
|
|
@ -350,7 +350,7 @@ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
|
|||
u8 *cmd_tx_can_flags = NULL; /* GCC */
|
||||
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||
|
||||
*frame_len = cf->can_dlc;
|
||||
*frame_len = cf->len;
|
||||
|
||||
cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
|
||||
if (cmd) {
|
||||
|
@ -383,8 +383,8 @@ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
|
|||
cmd->u.tx_can.data[1] = cf->can_id & 0x3f;
|
||||
}
|
||||
|
||||
cmd->u.tx_can.data[5] = cf->can_dlc;
|
||||
memcpy(&cmd->u.tx_can.data[6], cf->data, cf->can_dlc);
|
||||
cmd->u.tx_can.data[5] = cf->len;
|
||||
memcpy(&cmd->u.tx_can.data[6], cf->data, cf->len);
|
||||
|
||||
if (cf->can_id & CAN_RTR_FLAG)
|
||||
*cmd_tx_can_flags |= MSG_FLAG_REMOTE_FRAME;
|
||||
|
@ -576,7 +576,7 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
|
|||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
} else {
|
||||
netdev_err(priv->netdev,
|
||||
|
@ -694,7 +694,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
|
|||
{
|
||||
struct can_frame *cf;
|
||||
struct can_frame tmp_cf = { .can_id = CAN_ERR_FLAG,
|
||||
.can_dlc = CAN_ERR_DLC };
|
||||
.len = CAN_ERR_DLC };
|
||||
struct sk_buff *skb;
|
||||
struct net_device_stats *stats;
|
||||
struct kvaser_usb_net_priv *priv;
|
||||
|
@ -778,7 +778,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
|
|||
cf->data[7] = es->rxerr;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -978,13 +978,13 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
|
|||
else
|
||||
cf->can_id &= CAN_SFF_MASK;
|
||||
|
||||
cf->can_dlc = get_can_dlc(cmd->u.leaf.log_message.dlc);
|
||||
cf->len = can_cc_dlc2len(cmd->u.leaf.log_message.dlc);
|
||||
|
||||
if (cmd->u.leaf.log_message.flags & MSG_FLAG_REMOTE_FRAME)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
else
|
||||
memcpy(cf->data, &cmd->u.leaf.log_message.data,
|
||||
cf->can_dlc);
|
||||
cf->len);
|
||||
} else {
|
||||
cf->can_id = ((rx_data[0] & 0x1f) << 6) | (rx_data[1] & 0x3f);
|
||||
|
||||
|
@ -996,16 +996,16 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
|
|||
cf->can_id |= CAN_EFF_FLAG;
|
||||
}
|
||||
|
||||
cf->can_dlc = get_can_dlc(rx_data[5]);
|
||||
cf->len = can_cc_dlc2len(rx_data[5]);
|
||||
|
||||
if (cmd->u.rx_can_header.flag & MSG_FLAG_REMOTE_FRAME)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
else
|
||||
memcpy(cf->data, &rx_data[6], cf->can_dlc);
|
||||
memcpy(cf->data, &rx_data[6], cf->len);
|
||||
}
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ static inline struct mcba_usb_ctx *mcba_usb_get_free_ctx(struct mcba_priv *priv,
|
|||
|
||||
if (cf) {
|
||||
ctx->can = true;
|
||||
ctx->dlc = cf->can_dlc;
|
||||
ctx->dlc = cf->len;
|
||||
} else {
|
||||
ctx->can = false;
|
||||
ctx->dlc = 0;
|
||||
|
@ -348,7 +348,7 @@ static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb,
|
|||
usb_msg.eid = 0;
|
||||
}
|
||||
|
||||
usb_msg.dlc = cf->can_dlc;
|
||||
usb_msg.dlc = cf->len;
|
||||
|
||||
memcpy(usb_msg.data, cf->data, usb_msg.dlc);
|
||||
|
||||
|
@ -451,12 +451,12 @@ static void mcba_usb_process_can(struct mcba_priv *priv,
|
|||
if (msg->dlc & MCBA_DLC_RTR_MASK)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
|
||||
cf->can_dlc = get_can_dlc(msg->dlc & MCBA_DLC_MASK);
|
||||
cf->len = can_cc_dlc2len(msg->dlc & MCBA_DLC_MASK);
|
||||
|
||||
memcpy(cf->data, msg->data, cf->can_dlc);
|
||||
memcpy(cf->data, msg->data, cf->len);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
|
||||
can_led_event(priv->netdev, CAN_LED_EVENT_RX);
|
||||
netif_rx(skb);
|
||||
|
|
|
@ -596,7 +596,7 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
|
|||
}
|
||||
|
||||
mc->netdev->stats.rx_packets++;
|
||||
mc->netdev->stats.rx_bytes += cf->can_dlc;
|
||||
mc->netdev->stats.rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
return 0;
|
||||
|
@ -734,7 +734,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
|
|||
cf->can_id = le16_to_cpu(tmp16) >> 5;
|
||||
}
|
||||
|
||||
cf->can_dlc = get_can_dlc(rec_len);
|
||||
can_frame_set_cc_len(cf, rec_len, mc->pdev->dev.can.ctrlmode);
|
||||
|
||||
/* Only first packet timestamp is a word */
|
||||
if (pcan_usb_decode_ts(mc, !mc->rec_ts_idx))
|
||||
|
@ -751,7 +751,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
|
|||
if ((mc->ptr + rec_len) > mc->end)
|
||||
goto decode_failed;
|
||||
|
||||
memcpy(cf->data, mc->ptr, cf->can_dlc);
|
||||
memcpy(cf->data, mc->ptr, cf->len);
|
||||
mc->ptr += rec_len;
|
||||
}
|
||||
|
||||
|
@ -761,7 +761,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
|
|||
|
||||
/* update statistics */
|
||||
mc->netdev->stats.rx_packets++;
|
||||
mc->netdev->stats.rx_bytes += cf->can_dlc;
|
||||
mc->netdev->stats.rx_bytes += cf->len;
|
||||
/* push the skb */
|
||||
netif_rx(skb);
|
||||
|
||||
|
@ -838,7 +838,8 @@ static int pcan_usb_encode_msg(struct peak_usb_device *dev, struct sk_buff *skb,
|
|||
pc = obuf + PCAN_USB_MSG_HEADER_LEN;
|
||||
|
||||
/* status/len byte */
|
||||
*pc = cf->can_dlc;
|
||||
*pc = can_get_cc_dlc(cf, dev->can.ctrlmode);
|
||||
|
||||
if (cf->can_id & CAN_RTR_FLAG)
|
||||
*pc |= PCAN_USB_STATUSLEN_RTR;
|
||||
|
||||
|
@ -858,8 +859,8 @@ static int pcan_usb_encode_msg(struct peak_usb_device *dev, struct sk_buff *skb,
|
|||
|
||||
/* can data */
|
||||
if (!(cf->can_id & CAN_RTR_FLAG)) {
|
||||
memcpy(pc, cf->data, cf->can_dlc);
|
||||
pc += cf->can_dlc;
|
||||
memcpy(pc, cf->data, cf->len);
|
||||
pc += cf->len;
|
||||
}
|
||||
|
||||
obuf[(*size)-1] = (u8)(stats->tx_packets & 0xff);
|
||||
|
@ -992,7 +993,8 @@ const struct peak_usb_adapter pcan_usb = {
|
|||
.device_id = PCAN_USB_PRODUCT_ID,
|
||||
.ctrl_count = 1,
|
||||
.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_BERR_REPORTING,
|
||||
CAN_CTRLMODE_BERR_REPORTING |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC,
|
||||
.clock = {
|
||||
.freq = PCAN_USB_CRYSTAL_HZ / 2 ,
|
||||
},
|
||||
|
|
|
@ -492,14 +492,16 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,
|
|||
if (rx_msg_flags & PUCAN_MSG_ERROR_STATE_IND)
|
||||
cfd->flags |= CANFD_ESI;
|
||||
|
||||
cfd->len = can_dlc2len(get_canfd_dlc(pucan_msg_get_dlc(rm)));
|
||||
cfd->len = can_fd_dlc2len(pucan_msg_get_dlc(rm));
|
||||
} else {
|
||||
/* CAN 2.0 frame case */
|
||||
skb = alloc_can_skb(netdev, (struct can_frame **)&cfd);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cfd->len = get_can_dlc(pucan_msg_get_dlc(rm));
|
||||
can_frame_set_cc_len((struct can_frame *)cfd,
|
||||
pucan_msg_get_dlc(rm),
|
||||
dev->can.ctrlmode);
|
||||
}
|
||||
|
||||
cfd->can_id = le32_to_cpu(rm->can_id);
|
||||
|
@ -581,7 +583,7 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
|
|||
peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
|
||||
|
||||
netdev->stats.rx_packets++;
|
||||
netdev->stats.rx_bytes += cf->can_dlc;
|
||||
netdev->stats.rx_bytes += cf->len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -737,7 +739,7 @@ static int pcan_usb_fd_encode_msg(struct peak_usb_device *dev,
|
|||
struct pucan_tx_msg *tx_msg = (struct pucan_tx_msg *)obuf;
|
||||
struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
|
||||
u16 tx_msg_size, tx_msg_flags;
|
||||
u8 can_dlc;
|
||||
u8 dlc;
|
||||
|
||||
if (cfd->len > CANFD_MAX_DLEN)
|
||||
return -EINVAL;
|
||||
|
@ -756,7 +758,7 @@ static int pcan_usb_fd_encode_msg(struct peak_usb_device *dev,
|
|||
|
||||
if (can_is_canfd_skb(skb)) {
|
||||
/* considering a CANFD frame */
|
||||
can_dlc = can_len2dlc(cfd->len);
|
||||
dlc = can_fd_len2dlc(cfd->len);
|
||||
|
||||
tx_msg_flags |= PUCAN_MSG_EXT_DATA_LEN;
|
||||
|
||||
|
@ -767,14 +769,15 @@ static int pcan_usb_fd_encode_msg(struct peak_usb_device *dev,
|
|||
tx_msg_flags |= PUCAN_MSG_ERROR_STATE_IND;
|
||||
} else {
|
||||
/* CAND 2.0 frames */
|
||||
can_dlc = cfd->len;
|
||||
dlc = can_get_cc_dlc((struct can_frame *)cfd,
|
||||
dev->can.ctrlmode);
|
||||
|
||||
if (cfd->can_id & CAN_RTR_FLAG)
|
||||
tx_msg_flags |= PUCAN_MSG_RTR;
|
||||
}
|
||||
|
||||
tx_msg->flags = cpu_to_le16(tx_msg_flags);
|
||||
tx_msg->channel_dlc = PUCAN_MSG_CHANNEL_DLC(dev->ctrl_idx, can_dlc);
|
||||
tx_msg->channel_dlc = PUCAN_MSG_CHANNEL_DLC(dev->ctrl_idx, dlc);
|
||||
memcpy(tx_msg->d, cfd->data, cfd->len);
|
||||
|
||||
/* add null size message to tag the end (messages are 32-bits aligned)
|
||||
|
@ -1036,7 +1039,8 @@ const struct peak_usb_adapter pcan_usb_fd = {
|
|||
.device_id = PCAN_USBFD_PRODUCT_ID,
|
||||
.ctrl_count = PCAN_USBFD_CHANNEL_COUNT,
|
||||
.ctrlmode_supported = CAN_CTRLMODE_FD |
|
||||
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
|
||||
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC,
|
||||
.clock = {
|
||||
.freq = PCAN_UFD_CRYSTAL_HZ,
|
||||
},
|
||||
|
@ -1108,7 +1112,8 @@ const struct peak_usb_adapter pcan_usb_chip = {
|
|||
.device_id = PCAN_USBCHIP_PRODUCT_ID,
|
||||
.ctrl_count = PCAN_USBFD_CHANNEL_COUNT,
|
||||
.ctrlmode_supported = CAN_CTRLMODE_FD |
|
||||
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
|
||||
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC,
|
||||
.clock = {
|
||||
.freq = PCAN_UFD_CRYSTAL_HZ,
|
||||
},
|
||||
|
@ -1180,7 +1185,8 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
|
|||
.device_id = PCAN_USBPROFD_PRODUCT_ID,
|
||||
.ctrl_count = PCAN_USBPROFD_CHANNEL_COUNT,
|
||||
.ctrlmode_supported = CAN_CTRLMODE_FD |
|
||||
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
|
||||
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC,
|
||||
.clock = {
|
||||
.freq = PCAN_UFD_CRYSTAL_HZ,
|
||||
},
|
||||
|
@ -1252,7 +1258,8 @@ const struct peak_usb_adapter pcan_usb_x6 = {
|
|||
.device_id = PCAN_USBX6_PRODUCT_ID,
|
||||
.ctrl_count = PCAN_USBPROFD_CHANNEL_COUNT,
|
||||
.ctrlmode_supported = CAN_CTRLMODE_FD |
|
||||
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
|
||||
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC,
|
||||
.clock = {
|
||||
.freq = PCAN_UFD_CRYSTAL_HZ,
|
||||
},
|
||||
|
|
|
@ -532,7 +532,7 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
|
|||
return -ENOMEM;
|
||||
|
||||
can_frame->can_id = le32_to_cpu(rx->id);
|
||||
can_frame->can_dlc = rx->len & 0x0f;
|
||||
can_frame->len = rx->len & 0x0f;
|
||||
|
||||
if (rx->flags & PCAN_USBPRO_EXT)
|
||||
can_frame->can_id |= CAN_EFF_FLAG;
|
||||
|
@ -540,14 +540,14 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
|
|||
if (rx->flags & PCAN_USBPRO_RTR)
|
||||
can_frame->can_id |= CAN_RTR_FLAG;
|
||||
else
|
||||
memcpy(can_frame->data, rx->data, can_frame->can_dlc);
|
||||
memcpy(can_frame->data, rx->data, can_frame->len);
|
||||
|
||||
hwts = skb_hwtstamps(skb);
|
||||
peak_usb_get_ts_time(&usb_if->time_ref, le32_to_cpu(rx->ts32),
|
||||
&hwts->hwtstamp);
|
||||
|
||||
netdev->stats.rx_packets++;
|
||||
netdev->stats.rx_bytes += can_frame->can_dlc;
|
||||
netdev->stats.rx_bytes += can_frame->len;
|
||||
netif_rx(skb);
|
||||
|
||||
return 0;
|
||||
|
@ -662,7 +662,7 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
|
|||
hwts = skb_hwtstamps(skb);
|
||||
peak_usb_get_ts_time(&usb_if->time_ref, le32_to_cpu(er->ts32), &hwts->hwtstamp);
|
||||
netdev->stats.rx_packets++;
|
||||
netdev->stats.rx_bytes += can_frame->can_dlc;
|
||||
netdev->stats.rx_bytes += can_frame->len;
|
||||
netif_rx(skb);
|
||||
|
||||
return 0;
|
||||
|
@ -767,14 +767,14 @@ static int pcan_usb_pro_encode_msg(struct peak_usb_device *dev,
|
|||
|
||||
pcan_msg_init_empty(&usb_msg, obuf, *size);
|
||||
|
||||
if ((cf->can_id & CAN_RTR_FLAG) || (cf->can_dlc == 0))
|
||||
if ((cf->can_id & CAN_RTR_FLAG) || (cf->len == 0))
|
||||
data_type = PCAN_USBPRO_TXMSG0;
|
||||
else if (cf->can_dlc <= 4)
|
||||
else if (cf->len <= 4)
|
||||
data_type = PCAN_USBPRO_TXMSG4;
|
||||
else
|
||||
data_type = PCAN_USBPRO_TXMSG8;
|
||||
|
||||
len = (dev->ctrl_idx << 4) | (cf->can_dlc & 0x0f);
|
||||
len = (dev->ctrl_idx << 4) | (cf->len & 0x0f);
|
||||
|
||||
flags = 0;
|
||||
if (cf->can_id & CAN_EFF_FLAG)
|
||||
|
|
|
@ -303,12 +303,12 @@ struct ucan_priv {
|
|||
struct ucan_urb_context *context_array;
|
||||
};
|
||||
|
||||
static u8 ucan_get_can_dlc(struct ucan_can_msg *msg, u16 len)
|
||||
static u8 ucan_can_cc_dlc2len(struct ucan_can_msg *msg, u16 len)
|
||||
{
|
||||
if (le32_to_cpu(msg->id) & CAN_RTR_FLAG)
|
||||
return get_can_dlc(msg->dlc);
|
||||
return can_cc_dlc2len(msg->dlc);
|
||||
else
|
||||
return get_can_dlc(len - (UCAN_IN_HDR_SIZE + sizeof(msg->id)));
|
||||
return can_cc_dlc2len(len - (UCAN_IN_HDR_SIZE + sizeof(msg->id)));
|
||||
}
|
||||
|
||||
static void ucan_release_context_array(struct ucan_priv *up)
|
||||
|
@ -614,15 +614,15 @@ static void ucan_rx_can_msg(struct ucan_priv *up, struct ucan_message_in *m)
|
|||
cf->can_id = canid;
|
||||
|
||||
/* compute DLC taking RTR_FLAG into account */
|
||||
cf->can_dlc = ucan_get_can_dlc(&m->msg.can_msg, len);
|
||||
cf->len = ucan_can_cc_dlc2len(&m->msg.can_msg, len);
|
||||
|
||||
/* copy the payload of non RTR frames */
|
||||
if (!(cf->can_id & CAN_RTR_FLAG) || (cf->can_id & CAN_ERR_FLAG))
|
||||
memcpy(cf->data, m->msg.can_msg.data, cf->can_dlc);
|
||||
memcpy(cf->data, m->msg.can_msg.data, cf->len);
|
||||
|
||||
/* don't count error frames as real packets */
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
|
||||
/* pass it to Linux */
|
||||
netif_rx(skb);
|
||||
|
@ -1078,15 +1078,15 @@ static struct urb *ucan_prepare_tx_urb(struct ucan_priv *up,
|
|||
mlen = UCAN_OUT_HDR_SIZE +
|
||||
offsetof(struct ucan_can_msg, dlc) +
|
||||
sizeof(m->msg.can_msg.dlc);
|
||||
m->msg.can_msg.dlc = cf->can_dlc;
|
||||
m->msg.can_msg.dlc = cf->len;
|
||||
} else {
|
||||
mlen = UCAN_OUT_HDR_SIZE +
|
||||
sizeof(m->msg.can_msg.id) + cf->can_dlc;
|
||||
memcpy(m->msg.can_msg.data, cf->data, cf->can_dlc);
|
||||
sizeof(m->msg.can_msg.id) + cf->len;
|
||||
memcpy(m->msg.can_msg.data, cf->data, cf->len);
|
||||
}
|
||||
m->len = cpu_to_le16(mlen);
|
||||
|
||||
context->dlc = cf->can_dlc;
|
||||
context->dlc = cf->len;
|
||||
|
||||
m->subtype = echo_index;
|
||||
|
||||
|
|
|
@ -449,7 +449,7 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
|
|||
priv->bec.rxerr = rxerr;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
|
@ -470,7 +470,7 @@ static void usb_8dev_rx_can_msg(struct usb_8dev_priv *priv,
|
|||
return;
|
||||
|
||||
cf->can_id = be32_to_cpu(msg->id);
|
||||
cf->can_dlc = get_can_dlc(msg->dlc & 0xF);
|
||||
can_frame_set_cc_len(cf, msg->dlc & 0xF, priv->can.ctrlmode);
|
||||
|
||||
if (msg->flags & USB_8DEV_EXTID)
|
||||
cf->can_id |= CAN_EFF_FLAG;
|
||||
|
@ -478,10 +478,10 @@ static void usb_8dev_rx_can_msg(struct usb_8dev_priv *priv,
|
|||
if (msg->flags & USB_8DEV_RTR)
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
else
|
||||
memcpy(cf->data, msg->data, cf->can_dlc);
|
||||
memcpy(cf->data, msg->data, cf->len);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
|
||||
can_led_event(priv->netdev, CAN_LED_EVENT_RX);
|
||||
|
@ -637,8 +637,8 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
|
|||
msg->flags |= USB_8DEV_EXTID;
|
||||
|
||||
msg->id = cpu_to_be32(cf->can_id & CAN_ERR_MASK);
|
||||
msg->dlc = cf->can_dlc;
|
||||
memcpy(msg->data, cf->data, cf->can_dlc);
|
||||
msg->dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
|
||||
memcpy(msg->data, cf->data, cf->len);
|
||||
msg->end = USB_8DEV_DATA_END;
|
||||
|
||||
for (i = 0; i < MAX_TX_URBS; i++) {
|
||||
|
@ -656,7 +656,7 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
|
|||
|
||||
context->priv = priv;
|
||||
context->echo_index = i;
|
||||
context->dlc = cf->can_dlc;
|
||||
context->dlc = cf->len;
|
||||
|
||||
usb_fill_bulk_urb(urb, priv->udev,
|
||||
usb_sndbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_TX),
|
||||
|
@ -928,7 +928,8 @@ static int usb_8dev_probe(struct usb_interface *intf,
|
|||
priv->can.do_get_berr_counter = usb_8dev_get_berr_counter;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
|
||||
CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_ONE_SHOT;
|
||||
CAN_CTRLMODE_ONE_SHOT |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC;
|
||||
|
||||
netdev->netdev_ops = &usb_8dev_netdev_ops;
|
||||
|
||||
|
|
|
@ -583,7 +583,7 @@ static void xcan_write_frame(struct net_device *ndev, struct sk_buff *skb,
|
|||
id |= XCAN_IDR_SRR_MASK;
|
||||
}
|
||||
|
||||
dlc = can_len2dlc(cf->len) << XCAN_DLCR_DLC_SHIFT;
|
||||
dlc = can_fd_len2dlc(cf->len) << XCAN_DLCR_DLC_SHIFT;
|
||||
if (can_is_canfd_skb(skb)) {
|
||||
if (cf->flags & CANFD_BRS)
|
||||
dlc |= XCAN_DLCR_BRS_MASK;
|
||||
|
@ -759,7 +759,7 @@ static int xcan_rx(struct net_device *ndev, int frame_base)
|
|||
XCAN_DLCR_DLC_SHIFT;
|
||||
|
||||
/* Change Xilinx CAN data length format to socketCAN data format */
|
||||
cf->can_dlc = get_can_dlc(dlc);
|
||||
cf->len = can_cc_dlc2len(dlc);
|
||||
|
||||
/* Change Xilinx CAN ID format to socketCAN ID format */
|
||||
if (id_xcan & XCAN_IDR_IDE_MASK) {
|
||||
|
@ -784,13 +784,13 @@ static int xcan_rx(struct net_device *ndev, int frame_base)
|
|||
|
||||
if (!(cf->can_id & CAN_RTR_FLAG)) {
|
||||
/* Change Xilinx CAN data format to socketCAN data format */
|
||||
if (cf->can_dlc > 0)
|
||||
if (cf->len > 0)
|
||||
*(__be32 *)(cf->data) = cpu_to_be32(data[0]);
|
||||
if (cf->can_dlc > 4)
|
||||
if (cf->len > 4)
|
||||
*(__be32 *)(cf->data + 4) = cpu_to_be32(data[1]);
|
||||
}
|
||||
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
stats->rx_packets++;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
|
@ -832,10 +832,10 @@ static int xcanfd_rx(struct net_device *ndev, int frame_base)
|
|||
* format
|
||||
*/
|
||||
if (dlc & XCAN_DLCR_EDL_MASK)
|
||||
cf->len = can_dlc2len((dlc & XCAN_DLCR_DLC_MASK) >>
|
||||
cf->len = can_fd_dlc2len((dlc & XCAN_DLCR_DLC_MASK) >>
|
||||
XCAN_DLCR_DLC_SHIFT);
|
||||
else
|
||||
cf->len = get_can_dlc((dlc & XCAN_DLCR_DLC_MASK) >>
|
||||
cf->len = can_cc_dlc2len((dlc & XCAN_DLCR_DLC_MASK) >>
|
||||
XCAN_DLCR_DLC_SHIFT);
|
||||
|
||||
/* Change Xilinx CAN ID format to socketCAN ID format */
|
||||
|
@ -970,7 +970,7 @@ static void xcan_update_error_state_after_rxtx(struct net_device *ndev)
|
|||
struct net_device_stats *stats = &ndev->stats;
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->can_dlc;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_rx(skb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
#define IMX_SC_R_CAN_0 105
|
||||
#define IMX_SC_R_CAN_1 106
|
||||
#define IMX_SC_R_CAN_2 107
|
||||
#define IMX_SC_R_CAN(x) (IMX_SC_R_CAN_0 + (x))
|
||||
#define IMX_SC_R_DMA_1_CH0 108
|
||||
#define IMX_SC_R_DMA_1_CH1 109
|
||||
#define IMX_SC_R_DMA_1_CH2 110
|
||||
|
|
|
@ -98,14 +98,13 @@ static inline unsigned int can_bit_time(const struct can_bittiming *bt)
|
|||
}
|
||||
|
||||
/*
|
||||
* get_can_dlc(value) - helper macro to cast a given data length code (dlc)
|
||||
* to u8 and ensure the dlc value to be max. 8 bytes.
|
||||
* can_cc_dlc2len(value) - convert a given data length code (dlc) of a
|
||||
* Classical CAN frame into a valid data length of max. 8 bytes.
|
||||
*
|
||||
* To be used in the CAN netdriver receive path to ensure conformance with
|
||||
* ISO 11898-1 Chapter 8.4.2.3 (DLC field)
|
||||
*/
|
||||
#define get_can_dlc(i) (min_t(u8, (i), CAN_MAX_DLC))
|
||||
#define get_canfd_dlc(i) (min_t(u8, (i), CANFD_MAX_DLC))
|
||||
#define can_cc_dlc2len(dlc) (min_t(u8, (dlc), CAN_MAX_DLEN))
|
||||
|
||||
/* Check for outgoing skbs that have not been created by the CAN subsystem */
|
||||
static inline bool can_skb_headroom_valid(struct net_device *dev,
|
||||
|
@ -171,6 +170,31 @@ static inline bool can_is_canfd_skb(const struct sk_buff *skb)
|
|||
return skb->len == CANFD_MTU;
|
||||
}
|
||||
|
||||
/* helper to get the data length code (DLC) for Classical CAN raw DLC access */
|
||||
static inline u8 can_get_cc_dlc(const struct can_frame *cf, const u32 ctrlmode)
|
||||
{
|
||||
/* return len8_dlc as dlc value only if all conditions apply */
|
||||
if ((ctrlmode & CAN_CTRLMODE_CC_LEN8_DLC) &&
|
||||
(cf->len == CAN_MAX_DLEN) &&
|
||||
(cf->len8_dlc > CAN_MAX_DLEN && cf->len8_dlc <= CAN_MAX_RAW_DLC))
|
||||
return cf->len8_dlc;
|
||||
|
||||
/* return the payload length as dlc value */
|
||||
return cf->len;
|
||||
}
|
||||
|
||||
/* helper to set len and len8_dlc value for Classical CAN raw DLC access */
|
||||
static inline void can_frame_set_cc_len(struct can_frame *cf, const u8 dlc,
|
||||
const u32 ctrlmode)
|
||||
{
|
||||
/* the caller already ensured that dlc is a value from 0 .. 15 */
|
||||
if (ctrlmode & CAN_CTRLMODE_CC_LEN8_DLC && dlc > CAN_MAX_DLEN)
|
||||
cf->len8_dlc = dlc;
|
||||
|
||||
/* limit the payload length 'len' to CAN_MAX_DLEN */
|
||||
cf->len = can_cc_dlc2len(dlc);
|
||||
}
|
||||
|
||||
/* helper to define static CAN controller features at device creation time */
|
||||
static inline void can_set_static_ctrlmode(struct net_device *dev,
|
||||
u32 static_mode)
|
||||
|
@ -186,11 +210,11 @@ static inline void can_set_static_ctrlmode(struct net_device *dev,
|
|||
dev->mtu = CANFD_MTU;
|
||||
}
|
||||
|
||||
/* get data length from can_dlc with sanitized can_dlc */
|
||||
u8 can_dlc2len(u8 can_dlc);
|
||||
/* get data length from raw data length code (DLC) */
|
||||
u8 can_fd_dlc2len(u8 dlc);
|
||||
|
||||
/* map the sanitized data length to an appropriate data length code */
|
||||
u8 can_len2dlc(u8 len);
|
||||
u8 can_fd_len2dlc(u8 len);
|
||||
|
||||
struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
|
||||
unsigned int txqs, unsigned int rxqs);
|
||||
|
|
|
@ -282,7 +282,7 @@ static inline int pucan_msg_get_channel(const struct pucan_rx_msg *msg)
|
|||
}
|
||||
|
||||
/* return the dlc value from any received message channel_dlc field */
|
||||
static inline int pucan_msg_get_dlc(const struct pucan_rx_msg *msg)
|
||||
static inline u8 pucan_msg_get_dlc(const struct pucan_rx_msg *msg)
|
||||
{
|
||||
return msg->channel_dlc >> 4;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ typedef __u32 can_err_mask_t;
|
|||
|
||||
/* CAN payload length and DLC definitions according to ISO 11898-1 */
|
||||
#define CAN_MAX_DLC 8
|
||||
#define CAN_MAX_RAW_DLC 15
|
||||
#define CAN_MAX_DLEN 8
|
||||
|
||||
/* CAN FD payload length and DLC definitions according to ISO 11898-7 */
|
||||
|
@ -91,23 +92,32 @@ typedef __u32 can_err_mask_t;
|
|||
#define CANFD_MAX_DLEN 64
|
||||
|
||||
/**
|
||||
* struct can_frame - basic CAN frame structure
|
||||
* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
|
||||
* @can_dlc: frame payload length in byte (0 .. 8) aka data length code
|
||||
* N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
|
||||
* mapping of the 'data length code' to the real payload length
|
||||
* @__pad: padding
|
||||
* @__res0: reserved / padding
|
||||
* @__res1: reserved / padding
|
||||
* @data: CAN frame payload (up to 8 byte)
|
||||
* struct can_frame - Classical CAN frame structure (aka CAN 2.0B)
|
||||
* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
|
||||
* @len: CAN frame payload length in byte (0 .. 8)
|
||||
* @can_dlc: deprecated name for CAN frame payload length in byte (0 .. 8)
|
||||
* @__pad: padding
|
||||
* @__res0: reserved / padding
|
||||
* @len8_dlc: optional DLC value (9 .. 15) at 8 byte payload length
|
||||
* len8_dlc contains values from 9 .. 15 when the payload length is
|
||||
* 8 bytes but the DLC value (see ISO 11898-1) is greater then 8.
|
||||
* CAN_CTRLMODE_CC_LEN8_DLC flag has to be enabled in CAN driver.
|
||||
* @data: CAN frame payload (up to 8 byte)
|
||||
*/
|
||||
struct can_frame {
|
||||
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
|
||||
__u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
|
||||
__u8 __pad; /* padding */
|
||||
__u8 __res0; /* reserved / padding */
|
||||
__u8 __res1; /* reserved / padding */
|
||||
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
|
||||
union {
|
||||
/* CAN frame payload length in byte (0 .. CAN_MAX_DLEN)
|
||||
* was previously named can_dlc so we need to carry that
|
||||
* name for legacy support
|
||||
*/
|
||||
__u8 len;
|
||||
__u8 can_dlc; /* deprecated */
|
||||
};
|
||||
__u8 __pad; /* padding */
|
||||
__u8 __res0; /* reserved / padding */
|
||||
__u8 len8_dlc; /* optional DLC for 8 byte payload length (9 .. 15) */
|
||||
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -98,8 +98,8 @@ enum {
|
|||
|
||||
/* CAN frame elements that are affected by curr. 3 CAN frame modifications */
|
||||
#define CGW_MOD_ID 0x01
|
||||
#define CGW_MOD_DLC 0x02 /* contains the data length in bytes */
|
||||
#define CGW_MOD_LEN CGW_MOD_DLC /* CAN FD length representation */
|
||||
#define CGW_MOD_DLC 0x02 /* Classical CAN data length code */
|
||||
#define CGW_MOD_LEN CGW_MOD_DLC /* CAN FD (plain) data length */
|
||||
#define CGW_MOD_DATA 0x04
|
||||
#define CGW_MOD_FLAGS 0x08 /* CAN FD flags */
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ struct can_ctrlmode {
|
|||
#define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */
|
||||
#define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */
|
||||
#define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */
|
||||
#define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */
|
||||
|
||||
/*
|
||||
* CAN device statistics
|
||||
|
|
|
@ -888,7 +888,7 @@ static __init int can_init(void)
|
|||
int err;
|
||||
|
||||
/* check for correct padding to be able to use the structs similarly */
|
||||
BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) !=
|
||||
BUILD_BUG_ON(offsetof(struct can_frame, len) !=
|
||||
offsetof(struct canfd_frame, len) ||
|
||||
offsetof(struct can_frame, data) !=
|
||||
offsetof(struct canfd_frame, data));
|
||||
|
|
80
net/can/gw.c
80
net/can/gw.c
|
@ -199,6 +199,68 @@ static void mod_set_fddata(struct canfd_frame *cf, struct cf_mod *mod)
|
|||
memcpy(cf->data, mod->modframe.set.data, CANFD_MAX_DLEN);
|
||||
}
|
||||
|
||||
/* retrieve valid CC DLC value and store it into 'len' */
|
||||
static void mod_retrieve_ccdlc(struct canfd_frame *cf)
|
||||
{
|
||||
struct can_frame *ccf = (struct can_frame *)cf;
|
||||
|
||||
/* len8_dlc is only valid if len == CAN_MAX_DLEN */
|
||||
if (ccf->len != CAN_MAX_DLEN)
|
||||
return;
|
||||
|
||||
/* do we have a valid len8_dlc value from 9 .. 15 ? */
|
||||
if (ccf->len8_dlc > CAN_MAX_DLEN && ccf->len8_dlc <= CAN_MAX_RAW_DLC)
|
||||
ccf->len = ccf->len8_dlc;
|
||||
}
|
||||
|
||||
/* convert valid CC DLC value in 'len' into struct can_frame elements */
|
||||
static void mod_store_ccdlc(struct canfd_frame *cf)
|
||||
{
|
||||
struct can_frame *ccf = (struct can_frame *)cf;
|
||||
|
||||
/* clear potential leftovers */
|
||||
ccf->len8_dlc = 0;
|
||||
|
||||
/* plain data length 0 .. 8 - that was easy */
|
||||
if (ccf->len <= CAN_MAX_DLEN)
|
||||
return;
|
||||
|
||||
/* potentially broken values are catched in can_can_gw_rcv() */
|
||||
if (ccf->len > CAN_MAX_RAW_DLC)
|
||||
return;
|
||||
|
||||
/* we have a valid dlc value from 9 .. 15 in ccf->len */
|
||||
ccf->len8_dlc = ccf->len;
|
||||
ccf->len = CAN_MAX_DLEN;
|
||||
}
|
||||
|
||||
static void mod_and_ccdlc(struct canfd_frame *cf, struct cf_mod *mod)
|
||||
{
|
||||
mod_retrieve_ccdlc(cf);
|
||||
mod_and_len(cf, mod);
|
||||
mod_store_ccdlc(cf);
|
||||
}
|
||||
|
||||
static void mod_or_ccdlc(struct canfd_frame *cf, struct cf_mod *mod)
|
||||
{
|
||||
mod_retrieve_ccdlc(cf);
|
||||
mod_or_len(cf, mod);
|
||||
mod_store_ccdlc(cf);
|
||||
}
|
||||
|
||||
static void mod_xor_ccdlc(struct canfd_frame *cf, struct cf_mod *mod)
|
||||
{
|
||||
mod_retrieve_ccdlc(cf);
|
||||
mod_xor_len(cf, mod);
|
||||
mod_store_ccdlc(cf);
|
||||
}
|
||||
|
||||
static void mod_set_ccdlc(struct canfd_frame *cf, struct cf_mod *mod)
|
||||
{
|
||||
mod_set_len(cf, mod);
|
||||
mod_store_ccdlc(cf);
|
||||
}
|
||||
|
||||
static void canframecpy(struct canfd_frame *dst, struct can_frame *src)
|
||||
{
|
||||
/* Copy the struct members separately to ensure that no uninitialized
|
||||
|
@ -207,7 +269,7 @@ static void canframecpy(struct canfd_frame *dst, struct can_frame *src)
|
|||
*/
|
||||
|
||||
dst->can_id = src->can_id;
|
||||
dst->len = src->can_dlc;
|
||||
dst->len = src->len;
|
||||
*(u64 *)dst->data = *(u64 *)src->data;
|
||||
}
|
||||
|
||||
|
@ -842,8 +904,8 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
|
|||
if (mb.modtype & CGW_MOD_ID)
|
||||
mod->modfunc[modidx++] = mod_and_id;
|
||||
|
||||
if (mb.modtype & CGW_MOD_LEN)
|
||||
mod->modfunc[modidx++] = mod_and_len;
|
||||
if (mb.modtype & CGW_MOD_DLC)
|
||||
mod->modfunc[modidx++] = mod_and_ccdlc;
|
||||
|
||||
if (mb.modtype & CGW_MOD_DATA)
|
||||
mod->modfunc[modidx++] = mod_and_data;
|
||||
|
@ -858,8 +920,8 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
|
|||
if (mb.modtype & CGW_MOD_ID)
|
||||
mod->modfunc[modidx++] = mod_or_id;
|
||||
|
||||
if (mb.modtype & CGW_MOD_LEN)
|
||||
mod->modfunc[modidx++] = mod_or_len;
|
||||
if (mb.modtype & CGW_MOD_DLC)
|
||||
mod->modfunc[modidx++] = mod_or_ccdlc;
|
||||
|
||||
if (mb.modtype & CGW_MOD_DATA)
|
||||
mod->modfunc[modidx++] = mod_or_data;
|
||||
|
@ -874,8 +936,8 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
|
|||
if (mb.modtype & CGW_MOD_ID)
|
||||
mod->modfunc[modidx++] = mod_xor_id;
|
||||
|
||||
if (mb.modtype & CGW_MOD_LEN)
|
||||
mod->modfunc[modidx++] = mod_xor_len;
|
||||
if (mb.modtype & CGW_MOD_DLC)
|
||||
mod->modfunc[modidx++] = mod_xor_ccdlc;
|
||||
|
||||
if (mb.modtype & CGW_MOD_DATA)
|
||||
mod->modfunc[modidx++] = mod_xor_data;
|
||||
|
@ -890,8 +952,8 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
|
|||
if (mb.modtype & CGW_MOD_ID)
|
||||
mod->modfunc[modidx++] = mod_set_id;
|
||||
|
||||
if (mb.modtype & CGW_MOD_LEN)
|
||||
mod->modfunc[modidx++] = mod_set_len;
|
||||
if (mb.modtype & CGW_MOD_DLC)
|
||||
mod->modfunc[modidx++] = mod_set_ccdlc;
|
||||
|
||||
if (mb.modtype & CGW_MOD_DATA)
|
||||
mod->modfunc[modidx++] = mod_set_data;
|
||||
|
|
|
@ -62,7 +62,7 @@ static void j1939_can_recv(struct sk_buff *iskb, void *data)
|
|||
skb_pull(skb, J1939_CAN_HDR);
|
||||
|
||||
/* fix length, set to dlc, with 8 maximum */
|
||||
skb_trim(skb, min_t(uint8_t, cf->can_dlc, 8));
|
||||
skb_trim(skb, min_t(uint8_t, cf->len, 8));
|
||||
|
||||
/* set addr */
|
||||
skcb = j1939_skb_to_cb(skb);
|
||||
|
@ -335,7 +335,7 @@ int j1939_send_one(struct j1939_priv *priv, struct sk_buff *skb)
|
|||
canid |= skcb->addr.da << 8;
|
||||
|
||||
cf->can_id = canid;
|
||||
cf->can_dlc = dlc;
|
||||
cf->len = dlc;
|
||||
|
||||
return can_send(skb, 1);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче