diff options
| author | David S. Miller <davem@davemloft.net> | 2019-11-12 12:27:05 -0800 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-11-12 12:27:05 -0800 |
| commit | e0580b50d9d4b61d6c56085acdc2bb01c040aca9 (patch) | |
| tree | f1d02e5c4a077c9690ce8b7518bb1c09336d26ca /drivers/net/can/m_can/m_can.c | |
| parent | 9440a875b8359090fa9ae65b4fb640893c04a80d (diff) | |
| parent | b9468ad8ff65e6dcfeb69cab15deecafdb883643 (diff) | |
| download | blackbird-op-linux-e0580b50d9d4b61d6c56085acdc2bb01c040aca9.tar.gz blackbird-op-linux-e0580b50d9d4b61d6c56085acdc2bb01c040aca9.zip | |
Merge tag 'linux-can-next-for-5.5-20191111' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says:
====================
pull-request: can-next 2019-10-07
this is a pull request for net-next/master consisting of 32 patches.
The first patch is by Gustavo A. R. Silva and removes unused code in the
generic CAN infrastructure.
The next three patches target the mcp251x driver. The one by Andy
Shevchenko removes the legacy platform data support from the driver. The
other two are by Timo Schlüßler and reset the device only when needed,
to prevent glitches on the output when GPIO support is added.
I'm contributing two patches fixing checkpatch warnings in the
c_can_platform and peak_canfd driver.
Stephane Grosjean's patch for the peak_canfd driver adds hw timestamps
support in rx skbs.
The next three patches target the xilinx_can driver. One patch by me to
fix checkpatch warnings, one patch by Anssi Hannula to avoid non
requested bus error frames, and a patch by YueHaibing that switches the
driver to devm_platform_ioremap_resource().
Pankaj Sharma contributes two patches for the m_can driver, the first
one adds support for one shot mode, the other support for handling
arbitration errors.
Followed by four patches by YueHaibing, switching the grcan, ifi, rcar,
and sun4i drivers to devm_platform_ioremap_resource()
I'm contributing cleanup patches for the rx-offload helper, while Joakim
Zhang's patch prepares the rx-offload helper for CAN-FD support. The rx
offload users flexcan and ti_hecc are converted accordingly.
The remaining twelve patches target the flexcan driver. First Joakim
Zhang switches the driver to devm_platform_ioremap_resource(). The
remaining eleven patch are by me and clean up the abstract the access of
the iflag1 and iflag2 register both for RX and TX mailboxes. This is a
preparation for the upcoming CAN-FD support.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can/m_can/m_can.c')
| -rw-r--r-- | drivers/net/can/m_can/m_can.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 562c8317e3aa..02c5795b7393 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -123,6 +123,7 @@ enum m_can_reg { #define CCCR_CME_CANFD_BRS 0x2 #define CCCR_TXP BIT(14) #define CCCR_TEST BIT(7) +#define CCCR_DAR BIT(6) #define CCCR_MON BIT(5) #define CCCR_CSR BIT(4) #define CCCR_CSA BIT(3) @@ -777,6 +778,43 @@ static inline bool is_lec_err(u32 psr) return psr && (psr != LEC_UNUSED); } +static inline bool m_can_is_protocol_err(u32 irqstatus) +{ + return irqstatus & IR_ERR_LEC_31X; +} + +static int m_can_handle_protocol_error(struct net_device *dev, u32 irqstatus) +{ + struct net_device_stats *stats = &dev->stats; + struct m_can_classdev *cdev = netdev_priv(dev); + struct can_frame *cf; + struct sk_buff *skb; + + /* propagate the error condition to the CAN stack */ + skb = alloc_can_err_skb(dev, &cf); + + /* update tx error stats since there is protocol error */ + stats->tx_errors++; + + /* update arbitration lost status */ + if (cdev->version >= 31 && (irqstatus & IR_PEA)) { + netdev_dbg(dev, "Protocol error in Arbitration fail\n"); + cdev->can.can_stats.arbitration_lost++; + if (skb) { + cf->can_id |= CAN_ERR_LOSTARB; + cf->data[0] |= CAN_ERR_LOSTARB_UNSPEC; + } + } + + if (unlikely(!skb)) { + netdev_dbg(dev, "allocation of skb failed\n"); + return 0; + } + netif_receive_skb(skb); + + return 1; +} + static int m_can_handle_bus_errors(struct net_device *dev, u32 irqstatus, u32 psr) { @@ -791,6 +829,11 @@ static int m_can_handle_bus_errors(struct net_device *dev, u32 irqstatus, is_lec_err(psr)) work_done += m_can_handle_lec_err(dev, psr & LEC_UNUSED); + /* handle protocol errors in arbitration phase */ + if ((cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && + m_can_is_protocol_err(irqstatus)) + work_done += m_can_handle_protocol_error(dev, irqstatus); + /* other unproccessed error interrupts */ m_can_handle_other_err(dev, irqstatus); @@ -1135,7 +1178,7 @@ static void m_can_chip_config(struct net_device *dev) if (cdev->version == 30) { /* Version 3.0.x */ - cccr &= ~(CCCR_TEST | CCCR_MON | + cccr &= ~(CCCR_TEST | CCCR_MON | CCCR_DAR | (CCCR_CMR_MASK << CCCR_CMR_SHIFT) | (CCCR_CME_MASK << CCCR_CME_SHIFT)); @@ -1145,7 +1188,7 @@ static void m_can_chip_config(struct net_device *dev) } else { /* Version 3.1.x or 3.2.x */ cccr &= ~(CCCR_TEST | CCCR_MON | CCCR_BRSE | CCCR_FDOE | - CCCR_NISO); + CCCR_NISO | CCCR_DAR); /* Only 3.2.x has NISO Bit implemented */ if (cdev->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) @@ -1165,6 +1208,10 @@ static void m_can_chip_config(struct net_device *dev) if (cdev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) cccr |= CCCR_MON; + /* Disable Auto Retransmission (all versions) */ + if (cdev->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) + cccr |= CCCR_DAR; + /* Write config */ m_can_write(cdev, M_CAN_CCCR, cccr); m_can_write(cdev, M_CAN_TEST, test); @@ -1310,7 +1357,8 @@ static int m_can_dev_setup(struct m_can_classdev *m_can_dev) m_can_dev->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING | - CAN_CTRLMODE_FD; + CAN_CTRLMODE_FD | + CAN_CTRLMODE_ONE_SHOT; /* Set properties depending on M_CAN version */ switch (m_can_dev->version) { |

