Commit 50ad649d authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-next-for-5.20-20220720' of...

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

Marc Kleine-Budde says:

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

The first 6 patches target the slcan driver. Dan Carpenter contributes
a hardening patch, followed by 5 cleanup patches.

Biju Das contributes 5 patches to prepare the sja1000 driver to
support the Renesas RZ/N1 SJA1000 CAN controller.

Dario Binacchi's patch for the slcan driver fixes a sleep with held
spin lock.

Another patch by Dario Binacchi fixes a wrong comment in the c_can
driver.

Pavel Pisa updates the CTU CAN FD IP core registers.

Stephane Grosjean contributes 3 patches to the peak_usb driver for
cleanups and support of a new MCU.

The last 12 patches are by Vincent Mailhol, they fix and improve the
txerr and rxerr reporting in all CAN drivers.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c2fe9ec3 1dbd8748
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/can/nxp,sja1000.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
maintainers:
- Wolfgang Grandegger <wg@grandegger.com>
properties:
compatible:
oneOf:
- enum:
- nxp,sja1000
- technologic,sja1000
- items:
- enum:
- renesas,r9a06g032-sja1000 # RZ/N1D
- renesas,r9a06g033-sja1000 # RZ/N1S
- const: renesas,rzn1-sja1000 # RZ/N1
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
reg-io-width:
$ref: /schemas/types.yaml#/definitions/uint32
description: I/O register width (in bytes) implemented by this device
default: 1
enum: [ 1, 2, 4 ]
nxp,external-clock-frequency:
$ref: /schemas/types.yaml#/definitions/uint32
default: 16000000
description: |
Frequency of the external oscillator clock in Hz.
The internal clock frequency used by the SJA1000 is half of that value.
nxp,tx-output-mode:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 0, 1, 2, 3 ]
default: 1
description: |
operation mode of the TX output control logic. Valid values are:
<0> : bi-phase output mode
<1> : normal output mode (default)
<2> : test output mode
<3> : clock output mode
nxp,tx-output-config:
$ref: /schemas/types.yaml#/definitions/uint32
default: 0x02
description: |
TX output pin configuration. Valid values are any one of the below
or combination of TX0 and TX1:
<0x01> : TX0 invert
<0x02> : TX0 pull-down (default)
<0x04> : TX0 pull-up
<0x06> : TX0 push-pull
<0x08> : TX1 invert
<0x10> : TX1 pull-down
<0x20> : TX1 pull-up
<0x30> : TX1 push-pull
nxp,clock-out-frequency:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
clock frequency in Hz on the CLKOUT pin.
If not specified or if the specified value is 0, the CLKOUT pin
will be disabled.
nxp,no-comparator-bypass:
type: boolean
description: Allows to disable the CAN input comparator.
required:
- compatible
- reg
- interrupts
allOf:
- $ref: can-controller.yaml#
- if:
properties:
compatible:
contains:
enum:
- technologic,sja1000
- renesas,rzn1-sja1000
then:
required:
- reg-io-width
- if:
properties:
compatible:
contains:
const: renesas,rzn1-sja1000
then:
required:
- clocks
unevaluatedProperties: false
examples:
- |
can@1a000 {
compatible = "technologic,sja1000";
reg = <0x1a000 0x100>;
interrupts = <1>;
reg-io-width = <2>;
nxp,tx-output-config = <0x06>;
nxp,external-clock-frequency = <24000000>;
};
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/r9a06g032-sysctrl.h>
can@52104000 {
compatible = "renesas,r9a06g032-sja1000", "renesas,rzn1-sja1000";
reg = <0x52104000 0x800>;
reg-io-width = <4>;
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sysctrl R9A06G032_HCLK_CAN0>;
};
Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
Required properties:
- compatible : should be one of "nxp,sja1000", "technologic,sja1000".
- reg : should specify the chip select, address offset and size required
to map the registers of the SJA1000. The size is usually 0x80.
- interrupts: property with a value describing the interrupt source
(number and sensitivity) required for the SJA1000.
Optional properties:
- reg-io-width : Specify the size (in bytes) of the IO accesses that
should be performed on the device. Valid value is 1, 2 or 4.
This property is ignored for technologic version.
Default to 1 (8 bits).
- nxp,external-clock-frequency : Frequency of the external oscillator
clock in Hz. Note that the internal clock frequency used by the
SJA1000 is half of that value. If not specified, a default value
of 16000000 (16 MHz) is used.
- nxp,tx-output-mode : operation mode of the TX output control logic:
<0x0> : bi-phase output mode
<0x1> : normal output mode (default)
<0x2> : test output mode
<0x3> : clock output mode
- nxp,tx-output-config : TX output pin configuration:
<0x01> : TX0 invert
<0x02> : TX0 pull-down (default)
<0x04> : TX0 pull-up
<0x06> : TX0 push-pull
<0x08> : TX1 invert
<0x10> : TX1 pull-down
<0x20> : TX1 pull-up
<0x30> : TX1 push-pull
- nxp,clock-out-frequency : clock frequency in Hz on the CLKOUT pin.
If not specified or if the specified value is 0, the CLKOUT pin
will be disabled.
- nxp,no-comparator-bypass : Allows to disable the CAN input comparator.
For further information, please have a look to the SJA1000 data sheet.
Examples:
can@3,100 {
compatible = "nxp,sja1000";
reg = <3 0x100 0x80>;
interrupts = <2 0>;
interrupt-parent = <&mpic>;
nxp,external-clock-frequency = <16000000>;
};
...@@ -952,15 +952,14 @@ static int c_can_handle_state_change(struct net_device *dev, ...@@ -952,15 +952,14 @@ static int c_can_handle_state_change(struct net_device *dev,
switch (error_type) { switch (error_type) {
case C_CAN_NO_ERROR: case C_CAN_NO_ERROR:
/* error warning state */ cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = CAN_ERR_CRTL_ACTIVE; cf->data[1] = CAN_ERR_CRTL_ACTIVE;
cf->data[6] = bec.txerr; cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr; cf->data[7] = bec.rxerr;
break; break;
case C_CAN_ERROR_WARNING: case C_CAN_ERROR_WARNING:
/* error warning state */ /* error warning state */
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (bec.txerr > bec.rxerr) ? cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING : CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING; CAN_ERR_CRTL_RX_WARNING;
...@@ -970,7 +969,7 @@ static int c_can_handle_state_change(struct net_device *dev, ...@@ -970,7 +969,7 @@ static int c_can_handle_state_change(struct net_device *dev,
break; break;
case C_CAN_ERROR_PASSIVE: case C_CAN_ERROR_PASSIVE:
/* error passive state */ /* error passive state */
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
if (rx_err_passive) if (rx_err_passive)
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
if (bec.txerr > 127) if (bec.txerr > 127)
......
...@@ -512,6 +512,7 @@ static int cc770_err(struct net_device *dev, u8 status) ...@@ -512,6 +512,7 @@ static int cc770_err(struct net_device *dev, u8 status)
/* Use extended functions of the CC770 */ /* Use extended functions of the CC770 */
if (priv->control_normal_mode & CTRL_EAF) { if (priv->control_normal_mode & CTRL_EAF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = cc770_read_reg(priv, tx_error_counter); cf->data[6] = cc770_read_reg(priv, tx_error_counter);
cf->data[7] = cc770_read_reg(priv, rx_error_counter); cf->data[7] = cc770_read_reg(priv, rx_error_counter);
} }
......
...@@ -847,7 +847,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr) ...@@ -847,7 +847,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
case CAN_STATE_ERROR_PASSIVE: case CAN_STATE_ERROR_PASSIVE:
priv->can.can_stats.error_passive++; priv->can.can_stats.error_passive++;
if (skb) { if (skb) {
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (bec.rxerr > 127) ? cf->data[1] = (bec.rxerr > 127) ?
CAN_ERR_CRTL_RX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE :
CAN_ERR_CRTL_TX_PASSIVE; CAN_ERR_CRTL_TX_PASSIVE;
...@@ -858,7 +858,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr) ...@@ -858,7 +858,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
case CAN_STATE_ERROR_WARNING: case CAN_STATE_ERROR_WARNING:
priv->can.can_stats.error_warning++; priv->can.can_stats.error_warning++;
if (skb) { if (skb) {
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] |= (bec.txerr > bec.rxerr) ? cf->data[1] |= (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING : CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING; CAN_ERR_CRTL_RX_WARNING;
...@@ -867,6 +867,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr) ...@@ -867,6 +867,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
} }
break; break;
case CAN_STATE_ERROR_ACTIVE: case CAN_STATE_ERROR_ACTIVE:
cf->can_id |= CAN_ERR_CNT;
cf->data[1] = CAN_ERR_CRTL_ACTIVE; cf->data[1] = CAN_ERR_CRTL_ACTIVE;
cf->data[6] = bec.txerr; cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr; cf->data[7] = bec.rxerr;
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
* CTU CAN FD IP Core * CTU CAN FD IP Core
* *
* Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU * Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU
* Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded * Copyright (C) 2018-2022 Ondrej Ille <ondrej.ille@gmail.com> self-funded
* Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU * Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU
* Copyright (C) 2018-2021 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded * Copyright (C) 2018-2022 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded
* *
* Project advisors: * Project advisors:
* Jiri Novak <jnovak@fel.cvut.cz> * Jiri Novak <jnovak@fel.cvut.cz>
...@@ -64,9 +64,12 @@ enum ctu_can_fd_can_registers { ...@@ -64,9 +64,12 @@ enum ctu_can_fd_can_registers {
CTUCANFD_RX_DATA = 0x6c, CTUCANFD_RX_DATA = 0x6c,
CTUCANFD_TX_STATUS = 0x70, CTUCANFD_TX_STATUS = 0x70,
CTUCANFD_TX_COMMAND = 0x74, CTUCANFD_TX_COMMAND = 0x74,
CTUCANFD_TXTB_INFO = 0x76,
CTUCANFD_TX_PRIORITY = 0x78, CTUCANFD_TX_PRIORITY = 0x78,
CTUCANFD_ERR_CAPT = 0x7c, CTUCANFD_ERR_CAPT = 0x7c,
CTUCANFD_RETR_CTR = 0x7d,
CTUCANFD_ALC = 0x7e, CTUCANFD_ALC = 0x7e,
CTUCANFD_TS_INFO = 0x7f,
CTUCANFD_TRV_DELAY = 0x80, CTUCANFD_TRV_DELAY = 0x80,
CTUCANFD_SSP_CFG = 0x82, CTUCANFD_SSP_CFG = 0x82,
CTUCANFD_RX_FR_CTR = 0x84, CTUCANFD_RX_FR_CTR = 0x84,
...@@ -102,8 +105,12 @@ enum ctu_can_fd_can_registers { ...@@ -102,8 +105,12 @@ enum ctu_can_fd_can_registers {
#define REG_MODE_STM BIT(2) #define REG_MODE_STM BIT(2)
#define REG_MODE_AFM BIT(3) #define REG_MODE_AFM BIT(3)
#define REG_MODE_FDE BIT(4) #define REG_MODE_FDE BIT(4)
#define REG_MODE_TTTM BIT(5)
#define REG_MODE_ROM BIT(6)
#define REG_MODE_ACF BIT(7) #define REG_MODE_ACF BIT(7)
#define REG_MODE_TSTM BIT(8) #define REG_MODE_TSTM BIT(8)
#define REG_MODE_RXBAM BIT(9)
#define REG_MODE_SAM BIT(11)
#define REG_MODE_RTRLE BIT(16) #define REG_MODE_RTRLE BIT(16)
#define REG_MODE_RTRTH GENMASK(20, 17) #define REG_MODE_RTRTH GENMASK(20, 17)
#define REG_MODE_ILBP BIT(21) #define REG_MODE_ILBP BIT(21)
...@@ -123,8 +130,10 @@ enum ctu_can_fd_can_registers { ...@@ -123,8 +130,10 @@ enum ctu_can_fd_can_registers {
#define REG_STATUS_EWL BIT(6) #define REG_STATUS_EWL BIT(6)
#define REG_STATUS_IDLE BIT(7) #define REG_STATUS_IDLE BIT(7)
#define REG_STATUS_PEXS BIT(8) #define REG_STATUS_PEXS BIT(8)
#define REG_STATUS_STCNT BIT(16)
/* COMMAND registers */ /* COMMAND registers */
#define REG_COMMAND_RXRPMV BIT(1)
#define REG_COMMAND_RRB BIT(2) #define REG_COMMAND_RRB BIT(2)
#define REG_COMMAND_CDO BIT(3) #define REG_COMMAND_CDO BIT(3)
#define REG_COMMAND_ERCRST BIT(4) #define REG_COMMAND_ERCRST BIT(4)
...@@ -263,8 +272,12 @@ enum ctu_can_fd_can_registers { ...@@ -263,8 +272,12 @@ enum ctu_can_fd_can_registers {
#define REG_TX_STATUS_TX2S GENMASK(7, 4) #define REG_TX_STATUS_TX2S GENMASK(7, 4)
#define REG_TX_STATUS_TX3S GENMASK(11, 8) #define REG_TX_STATUS_TX3S GENMASK(11, 8)
#define REG_TX_STATUS_TX4S GENMASK(15, 12) #define REG_TX_STATUS_TX4S GENMASK(15, 12)
#define REG_TX_STATUS_TX5S GENMASK(19, 16)
#define REG_TX_STATUS_TX6S GENMASK(23, 20)
#define REG_TX_STATUS_TX7S GENMASK(27, 24)
#define REG_TX_STATUS_TX8S GENMASK(31, 28)
/* TX_COMMAND registers */ /* TX_COMMAND TXTB_INFO registers */
#define REG_TX_COMMAND_TXCE BIT(0) #define REG_TX_COMMAND_TXCE BIT(0)
#define REG_TX_COMMAND_TXCR BIT(1) #define REG_TX_COMMAND_TXCR BIT(1)
#define REG_TX_COMMAND_TXCA BIT(2) #define REG_TX_COMMAND_TXCA BIT(2)
...@@ -272,18 +285,29 @@ enum ctu_can_fd_can_registers { ...@@ -272,18 +285,29 @@ enum ctu_can_fd_can_registers {
#define REG_TX_COMMAND_TXB2 BIT(9) #define REG_TX_COMMAND_TXB2 BIT(9)
#define REG_TX_COMMAND_TXB3 BIT(10) #define REG_TX_COMMAND_TXB3 BIT(10)
#define REG_TX_COMMAND_TXB4 BIT(11) #define REG_TX_COMMAND_TXB4 BIT(11)
#define REG_TX_COMMAND_TXB5 BIT(12)
#define REG_TX_COMMAND_TXB6 BIT(13)
#define REG_TX_COMMAND_TXB7 BIT(14)
#define REG_TX_COMMAND_TXB8 BIT(15)
#define REG_TX_COMMAND_TXT_BUFFER_COUNT GENMASK(19, 16)
/* TX_PRIORITY registers */ /* TX_PRIORITY registers */
#define REG_TX_PRIORITY_TXT1P GENMASK(2, 0) #define REG_TX_PRIORITY_TXT1P GENMASK(2, 0)
#define REG_TX_PRIORITY_TXT2P GENMASK(6, 4) #define REG_TX_PRIORITY_TXT2P GENMASK(6, 4)
#define REG_TX_PRIORITY_TXT3P GENMASK(10, 8) #define REG_TX_PRIORITY_TXT3P GENMASK(10, 8)
#define REG_TX_PRIORITY_TXT4P GENMASK(14, 12) #define REG_TX_PRIORITY_TXT4P GENMASK(14, 12)
#define REG_TX_PRIORITY_TXT5P GENMASK(18, 16)
#define REG_TX_PRIORITY_TXT6P GENMASK(22, 20)
#define REG_TX_PRIORITY_TXT7P GENMASK(26, 24)
#define REG_TX_PRIORITY_TXT8P GENMASK(30, 28)
/* ERR_CAPT ALC registers */ /* ERR_CAPT RETR_CTR ALC TS_INFO registers */
#define REG_ERR_CAPT_ERR_POS GENMASK(4, 0) #define REG_ERR_CAPT_ERR_POS GENMASK(4, 0)
#define REG_ERR_CAPT_ERR_TYPE GENMASK(7, 5) #define REG_ERR_CAPT_ERR_TYPE GENMASK(7, 5)
#define REG_ERR_CAPT_RETR_CTR_VAL GENMASK(11, 8)
#define REG_ERR_CAPT_ALC_BIT GENMASK(20, 16) #define REG_ERR_CAPT_ALC_BIT GENMASK(20, 16)
#define REG_ERR_CAPT_ALC_ID_FIELD GENMASK(23, 21) #define REG_ERR_CAPT_ALC_ID_FIELD GENMASK(23, 21)
#define REG_ERR_CAPT_TS_BITS GENMASK(29, 24)
/* TRV_DELAY SSP_CFG registers */ /* TRV_DELAY SSP_CFG registers */
#define REG_TRV_DELAY_TRV_DELAY_VALUE GENMASK(6, 0) #define REG_TRV_DELAY_TRV_DELAY_VALUE GENMASK(6, 0)
......
...@@ -671,6 +671,7 @@ static void grcan_err(struct net_device *dev, u32 sources, u32 status) ...@@ -671,6 +671,7 @@ static void grcan_err(struct net_device *dev, u32 sources, u32 status)
/* There are no others at this point */ /* There are no others at this point */
break; break;
} }
cf.can_id |= CAN_ERR_CNT;
cf.data[6] = txerr; cf.data[6] = txerr;
cf.data[7] = rxerr; cf.data[7] = rxerr;
priv->can.state = state; priv->can.state = state;
......
...@@ -492,7 +492,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, ...@@ -492,7 +492,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
switch (new_state) { switch (new_state) {
case CAN_STATE_ERROR_WARNING: case CAN_STATE_ERROR_WARNING:
/* error warning state */ /* error warning state */
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (bec.txerr > bec.rxerr) ? cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING : CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING; CAN_ERR_CRTL_RX_WARNING;
...@@ -501,7 +501,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, ...@@ -501,7 +501,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
break; break;
case CAN_STATE_ERROR_PASSIVE: case CAN_STATE_ERROR_PASSIVE:
/* error passive state */ /* error passive state */
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
if (bec.txerr > 127) if (bec.txerr > 127)
cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
......
...@@ -1127,7 +1127,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) ...@@ -1127,7 +1127,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg)
/* bus error interrupt */ /* bus error interrupt */
if (isrc == CEVTIND_BEI) { if (isrc == CEVTIND_BEI) {
mod->can.can_stats.bus_error++; mod->can.can_stats.bus_error++;
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
switch (ecc & ECC_MASK) { switch (ecc & ECC_MASK) {
case ECC_BIT: case ECC_BIT:
...@@ -1153,7 +1153,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) ...@@ -1153,7 +1153,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg)
if (state != mod->can.state && (state == CAN_STATE_ERROR_WARNING || if (state != mod->can.state && (state == CAN_STATE_ERROR_WARNING ||
state == CAN_STATE_ERROR_PASSIVE)) { state == CAN_STATE_ERROR_PASSIVE)) {
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
if (state == CAN_STATE_ERROR_WARNING) { if (state == CAN_STATE_ERROR_WARNING) {
mod->can.can_stats.error_warning++; mod->can.can_stats.error_warning++;
cf->data[1] = (txerr > rxerr) ? cf->data[1] = (txerr > rxerr) ?
......
...@@ -1306,7 +1306,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can, ...@@ -1306,7 +1306,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
shhwtstamps->hwtstamp = shhwtstamps->hwtstamp =
ns_to_ktime(div_u64(p->timestamp * 1000, ns_to_ktime(div_u64(p->timestamp * 1000,
can->kv_pcie->freq_to_ticks_div)); can->kv_pcie->freq_to_ticks_div));
cf->can_id |= CAN_ERR_BUSERROR; cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
cf->data[6] = bec.txerr; cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr; cf->data[7] = bec.rxerr;
......
...@@ -741,7 +741,7 @@ static int m_can_handle_state_change(struct net_device *dev, ...@@ -741,7 +741,7 @@ static int m_can_handle_state_change(struct net_device *dev,
switch (new_state) { switch (new_state) {
case CAN_STATE_ERROR_WARNING: case CAN_STATE_ERROR_WARNING:
/* error warning state */ /* error warning state */
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (bec.txerr > bec.rxerr) ? cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING : CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING; CAN_ERR_CRTL_RX_WARNING;
...@@ -750,7 +750,7 @@ static int m_can_handle_state_change(struct net_device *dev, ...@@ -750,7 +750,7 @@ static int m_can_handle_state_change(struct net_device *dev,
break; break;
case CAN_STATE_ERROR_PASSIVE: case CAN_STATE_ERROR_PASSIVE:
/* error passive state */ /* error passive state */
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
ecr = m_can_read(cdev, M_CAN_ECR); ecr = m_can_read(cdev, M_CAN_ECR);
if (ecr & ECR_RP) if (ecr & ECR_RP)
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
......
...@@ -496,6 +496,10 @@ static void pch_can_error(struct net_device *ndev, u32 status) ...@@ -496,6 +496,10 @@ static void pch_can_error(struct net_device *ndev, u32 status)
cf->can_id |= CAN_ERR_BUSOFF; cf->can_id |= CAN_ERR_BUSOFF;
priv->can.can_stats.bus_off++; priv->can.can_stats.bus_off++;
can_bus_off(ndev); can_bus_off(ndev);
} else {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = errc & PCH_TEC;
cf->data[7] = (errc & PCH_REC) >> 8;
} }
errc = ioread32(&priv->regs->errc); errc = ioread32(&priv->regs->errc);
...@@ -556,9 +560,6 @@ static void pch_can_error(struct net_device *ndev, u32 status) ...@@ -556,9 +560,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
break; break;
} }
cf->data[6] = errc & PCH_TEC;
cf->data[7] = (errc & PCH_REC) >> 8;
priv->can.state = state; priv->can.state = state;
netif_receive_skb(skb); netif_receive_skb(skb);
} }
......
...@@ -373,7 +373,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv, ...@@ -373,7 +373,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
priv->can.state = CAN_STATE_ERROR_PASSIVE; priv->can.state = CAN_STATE_ERROR_PASSIVE;
priv->can.can_stats.error_passive++; priv->can.can_stats.error_passive++;
if (skb) { if (skb) {
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (priv->bec.txerr > priv->bec.rxerr) ? cf->data[1] = (priv->bec.txerr > priv->bec.rxerr) ?
CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_TX_PASSIVE :
CAN_ERR_CRTL_RX_PASSIVE; CAN_ERR_CRTL_RX_PASSIVE;
...@@ -386,7 +386,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv, ...@@ -386,7 +386,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
priv->can.state = CAN_STATE_ERROR_WARNING; priv->can.state = CAN_STATE_ERROR_WARNING;
priv->can.can_stats.error_warning++; priv->can.can_stats.error_warning++;
if (skb) { if (skb) {
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (priv->bec.txerr > priv->bec.rxerr) ? cf->data[1] = (priv->bec.txerr > priv->bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING : CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING; CAN_ERR_CRTL_RX_WARNING;
...@@ -430,7 +430,7 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv) ...@@ -430,7 +430,7 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv)
return -ENOMEM; return -ENOMEM;
} }
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
cf->data[6] = priv->bec.txerr; cf->data[6] = priv->bec.txerr;
......
...@@ -232,11 +232,8 @@ static void rcar_can_error(struct net_device *ndev) ...@@ -232,11 +232,8 @@ static void rcar_can_error(struct net_device *ndev)
if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) { if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) {
txerr = readb(&priv->regs->tecr); txerr = readb(&priv->regs->tecr);
rxerr = readb(&priv->regs->recr); rxerr = readb(&priv->regs->recr);
if (skb) { if (skb)
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
} }
if (eifr & RCAR_CAN_EIFR_BEIF) { if (eifr & RCAR_CAN_EIFR_BEIF) {
int rx_errors = 0, tx_errors = 0; int rx_errors = 0, tx_errors = 0;
...@@ -336,6 +333,10 @@ static void rcar_can_error(struct net_device *ndev) ...@@ -336,6 +333,10 @@ static void rcar_can_error(struct net_device *ndev)
can_bus_off(ndev); can_bus_off(ndev);
if (skb) if (skb)
cf->can_id |= CAN_ERR_BUSOFF; cf->can_id |= CAN_ERR_BUSOFF;
} else if (skb) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
} }
if (eifr & RCAR_CAN_EIFR_ORIF) { if (eifr & RCAR_CAN_EIFR_ORIF) {
netdev_dbg(priv->ndev, "Receive overrun error interrupt\n"); netdev_dbg(priv->ndev, "Receive overrun error interrupt\n");
......
...@@ -1052,7 +1052,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl, ...@@ -1052,7 +1052,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
netdev_dbg(ndev, "Error warning interrupt\n"); netdev_dbg(ndev, "Error warning interrupt\n");
priv->can.state = CAN_STATE_ERROR_WARNING; priv->can.state = CAN_STATE_ERROR_WARNING;
priv->can.can_stats.error_warning++; priv->can.can_stats.error_warning++;
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_WARNING : cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING; CAN_ERR_CRTL_RX_WARNING;
cf->data[6] = txerr; cf->data[6] = txerr;
...@@ -1062,7 +1062,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl, ...@@ -1062,7 +1062,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
netdev_dbg(ndev, "Error passive interrupt\n"); netdev_dbg(ndev, "Error passive interrupt\n");
priv->can.state = CAN_STATE_ERROR_PASSIVE; priv->can.state = CAN_STATE_ERROR_PASSIVE;
priv->can.can_stats.error_passive++; priv->can.can_stats.error_passive++;
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_PASSIVE : cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_PASSIVE :
CAN_ERR_CRTL_RX_PASSIVE; CAN_ERR_CRTL_RX_PASSIVE;
cf->data[6] = txerr; cf->data[6] = txerr;
......
...@@ -183,8 +183,9 @@ static void chipset_init(struct net_device *dev) ...@@ -183,8 +183,9 @@ static void chipset_init(struct net_device *dev)
{ {
struct sja1000_priv *priv = netdev_priv(dev); struct sja1000_priv *priv = netdev_priv(dev);
/* set clock divider and output control register */ if (!(priv->flags & SJA1000_QUIRK_NO_CDR_REG))
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN); /* set clock divider and output control register */
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
/* set acceptance filter (accept all) */ /* set acceptance filter (accept all) */
priv->write_reg(priv, SJA1000_ACCC0, 0x00); priv->write_reg(priv, SJA1000_ACCC0, 0x00);
...@@ -209,7 +210,8 @@ static void sja1000_start(struct net_device *dev) ...@@ -209,7 +210,8 @@ static void sja1000_start(struct net_device *dev)
set_reset_mode(dev); set_reset_mode(dev);
/* Initialize chip if uninitialized at this stage */ /* Initialize chip if uninitialized at this stage */
if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN)) if (!(priv->flags & SJA1000_QUIRK_NO_CDR_REG ||
priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN))
chipset_init(dev); chipset_init(dev);
/* Clear error counters and error code capture */ /* Clear error counters and error code capture */
...@@ -402,9 +404,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) ...@@ -402,9 +404,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
txerr = priv->read_reg(priv, SJA1000_TXERR); txerr = priv->read_reg(priv, SJA1000_TXERR);
rxerr = priv->read_reg(priv, SJA1000_RXERR); rxerr = priv->read_reg(priv, SJA1000_RXERR);
cf->data[6] = txerr;
cf->data[7] = rxerr;
if (isrc & IRQ_DOI) { if (isrc & IRQ_DOI) {
/* data overrun interrupt */ /* data overrun interrupt */
netdev_dbg(dev, "data overrun interrupt\n"); netdev_dbg(dev, "data overrun interrupt\n");
...@@ -426,6 +425,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) ...@@ -426,6 +425,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
else else
state = CAN_STATE_ERROR_ACTIVE; state = CAN_STATE_ERROR_ACTIVE;
} }
if (state != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
if (isrc & IRQ_BEI) { if (isrc & IRQ_BEI) {
/* bus error interrupt */ /* bus error interrupt */
priv->can.can_stats.bus_error++; priv->can.can_stats.bus_error++;
......
...@@ -145,7 +145,8 @@ ...@@ -145,7 +145,8 @@
/* /*
* Flags for sja1000priv.flags * Flags for sja1000priv.flags
*/ */
#define SJA1000_CUSTOM_IRQ_HANDLER 0x1 #define SJA1000_CUSTOM_IRQ_HANDLER BIT(0)
#define SJA1000_QUIRK_NO_CDR_REG BIT(1)
/* /*
* SJA1000 private data structure * SJA1000 private data structure
......
...@@ -31,7 +31,7 @@ MODULE_LICENSE("GPL v2"); ...@@ -31,7 +31,7 @@ MODULE_LICENSE("GPL v2");
struct sja1000_of_data { struct sja1000_of_data {
size_t priv_sz; size_t priv_sz;
int (*init)(struct sja1000_priv *priv, struct device_node *of); void (*init)(struct sja1000_priv *priv, struct device_node *of);
}; };
struct technologic_priv { struct technologic_priv {
...@@ -94,15 +94,13 @@ static void sp_technologic_write_reg16(const struct sja1000_priv *priv, ...@@ -94,15 +94,13 @@ static void sp_technologic_write_reg16(const struct sja1000_priv *priv,
spin_unlock_irqrestore(&tp->io_lock, flags); spin_unlock_irqrestore(&tp->io_lock, flags);
} }
static int sp_technologic_init(struct sja1000_priv *priv, struct device_node *of) static void sp_technologic_init(struct sja1000_priv *priv, struct device_node *of)
{ {
struct technologic_priv *tp = priv->priv; struct technologic_priv *tp = priv->priv;
priv->read_reg = sp_technologic_read_reg16; priv->read_reg = sp_technologic_read_reg16;
priv->write_reg = sp_technologic_write_reg16; priv->write_reg = sp_technologic_write_reg16;
spin_lock_init(&tp->io_lock); spin_lock_init(&tp->io_lock);
return 0;
} }
static void sp_populate(struct sja1000_priv *priv, static void sp_populate(struct sja1000_priv *priv,
...@@ -210,7 +208,6 @@ static int sp_probe(struct platform_device *pdev) ...@@ -210,7 +208,6 @@ static int sp_probe(struct platform_device *pdev)
struct resource *res_mem, *res_irq = NULL; struct resource *res_mem, *res_irq = NULL;
struct sja1000_platform_data *pdata; struct sja1000_platform_data *pdata;
struct device_node *of = pdev->dev.of_node; struct device_node *of = pdev->dev.of_node;
const struct of_device_id *of_id;
const struct sja1000_of_data *of_data = NULL; const struct sja1000_of_data *of_data = NULL;
size_t priv_sz = 0; size_t priv_sz = 0;
...@@ -243,11 +240,9 @@ static int sp_probe(struct platform_device *pdev) ...@@ -243,11 +240,9 @@ static int sp_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
of_id = of_match_device(sp_of_table, &pdev->dev); of_data = device_get_match_data(&pdev->dev);
if (of_id && of_id->data) { if (of_data)
of_data = of_id->data;
priv_sz = of_data->priv_sz; priv_sz = of_data->priv_sz;
}
dev = alloc_sja1000dev(priv_sz); dev = alloc_sja1000dev(priv_sz);
if (!dev) if (!dev)
...@@ -269,11 +264,8 @@ static int sp_probe(struct platform_device *pdev) ...@@ -269,11 +264,8 @@ static int sp_probe(struct platform_device *pdev)
if (of) { if (of) {
sp_populate_of(priv, of); sp_populate_of(priv, of);
if (of_data && of_data->init) { if (of_data && of_data->init)
err = of_data->init(priv, of); of_data->init(priv, of);
if (err)
goto exit_free;
}
} else { } else {
sp_populate(priv, pdata, res_mem->flags); sp_populate(priv, pdata, res_mem->flags);
} }
......
This diff is collapsed.
...@@ -667,8 +667,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) ...@@ -667,8 +667,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
txerr = hi3110_read(spi, HI3110_READ_TEC); txerr = hi3110_read(spi, HI3110_READ_TEC);
rxerr = hi3110_read(spi, HI3110_READ_REC); rxerr = hi3110_read(spi, HI3110_READ_REC);
cf->data[6] = txerr;
cf->data[7] = rxerr;
tx_state = txerr >= rxerr ? new_state : 0; tx_state = txerr >= rxerr ? new_state : 0;
rx_state = txerr <= rxerr ? new_state : 0; rx_state = txerr <= rxerr ? new_state : 0;
can_change_state(net, cf, tx_state, rx_state); can_change_state(net, cf, tx_state, rx_state);
...@@ -681,6 +679,10 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) ...@@ -681,6 +679,10 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
hi3110_hw_sleep(spi); hi3110_hw_sleep(spi);
break; break;
} }
} else {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
} }
} }
......
...@@ -1099,6 +1099,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) ...@@ -1099,6 +1099,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv)
err = mcp251xfd_get_berr_counter(priv->ndev, &bec); err = mcp251xfd_get_berr_counter(priv->ndev, &bec);
if (err) if (err)
return err; return err;
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = bec.txerr; cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr; cf->data[7] = bec.rxerr;
} }
......
...@@ -535,11 +535,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) ...@@ -535,11 +535,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
rxerr = (errc >> 16) & 0xFF; rxerr = (errc >> 16) & 0xFF;
txerr = errc & 0xFF; txerr = errc & 0xFF;
if (skb) {
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
if (isrc & SUN4I_INT_DATA_OR) { if (isrc & SUN4I_INT_DATA_OR) {
/* data overrun interrupt */ /* data overrun interrupt */
netdev_dbg(dev, "data overrun interrupt\n"); netdev_dbg(dev, "data overrun interrupt\n");
...@@ -570,6 +565,11 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) ...@@ -570,6 +565,11 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
else else
state = CAN_STATE_ERROR_ACTIVE; state = CAN_STATE_ERROR_ACTIVE;
} }
if (skb && state != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
if (isrc & SUN4I_INT_BUS_ERR) { if (isrc & SUN4I_INT_BUS_ERR) {
/* bus error interrupt */ /* bus error interrupt */
netdev_dbg(dev, "bus error interrupt\n"); netdev_dbg(dev, "bus error interrupt\n");
......
...@@ -662,6 +662,7 @@ static void ti_hecc_change_state(struct net_device *ndev, ...@@ -662,6 +662,7 @@ static void ti_hecc_change_state(struct net_device *ndev,
can_change_state(priv->ndev, cf, tx_state, rx_state); can_change_state(priv->ndev, cf, tx_state, rx_state);
if (max(tx_state, rx_state) != CAN_STATE_BUS_OFF) { if (max(tx_state, rx_state) != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = hecc_read(priv, HECC_CANTEC); cf->data[6] = hecc_read(priv, HECC_CANTEC);
cf->data[7] = hecc_read(priv, HECC_CANREC); cf->data[7] = hecc_read(priv, HECC_CANREC);
} }
......
...@@ -265,7 +265,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv, ...@@ -265,7 +265,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
priv->can.can_stats.bus_error++; priv->can.can_stats.bus_error++;
stats->rx_errors++; stats->rx_errors++;
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR |
CAN_ERR_CNT;
switch (ecc & SJA1000_ECC_MASK) { switch (ecc & SJA1000_ECC_MASK) {
case SJA1000_ECC_BIT: case SJA1000_ECC_BIT:
......
...@@ -917,8 +917,11 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv, ...@@ -917,8 +917,11 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
new_state < CAN_STATE_BUS_OFF) new_state < CAN_STATE_BUS_OFF)
priv->can.can_stats.restarts++; priv->can.can_stats.restarts++;
cf->data[6] = bec->txerr; if (new_state != CAN_STATE_BUS_OFF) {
cf->data[7] = bec->rxerr; cf->can_id |= CAN_ERR_CNT;
cf->data[6] = bec->txerr;
cf->data[7] = bec->rxerr;
}
netif_rx(skb); netif_rx(skb);
} }
...@@ -1069,8 +1072,11 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv, ...@@ -1069,8 +1072,11 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
shhwtstamps->hwtstamp = hwtstamp; shhwtstamps->hwtstamp = hwtstamp;
cf->can_id |= CAN_ERR_BUSERROR; cf->can_id |= CAN_ERR_BUSERROR;
cf->data[6] = bec.txerr; if (new_state != CAN_STATE_BUS_OFF) {
cf->data[7] = bec.rxerr; cf->can_id |= CAN_ERR_CNT;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
}
netif_rx(skb); netif_rx(skb);
......
...@@ -853,8 +853,11 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, ...@@ -853,8 +853,11 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
break; break;
} }
cf->data[6] = es->txerr; if (new_state != CAN_STATE_BUS_OFF) {
cf->data[7] = es->rxerr; cf->can_id |= CAN_ERR_CNT;
cf->data[6] = es->txerr;
cf->data[7] = es->rxerr;
}
netif_rx(skb); netif_rx(skb);
} }
......
...@@ -506,6 +506,7 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, ...@@ -506,6 +506,7 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
/* Supply TX/RX error counters in case of /* Supply TX/RX error counters in case of
* controller error. * controller error.
*/ */
cf->can_id = CAN_ERR_CNT;
cf->data[6] = mc->pdev->bec.txerr; cf->data[6] = mc->pdev->bec.txerr;
cf->data[7] = mc->pdev->bec.rxerr; cf->data[7] = mc->pdev->bec.rxerr;
} }
......
...@@ -57,7 +57,7 @@ MODULE_DEVICE_TABLE(usb, peak_usb_table); ...@@ -57,7 +57,7 @@ MODULE_DEVICE_TABLE(usb, peak_usb_table);
* dump memory * dump memory
*/ */
#define DUMP_WIDTH 16 #define DUMP_WIDTH 16
void pcan_dump_mem(char *prompt, void *p, int l) void pcan_dump_mem(const char *prompt, const void *p, int l)
{ {
pr_info("%s dumping %s (%d bytes):\n", pr_info("%s dumping %s (%d bytes):\n",
PCAN_USB_DRIVER_NAME, prompt ? prompt : "memory", l); PCAN_USB_DRIVER_NAME, prompt ? prompt : "memory", l);
......
...@@ -132,7 +132,7 @@ struct peak_usb_device { ...@@ -132,7 +132,7 @@ struct peak_usb_device {
struct peak_usb_device *next_siblings; struct peak_usb_device *next_siblings;
}; };
void pcan_dump_mem(char *prompt, void *p, int l); void pcan_dump_mem(const char *prompt, const void *p, int l);
/* common timestamp management */ /* common timestamp management */
void peak_usb_init_time_ref(struct peak_time_ref *time_ref, void peak_usb_init_time_ref(struct peak_time_ref *time_ref,
......
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
#define PCAN_UFD_RX_BUFFER_SIZE 2048 #define PCAN_UFD_RX_BUFFER_SIZE 2048
#define PCAN_UFD_TX_BUFFER_SIZE 512 #define PCAN_UFD_TX_BUFFER_SIZE 512
/* struct pcan_ufd_fw_info::type */
#define PCAN_USBFD_TYPE_STD 1
#define PCAN_USBFD_TYPE_EXT 2 /* includes EP numbers */
/* read some versions info from the hw device */ /* read some versions info from the hw device */
struct __packed pcan_ufd_fw_info { struct __packed pcan_ufd_fw_info {
__le16 size_of; /* sizeof this */ __le16 size_of; /* sizeof this */
...@@ -44,6 +48,13 @@ struct __packed pcan_ufd_fw_info { ...@@ -44,6 +48,13 @@ struct __packed pcan_ufd_fw_info {
__le32 dev_id[2]; /* "device id" per CAN */ __le32 dev_id[2]; /* "device id" per CAN */
__le32 ser_no; /* S/N */ __le32 ser_no; /* S/N */
__le32 flags; /* special functions */ __le32 flags; /* special functions */
/* extended data when type == PCAN_USBFD_TYPE_EXT */
u8 cmd_out_ep; /* ep for cmd */
u8 cmd_in_ep; /* ep for replies */
u8 data_out_ep[2]; /* ep for CANx TX */
u8 data_in_ep; /* ep for CAN RX */
u8 dummy[3];
}; };
/* handle device specific info used by the netdevices */ /* handle device specific info used by the netdevices */
...@@ -171,6 +182,9 @@ static inline void *pcan_usb_fd_cmd_buffer(struct peak_usb_device *dev) ...@@ -171,6 +182,9 @@ static inline void *pcan_usb_fd_cmd_buffer(struct peak_usb_device *dev)
/* send PCAN-USB Pro FD commands synchronously */ /* send PCAN-USB Pro FD commands synchronously */
static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail) static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
{ {
struct pcan_usb_fd_device *pdev =
container_of(dev, struct pcan_usb_fd_device, dev);
struct pcan_ufd_fw_info *fw_info = &pdev->usb_if->fw_info;
void *cmd_head = pcan_usb_fd_cmd_buffer(dev); void *cmd_head = pcan_usb_fd_cmd_buffer(dev);
int err = 0; int err = 0;
u8 *packet_ptr; u8 *packet_ptr;
...@@ -200,7 +214,7 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail) ...@@ -200,7 +214,7 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
do { do {
err = usb_bulk_msg(dev->udev, err = usb_bulk_msg(dev->udev,
usb_sndbulkpipe(dev->udev, usb_sndbulkpipe(dev->udev,
PCAN_USBPRO_EP_CMDOUT), fw_info->cmd_out_ep),
packet_ptr, packet_len, packet_ptr, packet_len,
NULL, PCAN_UFD_CMD_TIMEOUT_MS); NULL, PCAN_UFD_CMD_TIMEOUT_MS);
if (err) { if (err) {
...@@ -426,6 +440,9 @@ static int pcan_usb_fd_set_bittiming_fast(struct peak_usb_device *dev, ...@@ -426,6 +440,9 @@ static int pcan_usb_fd_set_bittiming_fast(struct peak_usb_device *dev,
static int pcan_usb_fd_restart_async(struct peak_usb_device *dev, static int pcan_usb_fd_restart_async(struct peak_usb_device *dev,
struct urb *urb, u8 *buf) struct urb *urb, u8 *buf)
{ {
struct pcan_usb_fd_device *pdev =
container_of(dev, struct pcan_usb_fd_device, dev);
struct pcan_ufd_fw_info *fw_info = &pdev->usb_if->fw_info;
u8 *pc = buf; u8 *pc = buf;
/* build the entire cmds list in the provided buffer, to go back into /* build the entire cmds list in the provided buffer, to go back into
...@@ -439,7 +456,7 @@ static int pcan_usb_fd_restart_async(struct peak_usb_device *dev, ...@@ -439,7 +456,7 @@ static int pcan_usb_fd_restart_async(struct peak_usb_device *dev,
/* complete the URB */ /* complete the URB */
usb_fill_bulk_urb(urb, dev->udev, usb_fill_bulk_urb(urb, dev->udev,
usb_sndbulkpipe(dev->udev, PCAN_USBPRO_EP_CMDOUT), usb_sndbulkpipe(dev->udev, fw_info->cmd_out_ep),
buf, pc - buf, buf, pc - buf,
pcan_usb_pro_restart_complete, dev); pcan_usb_pro_restart_complete, dev);
...@@ -839,6 +856,15 @@ static int pcan_usb_fd_get_berr_counter(const struct net_device *netdev, ...@@ -839,6 +856,15 @@ static int pcan_usb_fd_get_berr_counter(const struct net_device *netdev,
return 0; return 0;
} }
/* probe function for all PCAN-USB FD family usb interfaces */
static int pcan_usb_fd_probe(struct usb_interface *intf)
{
struct usb_host_interface *iface_desc = &intf->altsetting[0];
/* CAN interface is always interface #0 */
return iface_desc->desc.bInterfaceNumber;
}
/* stop interface (last chance before set bus off) */ /* stop interface (last chance before set bus off) */
static int pcan_usb_fd_stop(struct peak_usb_device *dev) static int pcan_usb_fd_stop(struct peak_usb_device *dev)
{ {
...@@ -860,6 +886,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) ...@@ -860,6 +886,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
{ {
struct pcan_usb_fd_device *pdev = struct pcan_usb_fd_device *pdev =
container_of(dev, struct pcan_usb_fd_device, dev); container_of(dev, struct pcan_usb_fd_device, dev);
struct pcan_ufd_fw_info *fw_info;
int i, err = -ENOMEM; int i, err = -ENOMEM;
/* do this for 1st channel only */ /* do this for 1st channel only */
...@@ -878,10 +905,12 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) ...@@ -878,10 +905,12 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
/* number of ts msgs to ignore before taking one into account */ /* number of ts msgs to ignore before taking one into account */
pdev->usb_if->cm_ignore_count = 5; pdev->usb_if->cm_ignore_count = 5;
fw_info = &pdev->usb_if->fw_info;
err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
PCAN_USBPRO_INFO_FW, PCAN_USBPRO_INFO_FW,
&pdev->usb_if->fw_info, fw_info,
sizeof(pdev->usb_if->fw_info)); sizeof(*fw_info));
if (err) { if (err) {
dev_err(dev->netdev->dev.parent, dev_err(dev->netdev->dev.parent,
"unable to read %s firmware info (err %d)\n", "unable to read %s firmware info (err %d)\n",
...@@ -895,14 +924,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) ...@@ -895,14 +924,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
*/ */
dev_info(dev->netdev->dev.parent, dev_info(dev->netdev->dev.parent,
"PEAK-System %s v%u fw v%u.%u.%u (%u channels)\n", "PEAK-System %s v%u fw v%u.%u.%u (%u channels)\n",
dev->adapter->name, pdev->usb_if->fw_info.hw_version, dev->adapter->name, fw_info->hw_version,
pdev->usb_if->fw_info.fw_version[0], fw_info->fw_version[0],
pdev->usb_if->fw_info.fw_version[1], fw_info->fw_version[1],
pdev->usb_if->fw_info.fw_version[2], fw_info->fw_version[2],
dev->adapter->ctrl_count); dev->adapter->ctrl_count);
/* check for ability to switch between ISO/non-ISO modes */ /* check for ability to switch between ISO/non-ISO modes */
if (pdev->usb_if->fw_info.fw_version[0] >= 2) { if (fw_info->fw_version[0] >= 2) {
/* firmware >= 2.x supports ISO/non-ISO switching */ /* firmware >= 2.x supports ISO/non-ISO switching */
dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO; dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO;
} else { } else {
...@@ -910,6 +939,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) ...@@ -910,6 +939,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
dev->can.ctrlmode |= CAN_CTRLMODE_FD_NON_ISO; dev->can.ctrlmode |= CAN_CTRLMODE_FD_NON_ISO;
} }
/* if vendor rsp is of type 2, then it contains EP numbers to
* use for cmds pipes. If not, then default EP should be used.
*/
if (fw_info->type != cpu_to_le16(PCAN_USBFD_TYPE_EXT)) {
fw_info->cmd_out_ep = PCAN_USBPRO_EP_CMDOUT;
fw_info->cmd_in_ep = PCAN_USBPRO_EP_CMDIN;
}
/* tell the hardware the can driver is running */ /* tell the hardware the can driver is running */
err = pcan_usb_fd_drv_loaded(dev, 1); err = pcan_usb_fd_drv_loaded(dev, 1);
if (err) { if (err) {
...@@ -930,12 +967,23 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) ...@@ -930,12 +967,23 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
/* do a copy of the ctrlmode[_supported] too */ /* do a copy of the ctrlmode[_supported] too */
dev->can.ctrlmode = ppdev->dev.can.ctrlmode; dev->can.ctrlmode = ppdev->dev.can.ctrlmode;
dev->can.ctrlmode_supported = ppdev->dev.can.ctrlmode_supported; dev->can.ctrlmode_supported = ppdev->dev.can.ctrlmode_supported;
fw_info = &pdev->usb_if->fw_info;
} }
pdev->usb_if->dev[dev->ctrl_idx] = dev; pdev->usb_if->dev[dev->ctrl_idx] = dev;
dev->device_number = dev->device_number =
le32_to_cpu(pdev->usb_if->fw_info.dev_id[dev->ctrl_idx]); le32_to_cpu(pdev->usb_if->fw_info.dev_id[dev->ctrl_idx]);
/* if vendor rsp is of type 2, then it contains EP numbers to
* use for data pipes. If not, then statically defined EP are used
* (see peak_usb_create_dev()).
*/
if (fw_info->type == cpu_to_le16(PCAN_USBFD_TYPE_EXT)) {
dev->ep_msg_in = fw_info->data_in_ep;
dev->ep_msg_out = fw_info->data_out_ep[dev->ctrl_idx];
}
/* set clock domain */ /* set clock domain */
for (i = 0; i < ARRAY_SIZE(pcan_usb_fd_clk_freq); i++) for (i = 0; i < ARRAY_SIZE(pcan_usb_fd_clk_freq); i++)
if (dev->adapter->clock.freq == pcan_usb_fd_clk_freq[i]) if (dev->adapter->clock.freq == pcan_usb_fd_clk_freq[i])
...@@ -1091,7 +1139,7 @@ const struct peak_usb_adapter pcan_usb_fd = { ...@@ -1091,7 +1139,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
.tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE, .tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE,
/* device callbacks */ /* device callbacks */
.intf_probe = pcan_usb_pro_probe, /* same as PCAN-USB Pro */ .intf_probe = pcan_usb_fd_probe,
.dev_init = pcan_usb_fd_init, .dev_init = pcan_usb_fd_init,
.dev_exit = pcan_usb_fd_exit, .dev_exit = pcan_usb_fd_exit,
......
...@@ -439,7 +439,7 @@ static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev, ...@@ -439,7 +439,7 @@ static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
return err; return err;
pdn = (struct pcan_usb_pro_devid *)pc; pdn = (struct pcan_usb_pro_devid *)pc;
*device_id = le32_to_cpu(pdn->serial_num); *device_id = le32_to_cpu(pdn->dev_num);
return err; return err;
} }
......
...@@ -112,7 +112,7 @@ struct __packed pcan_usb_pro_devid { ...@@ -112,7 +112,7 @@ struct __packed pcan_usb_pro_devid {
u8 data_type; u8 data_type;
u8 channel; u8 channel;
__le16 dummy; __le16 dummy;
__le32 serial_num; __le32 dev_num;
}; };
#define PCAN_USBPRO_LED_DEVICE 0x00 #define PCAN_USBPRO_LED_DEVICE 0x00
......
...@@ -438,9 +438,11 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv, ...@@ -438,9 +438,11 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
if (rx_errors) if (rx_errors)
stats->rx_errors++; stats->rx_errors++;
if (priv->can.state != CAN_STATE_BUS_OFF) {
cf->data[6] = txerr; cf->can_id |= CAN_ERR_CNT;
cf->data[7] = rxerr; cf->data[6] = txerr;
cf->data[7] = rxerr;
}
priv->bec.txerr = txerr; priv->bec.txerr = txerr;
priv->bec.rxerr = rxerr; priv->bec.rxerr = rxerr;
......
...@@ -965,6 +965,7 @@ static void xcan_set_error_state(struct net_device *ndev, ...@@ -965,6 +965,7 @@ static void xcan_set_error_state(struct net_device *ndev,
can_change_state(ndev, cf, tx_state, rx_state); can_change_state(ndev, cf, tx_state, rx_state);
if (cf) { if (cf) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr; cf->data[6] = txerr;
cf->data[7] = rxerr; cf->data[7] = rxerr;
} }
......
...@@ -57,6 +57,8 @@ ...@@ -57,6 +57,8 @@
#define CAN_ERR_BUSOFF 0x00000040U /* bus off */ #define CAN_ERR_BUSOFF 0x00000040U /* bus off */
#define CAN_ERR_BUSERROR 0x00000080U /* bus error (may flood!) */ #define CAN_ERR_BUSERROR 0x00000080U /* bus error (may flood!) */
#define CAN_ERR_RESTARTED 0x00000100U /* controller restarted */ #define CAN_ERR_RESTARTED 0x00000100U /* controller restarted */
#define CAN_ERR_CNT 0x00000200U /* TX error counter / data[6] */
/* RX error counter / data[7] */
/* arbitration lost in bit ... / data[0] */ /* arbitration lost in bit ... / data[0] */
#define CAN_ERR_LOSTARB_UNSPEC 0x00 /* unspecified */ #define CAN_ERR_LOSTARB_UNSPEC 0x00 /* unspecified */
...@@ -120,6 +122,22 @@ ...@@ -120,6 +122,22 @@
#define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70 /* 0111 0000 */ #define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70 /* 0111 0000 */
#define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */ #define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */
/* controller specific additional information / data[5..7] */ /* data[5] is reserved (do not use) */
/* TX error counter / data[6] */
/* RX error counter / data[7] */
/* CAN state thresholds
*
* Error counter Error state
* -----------------------------------
* 0 - 95 Error-active
* 96 - 127 Error-warning
* 128 - 255 Error-passive
* 256 and greater Bus-off
*/
#define CAN_ERROR_WARNING_THRESHOLD 96
#define CAN_ERROR_PASSIVE_THRESHOLD 128
#define CAN_BUS_OFF_THRESHOLD 256
#endif /* _UAPI_CAN_ERROR_H */ #endif /* _UAPI_CAN_ERROR_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment