linux-can-next-for-5.20-20220720
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEBsvAIBsPu6mG7thcrX5LkNig010FAmLXs+kTHG1rbEBwZW5n dXRyb25peC5kZQAKCRCtfkuQ2KDTXRhhB/4oU+hdSITnF4SkX+bHa2+7YP/qq2CS AT4/cc7WheYsCB/NFLLBQ9YuPJauw8Z7dTcOvWDX5vxfKzkYen9QaMOhkX67q4i4 yTk1j28ryh7SSMOmSoSlBgru/sqDGL0gc2d3K/DnABJcudrY4gOsFsHA24yPCoPS XwRen/O+/zbumrZrn2vhcqpRKQFq7B4D5GXhFBKyi/VnPpd1z9vb7nR1RqBzg1Qr xdW0oNewAwOv0w1VbZUWJWa2NlsIIdyhSX2hG4pa4GBUl9/KHtA9SMS4WSCcvUhP PpRM2o7MTFKB0ViJqseNxty6f4Xin7B5tNshj9vpmchw5QBFRSN1v1g5 =0265 -----END PGP SIGNATURE----- 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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
50ad649dd7
132
Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml
Normal file
132
Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml
Normal file
@ -0,0 +1,132 @@
|
||||
# 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>;
|
||||
};
|
@ -1,58 +0,0 @@
|
||||
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,
|
||||
|
||||
switch (error_type) {
|
||||
case C_CAN_NO_ERROR:
|
||||
/* error warning state */
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
|
||||
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
break;
|
||||
case C_CAN_ERROR_WARNING:
|
||||
/* 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) ?
|
||||
CAN_ERR_CRTL_TX_WARNING :
|
||||
CAN_ERR_CRTL_RX_WARNING;
|
||||
@ -970,7 +969,7 @@ static int c_can_handle_state_change(struct net_device *dev,
|
||||
break;
|
||||
case C_CAN_ERROR_PASSIVE:
|
||||
/* error passive state */
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
|
||||
if (rx_err_passive)
|
||||
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
|
||||
if (bec.txerr > 127)
|
||||
|
@ -512,6 +512,7 @@ static int cc770_err(struct net_device *dev, u8 status)
|
||||
|
||||
/* Use extended functions of the CC770 */
|
||||
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[7] = cc770_read_reg(priv, rx_error_counter);
|
||||
}
|
||||
|
@ -847,7 +847,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
|
||||
case CAN_STATE_ERROR_PASSIVE:
|
||||
priv->can.can_stats.error_passive++;
|
||||
if (skb) {
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
|
||||
cf->data[1] = (bec.rxerr > 127) ?
|
||||
CAN_ERR_CRTL_RX_PASSIVE :
|
||||
CAN_ERR_CRTL_TX_PASSIVE;
|
||||
@ -858,7 +858,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
|
||||
case CAN_STATE_ERROR_WARNING:
|
||||
priv->can.can_stats.error_warning++;
|
||||
if (skb) {
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
|
||||
cf->data[1] |= (bec.txerr > bec.rxerr) ?
|
||||
CAN_ERR_CRTL_TX_WARNING :
|
||||
CAN_ERR_CRTL_RX_WARNING;
|
||||
@ -867,6 +867,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
|
||||
}
|
||||
break;
|
||||
case CAN_STATE_ERROR_ACTIVE:
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
|
@ -4,9 +4,9 @@
|
||||
* CTU CAN FD IP Core
|
||||
*
|
||||
* 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-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:
|
||||
* Jiri Novak <jnovak@fel.cvut.cz>
|
||||
@ -64,9 +64,12 @@ enum ctu_can_fd_can_registers {
|
||||
CTUCANFD_RX_DATA = 0x6c,
|
||||
CTUCANFD_TX_STATUS = 0x70,
|
||||
CTUCANFD_TX_COMMAND = 0x74,
|
||||
CTUCANFD_TXTB_INFO = 0x76,
|
||||
CTUCANFD_TX_PRIORITY = 0x78,
|
||||
CTUCANFD_ERR_CAPT = 0x7c,
|
||||
CTUCANFD_RETR_CTR = 0x7d,
|
||||
CTUCANFD_ALC = 0x7e,
|
||||
CTUCANFD_TS_INFO = 0x7f,
|
||||
CTUCANFD_TRV_DELAY = 0x80,
|
||||
CTUCANFD_SSP_CFG = 0x82,
|
||||
CTUCANFD_RX_FR_CTR = 0x84,
|
||||
@ -102,8 +105,12 @@ enum ctu_can_fd_can_registers {
|
||||
#define REG_MODE_STM BIT(2)
|
||||
#define REG_MODE_AFM BIT(3)
|
||||
#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_TSTM BIT(8)
|
||||
#define REG_MODE_RXBAM BIT(9)
|
||||
#define REG_MODE_SAM BIT(11)
|
||||
#define REG_MODE_RTRLE BIT(16)
|
||||
#define REG_MODE_RTRTH GENMASK(20, 17)
|
||||
#define REG_MODE_ILBP BIT(21)
|
||||
@ -123,8 +130,10 @@ enum ctu_can_fd_can_registers {
|
||||
#define REG_STATUS_EWL BIT(6)
|
||||
#define REG_STATUS_IDLE BIT(7)
|
||||
#define REG_STATUS_PEXS BIT(8)
|
||||
#define REG_STATUS_STCNT BIT(16)
|
||||
|
||||
/* COMMAND registers */
|
||||
#define REG_COMMAND_RXRPMV BIT(1)
|
||||
#define REG_COMMAND_RRB BIT(2)
|
||||
#define REG_COMMAND_CDO BIT(3)
|
||||
#define REG_COMMAND_ERCRST BIT(4)
|
||||
@ -263,8 +272,12 @@ enum ctu_can_fd_can_registers {
|
||||
#define REG_TX_STATUS_TX2S GENMASK(7, 4)
|
||||
#define REG_TX_STATUS_TX3S GENMASK(11, 8)
|
||||
#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_TXCR BIT(1)
|
||||
#define REG_TX_COMMAND_TXCA BIT(2)
|
||||
@ -272,18 +285,29 @@ enum ctu_can_fd_can_registers {
|
||||
#define REG_TX_COMMAND_TXB2 BIT(9)
|
||||
#define REG_TX_COMMAND_TXB3 BIT(10)
|
||||
#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 */
|
||||
#define REG_TX_PRIORITY_TXT1P GENMASK(2, 0)
|
||||
#define REG_TX_PRIORITY_TXT2P GENMASK(6, 4)
|
||||
#define REG_TX_PRIORITY_TXT3P GENMASK(10, 8)
|
||||
#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_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_ID_FIELD GENMASK(23, 21)
|
||||
#define REG_ERR_CAPT_TS_BITS GENMASK(29, 24)
|
||||
|
||||
/* TRV_DELAY SSP_CFG registers */
|
||||
#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)
|
||||
/* There are no others at this point */
|
||||
break;
|
||||
}
|
||||
cf.can_id |= CAN_ERR_CNT;
|
||||
cf.data[6] = txerr;
|
||||
cf.data[7] = rxerr;
|
||||
priv->can.state = state;
|
||||
|
@ -492,7 +492,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
|
||||
switch (new_state) {
|
||||
case CAN_STATE_ERROR_WARNING:
|
||||
/* 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) ?
|
||||
CAN_ERR_CRTL_TX_WARNING :
|
||||
CAN_ERR_CRTL_RX_WARNING;
|
||||
@ -501,7 +501,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
|
||||
break;
|
||||
case CAN_STATE_ERROR_PASSIVE:
|
||||
/* 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;
|
||||
if (bec.txerr > 127)
|
||||
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)
|
||||
/* bus error interrupt */
|
||||
if (isrc == CEVTIND_BEI) {
|
||||
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) {
|
||||
case ECC_BIT:
|
||||
@ -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 ||
|
||||
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) {
|
||||
mod->can.can_stats.error_warning++;
|
||||
cf->data[1] = (txerr > rxerr) ?
|
||||
|
@ -1306,7 +1306,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
|
||||
shhwtstamps->hwtstamp =
|
||||
ns_to_ktime(div_u64(p->timestamp * 1000,
|
||||
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[7] = bec.rxerr;
|
||||
|
@ -741,7 +741,7 @@ static int m_can_handle_state_change(struct net_device *dev,
|
||||
switch (new_state) {
|
||||
case CAN_STATE_ERROR_WARNING:
|
||||
/* 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) ?
|
||||
CAN_ERR_CRTL_TX_WARNING :
|
||||
CAN_ERR_CRTL_RX_WARNING;
|
||||
@ -750,7 +750,7 @@ static int m_can_handle_state_change(struct net_device *dev,
|
||||
break;
|
||||
case CAN_STATE_ERROR_PASSIVE:
|
||||
/* 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);
|
||||
if (ecr & ECR_RP)
|
||||
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
|
||||
|
@ -496,6 +496,10 @@ static void pch_can_error(struct net_device *ndev, u32 status)
|
||||
cf->can_id |= CAN_ERR_BUSOFF;
|
||||
priv->can.can_stats.bus_off++;
|
||||
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);
|
||||
@ -556,9 +560,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
|
||||
break;
|
||||
}
|
||||
|
||||
cf->data[6] = errc & PCH_TEC;
|
||||
cf->data[7] = (errc & PCH_REC) >> 8;
|
||||
|
||||
priv->can.state = state;
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
|
||||
priv->can.state = CAN_STATE_ERROR_PASSIVE;
|
||||
priv->can.can_stats.error_passive++;
|
||||
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) ?
|
||||
CAN_ERR_CRTL_TX_PASSIVE :
|
||||
CAN_ERR_CRTL_RX_PASSIVE;
|
||||
@ -386,7 +386,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
|
||||
priv->can.state = CAN_STATE_ERROR_WARNING;
|
||||
priv->can.can_stats.error_warning++;
|
||||
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) ?
|
||||
CAN_ERR_CRTL_TX_WARNING :
|
||||
CAN_ERR_CRTL_RX_WARNING;
|
||||
@ -430,7 +430,7 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv)
|
||||
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[6] = priv->bec.txerr;
|
||||
|
@ -232,11 +232,8 @@ static void rcar_can_error(struct net_device *ndev)
|
||||
if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) {
|
||||
txerr = readb(&priv->regs->tecr);
|
||||
rxerr = readb(&priv->regs->recr);
|
||||
if (skb) {
|
||||
if (skb)
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
}
|
||||
}
|
||||
if (eifr & RCAR_CAN_EIFR_BEIF) {
|
||||
int rx_errors = 0, tx_errors = 0;
|
||||
@ -336,6 +333,10 @@ static void rcar_can_error(struct net_device *ndev)
|
||||
can_bus_off(ndev);
|
||||
if (skb)
|
||||
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) {
|
||||
netdev_dbg(priv->ndev, "Receive overrun error interrupt\n");
|
||||
|
@ -1052,7 +1052,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
|
||||
netdev_dbg(ndev, "Error warning interrupt\n");
|
||||
priv->can.state = CAN_STATE_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 :
|
||||
CAN_ERR_CRTL_RX_WARNING;
|
||||
cf->data[6] = txerr;
|
||||
@ -1062,7 +1062,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
|
||||
netdev_dbg(ndev, "Error passive interrupt\n");
|
||||
priv->can.state = CAN_STATE_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 :
|
||||
CAN_ERR_CRTL_RX_PASSIVE;
|
||||
cf->data[6] = txerr;
|
||||
|
@ -183,8 +183,9 @@ static void chipset_init(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* set clock divider and output control register */
|
||||
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
|
||||
if (!(priv->flags & SJA1000_QUIRK_NO_CDR_REG))
|
||||
/* set clock divider and output control register */
|
||||
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
|
||||
|
||||
/* set acceptance filter (accept all) */
|
||||
priv->write_reg(priv, SJA1000_ACCC0, 0x00);
|
||||
@ -209,7 +210,8 @@ static void sja1000_start(struct net_device *dev)
|
||||
set_reset_mode(dev);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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)
|
||||
txerr = priv->read_reg(priv, SJA1000_TXERR);
|
||||
rxerr = priv->read_reg(priv, SJA1000_RXERR);
|
||||
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
|
||||
if (isrc & IRQ_DOI) {
|
||||
/* data overrun interrupt */
|
||||
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)
|
||||
else
|
||||
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) {
|
||||
/* bus error interrupt */
|
||||
priv->can.can_stats.bus_error++;
|
||||
|
@ -145,7 +145,8 @@
|
||||
/*
|
||||
* 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
|
||||
|
@ -31,7 +31,7 @@ MODULE_LICENSE("GPL v2");
|
||||
|
||||
struct sja1000_of_data {
|
||||
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 {
|
||||
@ -94,15 +94,13 @@ static void sp_technologic_write_reg16(const struct sja1000_priv *priv,
|
||||
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;
|
||||
|
||||
priv->read_reg = sp_technologic_read_reg16;
|
||||
priv->write_reg = sp_technologic_write_reg16;
|
||||
spin_lock_init(&tp->io_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sp_populate(struct sja1000_priv *priv,
|
||||
@ -210,7 +208,6 @@ static int sp_probe(struct platform_device *pdev)
|
||||
struct resource *res_mem, *res_irq = NULL;
|
||||
struct sja1000_platform_data *pdata;
|
||||
struct device_node *of = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id;
|
||||
const struct sja1000_of_data *of_data = NULL;
|
||||
size_t priv_sz = 0;
|
||||
|
||||
@ -243,11 +240,9 @@ static int sp_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
of_id = of_match_device(sp_of_table, &pdev->dev);
|
||||
if (of_id && of_id->data) {
|
||||
of_data = of_id->data;
|
||||
of_data = device_get_match_data(&pdev->dev);
|
||||
if (of_data)
|
||||
priv_sz = of_data->priv_sz;
|
||||
}
|
||||
|
||||
dev = alloc_sja1000dev(priv_sz);
|
||||
if (!dev)
|
||||
@ -269,11 +264,8 @@ static int sp_probe(struct platform_device *pdev)
|
||||
if (of) {
|
||||
sp_populate_of(priv, of);
|
||||
|
||||
if (of_data && of_data->init) {
|
||||
err = of_data->init(priv, of);
|
||||
if (err)
|
||||
goto exit_free;
|
||||
}
|
||||
if (of_data && of_data->init)
|
||||
of_data->init(priv, of);
|
||||
} else {
|
||||
sp_populate(priv, pdata, res_mem->flags);
|
||||
}
|
||||
|
@ -67,13 +67,14 @@ MODULE_AUTHOR("Oliver Hartkopp <socketcan@hartkopp.net>");
|
||||
#define SLCAN_MAGIC 0x53CA
|
||||
|
||||
static int maxdev = 10; /* MAX number of SLCAN channels;
|
||||
This can be overridden with
|
||||
insmod slcan.ko maxdev=nnn */
|
||||
* This can be overridden with
|
||||
* insmod slcan.ko maxdev=nnn
|
||||
*/
|
||||
module_param(maxdev, int, 0);
|
||||
MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces");
|
||||
|
||||
/* maximum rx buffer len: extended CAN frame with timestamp */
|
||||
#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
|
||||
#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r") + 1)
|
||||
|
||||
#define SLC_CMD_LEN 1
|
||||
#define SLC_SFF_ID_LEN 3
|
||||
@ -139,12 +140,11 @@ int slcan_enable_err_rst_on_open(struct net_device *ndev, bool on)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* SLCAN ENCAPSULATION FORMAT *
|
||||
************************************************************************/
|
||||
/*************************************************************************
|
||||
* SLCAN ENCAPSULATION FORMAT *
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
* A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
|
||||
/* A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
|
||||
* 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
|
||||
@ -174,9 +174,9 @@ int slcan_enable_err_rst_on_open(struct net_device *ndev, bool on)
|
||||
*
|
||||
*/
|
||||
|
||||
/************************************************************************
|
||||
* STANDARD SLCAN DECAPSULATION *
|
||||
************************************************************************/
|
||||
/*************************************************************************
|
||||
* STANDARD SLCAN DECAPSULATION *
|
||||
*************************************************************************/
|
||||
|
||||
/* Send one completely decapsulated can_frame to the network layer */
|
||||
static void slc_bump_frame(struct slcan *sl)
|
||||
@ -306,19 +306,18 @@ static void slc_bump_state(struct slcan *sl)
|
||||
return;
|
||||
|
||||
skb = alloc_can_err_skb(dev, &cf);
|
||||
if (skb) {
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
} else {
|
||||
cf = NULL;
|
||||
}
|
||||
|
||||
tx_state = txerr >= rxerr ? state : 0;
|
||||
rx_state = txerr <= rxerr ? state : 0;
|
||||
can_change_state(dev, cf, tx_state, rx_state);
|
||||
|
||||
if (state == CAN_STATE_BUS_OFF)
|
||||
if (state == CAN_STATE_BUS_OFF) {
|
||||
can_bus_off(dev);
|
||||
} else if (skb) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
}
|
||||
|
||||
if (skb)
|
||||
netif_rx(skb);
|
||||
@ -469,26 +468,26 @@ static void slcan_unesc(struct slcan *sl, unsigned char s)
|
||||
{
|
||||
if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */
|
||||
if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
|
||||
(sl->rcount > 4)) {
|
||||
sl->rcount > 4)
|
||||
slc_bump(sl);
|
||||
}
|
||||
|
||||
sl->rcount = 0;
|
||||
} else {
|
||||
if (!test_bit(SLF_ERROR, &sl->flags)) {
|
||||
if (sl->rcount < SLC_MTU) {
|
||||
sl->rbuff[sl->rcount++] = s;
|
||||
return;
|
||||
} else {
|
||||
sl->dev->stats.rx_over_errors++;
|
||||
set_bit(SLF_ERROR, &sl->flags);
|
||||
}
|
||||
|
||||
sl->dev->stats.rx_over_errors++;
|
||||
set_bit(SLF_ERROR, &sl->flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* STANDARD SLCAN ENCAPSULATION *
|
||||
************************************************************************/
|
||||
/*************************************************************************
|
||||
* STANDARD SLCAN ENCAPSULATION *
|
||||
*************************************************************************/
|
||||
|
||||
/* Encapsulate one can_frame and stuff into a TTY queue. */
|
||||
static void slc_encaps(struct slcan *sl, struct can_frame *cf)
|
||||
@ -575,7 +574,8 @@ static void slcan_transmit(struct work_struct *work)
|
||||
}
|
||||
|
||||
/* Now serial buffer is almost free & we can start
|
||||
* transmission of another packet */
|
||||
* transmission of another packet
|
||||
*/
|
||||
sl->dev->stats.tx_packets++;
|
||||
clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
|
||||
spin_unlock_bh(&sl->lock);
|
||||
@ -589,8 +589,7 @@ static void slcan_transmit(struct work_struct *work)
|
||||
spin_unlock_bh(&sl->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by the driver when there's room for more data.
|
||||
/* Called by the driver when there's room for more data.
|
||||
* Schedule the transmit.
|
||||
*/
|
||||
static void slcan_write_wakeup(struct tty_struct *tty)
|
||||
@ -618,13 +617,13 @@ static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
netdev_warn(dev, "xmit: iface is down\n");
|
||||
goto out;
|
||||
}
|
||||
if (sl->tty == NULL) {
|
||||
if (!sl->tty) {
|
||||
spin_unlock(&sl->lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
netif_stop_queue(sl->dev);
|
||||
slc_encaps(sl, (struct can_frame *) skb->data); /* encaps & send */
|
||||
slc_encaps(sl, (struct can_frame *)skb->data); /* encaps & send */
|
||||
spin_unlock(&sl->lock);
|
||||
|
||||
out:
|
||||
@ -632,7 +631,6 @@ out:
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************
|
||||
* Routines looking at netdevice side.
|
||||
******************************************/
|
||||
@ -647,7 +645,7 @@ static int slcan_transmit_cmd(struct slcan *sl, const unsigned char *cmd)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
n = snprintf(sl->xbuff, sizeof(sl->xbuff), "%s", cmd);
|
||||
n = scnprintf(sl->xbuff, sizeof(sl->xbuff), "%s", cmd);
|
||||
set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
|
||||
actual = sl->tty->ops->write(sl->tty, sl->xbuff, n);
|
||||
sl->xleft = n - actual;
|
||||
@ -689,15 +687,14 @@ static int slc_close(struct net_device *dev)
|
||||
clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
|
||||
}
|
||||
netif_stop_queue(dev);
|
||||
sl->rcount = 0;
|
||||
sl->xleft = 0;
|
||||
spin_unlock_bh(&sl->lock);
|
||||
close_candev(dev);
|
||||
sl->can.state = CAN_STATE_STOPPED;
|
||||
if (sl->can.bittiming.bitrate == CAN_BITRATE_UNKNOWN)
|
||||
sl->can.bittiming.bitrate = CAN_BITRATE_UNSET;
|
||||
|
||||
sl->rcount = 0;
|
||||
sl->xleft = 0;
|
||||
spin_unlock_bh(&sl->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -708,7 +705,7 @@ static int slc_open(struct net_device *dev)
|
||||
unsigned char cmd[SLC_MTU];
|
||||
int err, s;
|
||||
|
||||
if (sl->tty == NULL)
|
||||
if (!sl->tty)
|
||||
return -ENODEV;
|
||||
|
||||
/* The baud rate is not set with the command
|
||||
@ -736,7 +733,6 @@ static int slc_open(struct net_device *dev)
|
||||
/* The CAN framework has already validate the bitrate value,
|
||||
* so we can avoid to check if `s' has been properly set.
|
||||
*/
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "C\rS%d\r", s);
|
||||
err = slcan_transmit_cmd(sl, cmd);
|
||||
if (err) {
|
||||
@ -792,23 +788,21 @@ static const struct net_device_ops slc_netdev_ops = {
|
||||
};
|
||||
|
||||
/******************************************
|
||||
Routines looking at TTY side.
|
||||
* Routines looking at TTY side.
|
||||
******************************************/
|
||||
|
||||
/*
|
||||
* Handle the 'receiver data ready' interrupt.
|
||||
/* Handle the 'receiver data ready' interrupt.
|
||||
* This function is called by the 'tty_io' module in the kernel when
|
||||
* a block of SLCAN data has been received, which can now be decapsulated
|
||||
* and sent on to some IP layer for further processing. This will not
|
||||
* be re-entered while running but other ldisc functions may be called
|
||||
* in parallel
|
||||
*/
|
||||
|
||||
static void slcan_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, const char *fp,
|
||||
int count)
|
||||
{
|
||||
struct slcan *sl = (struct slcan *) tty->disc_data;
|
||||
struct slcan *sl = (struct slcan *)tty->disc_data;
|
||||
|
||||
if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
|
||||
return;
|
||||
@ -838,7 +832,7 @@ static void slc_sync(void)
|
||||
|
||||
for (i = 0; i < maxdev; i++) {
|
||||
dev = slcan_devs[i];
|
||||
if (dev == NULL)
|
||||
if (!dev)
|
||||
break;
|
||||
|
||||
sl = netdev_priv(dev);
|
||||
@ -858,9 +852,8 @@ static struct slcan *slc_alloc(void)
|
||||
|
||||
for (i = 0; i < maxdev; i++) {
|
||||
dev = slcan_devs[i];
|
||||
if (dev == NULL)
|
||||
if (!dev)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* Sorry, too many, all slots in use */
|
||||
@ -890,8 +883,7 @@ static struct slcan *slc_alloc(void)
|
||||
return sl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the high-level part of the SLCAN channel.
|
||||
/* Open the high-level part of the SLCAN channel.
|
||||
* This function is called by the TTY module when the
|
||||
* SLCAN line discipline is called for. Because we are
|
||||
* sure the tty line exists, we only have to link it to
|
||||
@ -899,7 +891,6 @@ static struct slcan *slc_alloc(void)
|
||||
*
|
||||
* Called in process context serialized from other ldisc calls.
|
||||
*/
|
||||
|
||||
static int slcan_open(struct tty_struct *tty)
|
||||
{
|
||||
struct slcan *sl;
|
||||
@ -908,12 +899,12 @@ static int slcan_open(struct tty_struct *tty)
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (tty->ops->write == NULL)
|
||||
if (!tty->ops->write)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* RTnetlink lock is misused here to serialize concurrent
|
||||
opens of slcan channels. There are better ways, but it is
|
||||
the simplest one.
|
||||
* opens of slcan channels. There are better ways, but it is
|
||||
* the simplest one.
|
||||
*/
|
||||
rtnl_lock();
|
||||
|
||||
@ -930,7 +921,7 @@ static int slcan_open(struct tty_struct *tty)
|
||||
/* OK. Find a free SLCAN channel to use. */
|
||||
err = -ENFILE;
|
||||
sl = slc_alloc();
|
||||
if (sl == NULL)
|
||||
if (!sl)
|
||||
goto err_exit;
|
||||
|
||||
sl->tty = tty;
|
||||
@ -974,17 +965,15 @@ err_exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close down a SLCAN channel.
|
||||
/* Close down a SLCAN channel.
|
||||
* This means flushing out any pending queues, and then returning. This
|
||||
* call is serialized against other ldisc functions.
|
||||
*
|
||||
* We also use this method for a hangup event.
|
||||
*/
|
||||
|
||||
static void slcan_close(struct tty_struct *tty)
|
||||
{
|
||||
struct slcan *sl = (struct slcan *) tty->disc_data;
|
||||
struct slcan *sl = (struct slcan *)tty->disc_data;
|
||||
|
||||
/* First make sure we're connected. */
|
||||
if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
|
||||
@ -1014,7 +1003,7 @@ static void slcan_hangup(struct tty_struct *tty)
|
||||
static int slcan_ioctl(struct tty_struct *tty, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct slcan *sl = (struct slcan *) tty->disc_data;
|
||||
struct slcan *sl = (struct slcan *)tty->disc_data;
|
||||
unsigned int tmp;
|
||||
|
||||
/* First make sure we're connected. */
|
||||
@ -1065,7 +1054,7 @@ static int __init slcan_init(void)
|
||||
/* Fill in our line protocol discipline, and register it */
|
||||
status = tty_register_ldisc(&slc_ldisc);
|
||||
if (status) {
|
||||
printk(KERN_ERR "slcan: can't register line discipline\n");
|
||||
pr_err("slcan: can't register line discipline\n");
|
||||
kfree(slcan_devs);
|
||||
}
|
||||
return status;
|
||||
@ -1079,7 +1068,7 @@ static void __exit slcan_exit(void)
|
||||
unsigned long timeout = jiffies + HZ;
|
||||
int busy = 0;
|
||||
|
||||
if (slcan_devs == NULL)
|
||||
if (!slcan_devs)
|
||||
return;
|
||||
|
||||
/* First of all: check for active disciplines and hangup them.
|
||||
@ -1104,7 +1093,8 @@ static void __exit slcan_exit(void)
|
||||
} while (busy && time_before(jiffies, timeout));
|
||||
|
||||
/* FIXME: hangup is async so we should wait when doing this second
|
||||
phase */
|
||||
* phase
|
||||
*/
|
||||
|
||||
for (i = 0; i < maxdev; i++) {
|
||||
dev = slcan_devs[i];
|
||||
@ -1112,9 +1102,8 @@ static void __exit slcan_exit(void)
|
||||
continue;
|
||||
|
||||
sl = netdev_priv(dev);
|
||||
if (sl->tty) {
|
||||
if (sl->tty)
|
||||
netdev_err(dev, "tty discipline still running\n");
|
||||
}
|
||||
|
||||
slc_close(dev);
|
||||
unregister_candev(dev);
|
||||
|
@ -667,8 +667,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
|
||||
|
||||
txerr = hi3110_read(spi, HI3110_READ_TEC);
|
||||
rxerr = hi3110_read(spi, HI3110_READ_REC);
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
tx_state = txerr >= rxerr ? new_state : 0;
|
||||
rx_state = txerr <= rxerr ? new_state : 0;
|
||||
can_change_state(net, cf, tx_state, rx_state);
|
||||
@ -681,6 +679,10 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
|
||||
hi3110_hw_sleep(spi);
|
||||
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)
|
||||
err = mcp251xfd_get_berr_counter(priv->ndev, &bec);
|
||||
if (err)
|
||||
return err;
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
}
|
||||
|
@ -535,11 +535,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
|
||||
rxerr = (errc >> 16) & 0xFF;
|
||||
txerr = errc & 0xFF;
|
||||
|
||||
if (skb) {
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
}
|
||||
|
||||
if (isrc & SUN4I_INT_DATA_OR) {
|
||||
/* data overrun interrupt */
|
||||
netdev_dbg(dev, "data overrun interrupt\n");
|
||||
@ -570,6 +565,11 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
|
||||
else
|
||||
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) {
|
||||
/* bus error interrupt */
|
||||
netdev_dbg(dev, "bus error interrupt\n");
|
||||
|
@ -662,6 +662,7 @@ static void ti_hecc_change_state(struct net_device *ndev,
|
||||
can_change_state(priv->ndev, cf, tx_state, rx_state);
|
||||
|
||||
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[7] = hecc_read(priv, HECC_CANREC);
|
||||
}
|
||||
|
@ -265,7 +265,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
|
||||
priv->can.can_stats.bus_error++;
|
||||
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) {
|
||||
case SJA1000_ECC_BIT:
|
||||
|
@ -917,8 +917,11 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
|
||||
new_state < CAN_STATE_BUS_OFF)
|
||||
priv->can.can_stats.restarts++;
|
||||
|
||||
cf->data[6] = bec->txerr;
|
||||
cf->data[7] = bec->rxerr;
|
||||
if (new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec->txerr;
|
||||
cf->data[7] = bec->rxerr;
|
||||
}
|
||||
|
||||
netif_rx(skb);
|
||||
}
|
||||
@ -1069,8 +1072,11 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
|
||||
shhwtstamps->hwtstamp = hwtstamp;
|
||||
|
||||
cf->can_id |= CAN_ERR_BUSERROR;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
if (new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
}
|
||||
|
||||
netif_rx(skb);
|
||||
|
||||
|
@ -853,8 +853,11 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
|
||||
break;
|
||||
}
|
||||
|
||||
cf->data[6] = es->txerr;
|
||||
cf->data[7] = es->rxerr;
|
||||
if (new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = es->txerr;
|
||||
cf->data[7] = es->rxerr;
|
||||
}
|
||||
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
@ -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
|
||||
* controller error.
|
||||
*/
|
||||
cf->can_id = CAN_ERR_CNT;
|
||||
cf->data[6] = mc->pdev->bec.txerr;
|
||||
cf->data[7] = mc->pdev->bec.rxerr;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ MODULE_DEVICE_TABLE(usb, peak_usb_table);
|
||||
* dump memory
|
||||
*/
|
||||
#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",
|
||||
PCAN_USB_DRIVER_NAME, prompt ? prompt : "memory", l);
|
||||
|
@ -132,7 +132,7 @@ struct peak_usb_device {
|
||||
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 */
|
||||
void peak_usb_init_time_ref(struct peak_time_ref *time_ref,
|
||||
|
@ -33,6 +33,10 @@
|
||||
#define PCAN_UFD_RX_BUFFER_SIZE 2048
|
||||
#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 */
|
||||
struct __packed pcan_ufd_fw_info {
|
||||
__le16 size_of; /* sizeof this */
|
||||
@ -44,6 +48,13 @@ struct __packed pcan_ufd_fw_info {
|
||||
__le32 dev_id[2]; /* "device id" per CAN */
|
||||
__le32 ser_no; /* S/N */
|
||||
__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 */
|
||||
@ -171,6 +182,9 @@ static inline void *pcan_usb_fd_cmd_buffer(struct peak_usb_device *dev)
|
||||
/* send PCAN-USB Pro FD commands synchronously */
|
||||
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);
|
||||
int err = 0;
|
||||
u8 *packet_ptr;
|
||||
@ -200,7 +214,7 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
|
||||
do {
|
||||
err = usb_bulk_msg(dev->udev,
|
||||
usb_sndbulkpipe(dev->udev,
|
||||
PCAN_USBPRO_EP_CMDOUT),
|
||||
fw_info->cmd_out_ep),
|
||||
packet_ptr, packet_len,
|
||||
NULL, PCAN_UFD_CMD_TIMEOUT_MS);
|
||||
if (err) {
|
||||
@ -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,
|
||||
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;
|
||||
|
||||
/* 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,
|
||||
|
||||
/* complete the URB */
|
||||
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,
|
||||
pcan_usb_pro_restart_complete, dev);
|
||||
|
||||
@ -839,6 +856,15 @@ static int pcan_usb_fd_get_berr_counter(const struct net_device *netdev,
|
||||
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) */
|
||||
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)
|
||||
{
|
||||
struct pcan_usb_fd_device *pdev =
|
||||
container_of(dev, struct pcan_usb_fd_device, dev);
|
||||
struct pcan_ufd_fw_info *fw_info;
|
||||
int i, err = -ENOMEM;
|
||||
|
||||
/* do this for 1st channel only */
|
||||
@ -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 */
|
||||
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,
|
||||
PCAN_USBPRO_INFO_FW,
|
||||
&pdev->usb_if->fw_info,
|
||||
sizeof(pdev->usb_if->fw_info));
|
||||
fw_info,
|
||||
sizeof(*fw_info));
|
||||
if (err) {
|
||||
dev_err(dev->netdev->dev.parent,
|
||||
"unable to read %s firmware info (err %d)\n",
|
||||
@ -895,14 +924,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
|
||||
*/
|
||||
dev_info(dev->netdev->dev.parent,
|
||||
"PEAK-System %s v%u fw v%u.%u.%u (%u channels)\n",
|
||||
dev->adapter->name, pdev->usb_if->fw_info.hw_version,
|
||||
pdev->usb_if->fw_info.fw_version[0],
|
||||
pdev->usb_if->fw_info.fw_version[1],
|
||||
pdev->usb_if->fw_info.fw_version[2],
|
||||
dev->adapter->name, fw_info->hw_version,
|
||||
fw_info->fw_version[0],
|
||||
fw_info->fw_version[1],
|
||||
fw_info->fw_version[2],
|
||||
dev->adapter->ctrl_count);
|
||||
|
||||
/* 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 */
|
||||
dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO;
|
||||
} else {
|
||||
@ -910,6 +939,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
|
||||
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 */
|
||||
err = pcan_usb_fd_drv_loaded(dev, 1);
|
||||
if (err) {
|
||||
@ -930,12 +967,23 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
|
||||
/* do a copy of the ctrlmode[_supported] too */
|
||||
dev->can.ctrlmode = ppdev->dev.can.ctrlmode;
|
||||
dev->can.ctrlmode_supported = ppdev->dev.can.ctrlmode_supported;
|
||||
|
||||
fw_info = &pdev->usb_if->fw_info;
|
||||
}
|
||||
|
||||
pdev->usb_if->dev[dev->ctrl_idx] = dev;
|
||||
dev->device_number =
|
||||
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 */
|
||||
for (i = 0; i < ARRAY_SIZE(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 = {
|
||||
.tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE,
|
||||
|
||||
/* 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_exit = pcan_usb_fd_exit,
|
||||
|
@ -439,7 +439,7 @@ static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
|
||||
return err;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ struct __packed pcan_usb_pro_devid {
|
||||
u8 data_type;
|
||||
u8 channel;
|
||||
__le16 dummy;
|
||||
__le32 serial_num;
|
||||
__le32 dev_num;
|
||||
};
|
||||
|
||||
#define PCAN_USBPRO_LED_DEVICE 0x00
|
||||
|
@ -438,9 +438,11 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
|
||||
|
||||
if (rx_errors)
|
||||
stats->rx_errors++;
|
||||
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
if (priv->can.state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
}
|
||||
|
||||
priv->bec.txerr = txerr;
|
||||
priv->bec.rxerr = rxerr;
|
||||
|
@ -965,6 +965,7 @@ static void xcan_set_error_state(struct net_device *ndev,
|
||||
can_change_state(ndev, cf, tx_state, rx_state);
|
||||
|
||||
if (cf) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
}
|
||||
|
@ -57,6 +57,8 @@
|
||||
#define CAN_ERR_BUSOFF 0x00000040U /* bus off */
|
||||
#define CAN_ERR_BUSERROR 0x00000080U /* bus error (may flood!) */
|
||||
#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] */
|
||||
#define CAN_ERR_LOSTARB_UNSPEC 0x00 /* unspecified */
|
||||
@ -120,6 +122,22 @@
|
||||
#define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70 /* 0111 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 */
|
||||
|
Loading…
Reference in New Issue
Block a user