--- /dev/null
+From e7a6994d043a1e31d5b17706a22ce33d2a3e4cdc Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Wed, 31 Oct 2018 14:05:26 +0100
+Subject: can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb is accessed out of bounds
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit e7a6994d043a1e31d5b17706a22ce33d2a3e4cdc upstream.
+
+If the "struct can_priv::echo_skb" is accessed out of bounds would lead
+to a kernel crash. Better print a sensible warning message instead and
+try to recover.
+
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/dev.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/can/dev.c
++++ b/drivers/net/can/dev.c
+@@ -481,7 +481,11 @@ struct sk_buff *__can_get_echo_skb(struc
+ {
+ struct can_priv *priv = netdev_priv(dev);
+
+- BUG_ON(idx >= priv->echo_skb_max);
++ if (idx >= priv->echo_skb_max) {
++ netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
++ __func__, idx, priv->echo_skb_max);
++ return NULL;
++ }
+
+ if (priv->echo_skb[idx]) {
+ /* Using "struct canfd_frame::len" for the frame
--- /dev/null
+From 7da11ba5c5066dadc2e96835a6233d56d7b7764a Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Wed, 31 Oct 2018 14:15:13 +0100
+Subject: can: dev: __can_get_echo_skb(): print error message, if trying to echo non existing skb
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit 7da11ba5c5066dadc2e96835a6233d56d7b7764a upstream.
+
+Prior to echoing a successfully transmitted CAN frame (by calling
+can_get_echo_skb()), CAN drivers have to put the CAN frame (by calling
+can_put_echo_skb() in the transmit function). These put and get function
+take an index as parameter, which is used to identify the CAN frame.
+
+A driver calling can_get_echo_skb() with a index not pointing to a skb
+is a BUG, so add an appropriate error message.
+
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/dev.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/can/dev.c
++++ b/drivers/net/can/dev.c
+@@ -480,6 +480,8 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
+ struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
+ {
+ struct can_priv *priv = netdev_priv(dev);
++ struct sk_buff *skb = priv->echo_skb[idx];
++ struct canfd_frame *cf;
+
+ if (idx >= priv->echo_skb_max) {
+ netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
+@@ -487,21 +489,20 @@ struct sk_buff *__can_get_echo_skb(struc
+ return NULL;
+ }
+
+- if (priv->echo_skb[idx]) {
+- /* Using "struct canfd_frame::len" for the frame
+- * length is supported on both CAN and CANFD frames.
+- */
+- struct sk_buff *skb = priv->echo_skb[idx];
+- struct canfd_frame *cf = (struct canfd_frame *)skb->data;
+- u8 len = cf->len;
+-
+- *len_ptr = len;
+- priv->echo_skb[idx] = NULL;
+-
+- return skb;
++ if (!skb) {
++ netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n",
++ __func__, idx);
++ return NULL;
+ }
+
+- return NULL;
++ /* Using "struct canfd_frame::len" for the frame
++ * length is supported on both CAN and CANFD frames.
++ */
++ cf = (struct canfd_frame *)skb->data;
++ *len_ptr = cf->len;
++ priv->echo_skb[idx] = NULL;
++
++ return skb;
+ }
+
+ /*
--- /dev/null
+From 200f5c49f7a2cd694436bfc6cb0662b794c96736 Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Wed, 31 Oct 2018 11:08:21 +0100
+Subject: can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to access frame length
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit 200f5c49f7a2cd694436bfc6cb0662b794c96736 upstream.
+
+This patch replaces the use of "struct can_frame::can_dlc" by "struct
+canfd_frame::len" to access the frame's length. As it is ensured that
+both structures have a compatible memory layout for this member this is
+no functional change. Futher, this compatibility is documented in a
+comment.
+
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/dev.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/can/dev.c
++++ b/drivers/net/can/dev.c
+@@ -484,11 +484,14 @@ struct sk_buff *__can_get_echo_skb(struc
+ BUG_ON(idx >= priv->echo_skb_max);
+
+ if (priv->echo_skb[idx]) {
++ /* Using "struct canfd_frame::len" for the frame
++ * length is supported on both CAN and CANFD frames.
++ */
+ struct sk_buff *skb = priv->echo_skb[idx];
+- struct can_frame *cf = (struct can_frame *)skb->data;
+- u8 dlc = cf->can_dlc;
++ struct canfd_frame *cf = (struct canfd_frame *)skb->data;
++ u8 len = cf->len;
+
+- *len_ptr = dlc;
++ *len_ptr = len;
+ priv->echo_skb[idx] = NULL;
+
+ return skb;
--- /dev/null
+From a4310fa2f24687888ce80fdb0e88583561a23700 Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Wed, 31 Oct 2018 10:37:46 +0100
+Subject: can: dev: can_get_echo_skb(): factor out non sending code to __can_get_echo_skb()
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit a4310fa2f24687888ce80fdb0e88583561a23700 upstream.
+
+This patch factors out all non sending parts of can_get_echo_skb() into
+a seperate function __can_get_echo_skb(), so that it can be re-used in
+an upcoming patch.
+
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/dev.c | 36 +++++++++++++++++++++++++-----------
+ include/linux/can/dev.h | 1 +
+ 2 files changed, 26 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/can/dev.c
++++ b/drivers/net/can/dev.c
+@@ -477,14 +477,7 @@ void can_put_echo_skb(struct sk_buff *sk
+ }
+ EXPORT_SYMBOL_GPL(can_put_echo_skb);
+
+-/*
+- * Get the skb from the stack and loop it back locally
+- *
+- * The function is typically called when the TX done interrupt
+- * is handled in the device driver. The driver must protect
+- * access to priv->echo_skb, if necessary.
+- */
+-unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
++struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
+ {
+ struct can_priv *priv = netdev_priv(dev);
+
+@@ -495,13 +488,34 @@ unsigned int can_get_echo_skb(struct net
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u8 dlc = cf->can_dlc;
+
+- netif_rx(priv->echo_skb[idx]);
++ *len_ptr = dlc;
+ priv->echo_skb[idx] = NULL;
+
+- return dlc;
++ return skb;
+ }
+
+- return 0;
++ return NULL;
++}
++
++/*
++ * Get the skb from the stack and loop it back locally
++ *
++ * The function is typically called when the TX done interrupt
++ * is handled in the device driver. The driver must protect
++ * access to priv->echo_skb, if necessary.
++ */
++unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
++{
++ struct sk_buff *skb;
++ u8 len;
++
++ skb = __can_get_echo_skb(dev, idx, &len);
++ if (!skb)
++ return 0;
++
++ netif_rx(skb);
++
++ return len;
+ }
+ EXPORT_SYMBOL_GPL(can_get_echo_skb);
+
+--- a/include/linux/can/dev.h
++++ b/include/linux/can/dev.h
+@@ -169,6 +169,7 @@ void can_change_state(struct net_device
+
+ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
+ unsigned int idx);
++struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr);
+ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
+ void can_free_echo_skb(struct net_device *dev, unsigned int idx);
+
--- /dev/null
+From cbffaf7aa09edbaea2bc7dc440c945297095e2fd Mon Sep 17 00:00:00 2001
+From: Alexander Stein <alexander.stein@systec-electronic.com>
+Date: Thu, 11 Oct 2018 17:01:25 +0200
+Subject: can: flexcan: Always use last mailbox for TX
+
+From: Alexander Stein <alexander.stein@systec-electronic.com>
+
+commit cbffaf7aa09edbaea2bc7dc440c945297095e2fd upstream.
+
+Essentially this patch moves the TX mailbox to position 63, regardless
+of timestamp based offloading or RX FIFO. So mainly the iflag register
+usage regarding TX has changed. The rest is consolidating RX FIFO and
+timestamp offloading as they now use both the same TX mailbox.
+
+The reason is a very annoying behavior regarding sending RTR frames when
+_not_ using RX FIFO:
+
+If a TX mailbox sent a RTR frame it becomes a RX mailbox. For that
+reason flexcan_irq disables the TX mailbox again. But if during the time
+the RTR was sent and the TX mailbox is disabled a new CAN frames is
+received, it is lost without notice. The reason is that so-called
+"Move-in" process starts from the lowest mailbox which happen to be a TX
+mailbox set to EMPTY.
+
+Steps to reproduce (I used an imx7d):
+1. generate regular bursts of messages
+2. send a RTR from flexcan with higher priority than burst messages every
+ 1ms, e.g. cangen -I 0x100 -L 0 -g 1 -R can0
+3. notice a lost message without notification after some seconds
+
+When running an iperf in parallel this problem is occurring even more
+frequently. Using filters is not possible as at least one single CAN-ID
+is allowed. Handling the TX MB during RX is also not possible as there
+is no race-free disable of RX MB.
+
+There is still a slight window when the described problem can occur. But
+for that all RX MB must be in use which is essentially next to an
+overrun. Still there will be no indication if it ever occurs.
+
+Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/flexcan.c | 67 ++++++++++++++++++++++------------------------
+ 1 file changed, 33 insertions(+), 34 deletions(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -135,13 +135,12 @@
+
+ /* FLEXCAN interrupt flag register (IFLAG) bits */
+ /* Errata ERR005829 step7: Reserve first valid MB */
+-#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8
+-#define FLEXCAN_TX_MB_OFF_FIFO 9
++#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8
+ #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0
+-#define FLEXCAN_TX_MB_OFF_TIMESTAMP 1
+-#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1)
+-#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST 63
+-#define FLEXCAN_IFLAG_MB(x) BIT(x)
++#define FLEXCAN_TX_MB 63
++#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1)
++#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST (FLEXCAN_TX_MB - 1)
++#define FLEXCAN_IFLAG_MB(x) BIT(x & 0x1f)
+ #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
+ #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
+ #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
+@@ -745,9 +744,9 @@ static inline u64 flexcan_read_reg_iflag
+ struct flexcan_regs __iomem *regs = priv->regs;
+ u32 iflag1, iflag2;
+
+- iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default;
+- iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default &
++ iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default &
+ ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
++ iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default;
+
+ return (u64)iflag2 << 32 | iflag1;
+ }
+@@ -759,11 +758,9 @@ static irqreturn_t flexcan_irq(int irq,
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->regs;
+ irqreturn_t handled = IRQ_NONE;
+- u32 reg_iflag1, reg_esr;
++ u32 reg_iflag2, reg_esr;
+ enum can_state last_state = priv->can.state;
+
+- reg_iflag1 = priv->read(®s->iflag1);
+-
+ /* reception interrupt */
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
+ u64 reg_iflag;
+@@ -777,6 +774,9 @@ static irqreturn_t flexcan_irq(int irq,
+ break;
+ }
+ } else {
++ u32 reg_iflag1;
++
++ reg_iflag1 = priv->read(®s->iflag1);
+ if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) {
+ handled = IRQ_HANDLED;
+ can_rx_offload_irq_offload_fifo(&priv->offload);
+@@ -792,8 +792,10 @@ static irqreturn_t flexcan_irq(int irq,
+ }
+ }
+
++ reg_iflag2 = priv->read(®s->iflag2);
++
+ /* transmission complete interrupt */
+- if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
++ if (reg_iflag2 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
+ u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl);
+
+ handled = IRQ_HANDLED;
+@@ -805,7 +807,7 @@ static irqreturn_t flexcan_irq(int irq,
+ /* after sending a RTR frame MB is in RX mode */
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+ &priv->tx_mb->can_ctrl);
+- priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1);
++ priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag2);
+ netif_wake_queue(dev);
+ }
+
+@@ -947,15 +949,13 @@ static int flexcan_chip_start(struct net
+ reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
+ reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
+ FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
+- FLEXCAN_MCR_IDAM_C;
++ FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
+
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
++ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
+ reg_mcr &= ~FLEXCAN_MCR_FEN;
+- reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last);
+- } else {
+- reg_mcr |= FLEXCAN_MCR_FEN |
+- FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
+- }
++ else
++ reg_mcr |= FLEXCAN_MCR_FEN;
++
+ netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
+ priv->write(reg_mcr, ®s->mcr);
+
+@@ -998,16 +998,17 @@ static int flexcan_chip_start(struct net
+ priv->write(reg_ctrl2, ®s->ctrl2);
+ }
+
+- /* clear and invalidate all mailboxes first */
+- for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
+- priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
+- ®s->mb[i].can_ctrl);
+- }
+-
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
+- for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
++ for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) {
+ priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
+ ®s->mb[i].can_ctrl);
++ }
++ } else {
++ /* clear and invalidate unused mailboxes first */
++ for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= ARRAY_SIZE(regs->mb); i++) {
++ priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
++ ®s->mb[i].can_ctrl);
++ }
+ }
+
+ /* Errata ERR005829: mark first TX mailbox as INACTIVE */
+@@ -1371,17 +1372,15 @@ static int flexcan_probe(struct platform
+ priv->devtype_data = devtype_data;
+ priv->reg_xceiver = reg_xceiver;
+
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
+- priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP;
++ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
+ priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP];
+- } else {
+- priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO;
++ else
+ priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO];
+- }
++ priv->tx_mb_idx = FLEXCAN_TX_MB;
+ priv->tx_mb = ®s->mb[priv->tx_mb_idx];
+
+- priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
+- priv->reg_imask2_default = 0;
++ priv->reg_imask1_default = 0;
++ priv->reg_imask2_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
+
+ priv->offload.mailbox_read = flexcan_mailbox_read;
+
--- /dev/null
+From ed72bc8bcb9277061e753faf300b20f97323761c Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+Date: Tue, 18 Sep 2018 11:40:39 +0200
+Subject: can: flexcan: handle tx-complete CAN frames via rx-offload infrastructure
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+commit ed72bc8bcb9277061e753faf300b20f97323761c upstream.
+
+Current flexcan driver will put TX-ECHO in regular unsorted way, in
+this case TX-ECHO can come after the response to the same TXed message.
+In some cases, for example for J1939 stack, things will break.
+This patch is using new rx-offload API to put the messages just in the
+right place.
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/flexcan.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -794,8 +794,11 @@ static irqreturn_t flexcan_irq(int irq,
+
+ /* transmission complete interrupt */
+ if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
++ u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl);
++
+ handled = IRQ_HANDLED;
+- stats->tx_bytes += can_get_echo_skb(dev, 0);
++ stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload,
++ 0, reg_ctrl << 16);
+ stats->tx_packets++;
+ can_led_event(dev, CAN_LED_EVENT_TX);
+
--- /dev/null
+From e05237f9da42ee52e73acea0bb082d788e111229 Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Fri, 9 Nov 2018 15:01:50 +0100
+Subject: can: flexcan: remove not needed struct flexcan_priv::tx_mb and struct flexcan_priv::tx_mb_idx
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit e05237f9da42ee52e73acea0bb082d788e111229 upstream.
+
+The previous patch changes the TX path to always use the last mailbox
+regardless of the used offload scheme (rx-fifo or timestamp based). This
+means members "tx_mb" and "tx_mb_idx" of the struct flexcan_priv don't
+depend on the offload scheme, so replace them by compile time constants.
+
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/flexcan.c | 27 ++++++++++++---------------
+ 1 file changed, 12 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -258,9 +258,7 @@ struct flexcan_priv {
+ struct can_rx_offload offload;
+
+ struct flexcan_regs __iomem *regs;
+- struct flexcan_mb __iomem *tx_mb;
+ struct flexcan_mb __iomem *tx_mb_reserved;
+- u8 tx_mb_idx;
+ u32 reg_ctrl_default;
+ u32 reg_imask1_default;
+ u32 reg_imask2_default;
+@@ -514,6 +512,7 @@ static int flexcan_get_berr_counter(cons
+ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ const struct flexcan_priv *priv = netdev_priv(dev);
++ struct flexcan_regs __iomem *regs = priv->regs;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u32 can_id;
+ u32 data;
+@@ -536,17 +535,17 @@ static netdev_tx_t flexcan_start_xmit(st
+
+ if (cf->can_dlc > 0) {
+ data = be32_to_cpup((__be32 *)&cf->data[0]);
+- priv->write(data, &priv->tx_mb->data[0]);
++ priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[0]);
+ }
+ if (cf->can_dlc > 4) {
+ data = be32_to_cpup((__be32 *)&cf->data[4]);
+- priv->write(data, &priv->tx_mb->data[1]);
++ priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[1]);
+ }
+
+ can_put_echo_skb(skb, dev, 0);
+
+- priv->write(can_id, &priv->tx_mb->can_id);
+- priv->write(ctrl, &priv->tx_mb->can_ctrl);
++ priv->write(can_id, ®s->mb[FLEXCAN_TX_MB].can_id);
++ priv->write(ctrl, ®s->mb[FLEXCAN_TX_MB].can_ctrl);
+
+ /* Errata ERR005829 step8:
+ * Write twice INACTIVE(0x8) code to first MB.
+@@ -745,7 +744,7 @@ static inline u64 flexcan_read_reg_iflag
+ u32 iflag1, iflag2;
+
+ iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default &
+- ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
++ ~FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB);
+ iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default;
+
+ return (u64)iflag2 << 32 | iflag1;
+@@ -795,7 +794,7 @@ static irqreturn_t flexcan_irq(int irq,
+ reg_iflag2 = priv->read(®s->iflag2);
+
+ /* transmission complete interrupt */
+- if (reg_iflag2 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
++ if (reg_iflag2 & FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB)) {
+ u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl);
+
+ handled = IRQ_HANDLED;
+@@ -806,8 +805,8 @@ static irqreturn_t flexcan_irq(int irq,
+
+ /* after sending a RTR frame MB is in RX mode */
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+- &priv->tx_mb->can_ctrl);
+- priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag2);
++ ®s->mb[FLEXCAN_TX_MB].can_ctrl);
++ priv->write(FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB), ®s->iflag2);
+ netif_wake_queue(dev);
+ }
+
+@@ -949,7 +948,7 @@ static int flexcan_chip_start(struct net
+ reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
+ reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
+ FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
+- FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
++ FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_MB);
+
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
+ reg_mcr &= ~FLEXCAN_MCR_FEN;
+@@ -1017,7 +1016,7 @@ static int flexcan_chip_start(struct net
+
+ /* mark TX mailbox as INACTIVE */
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+- &priv->tx_mb->can_ctrl);
++ ®s->mb[FLEXCAN_TX_MB].can_ctrl);
+
+ /* acceptance mask/acceptance code (accept everything) */
+ priv->write(0x0, ®s->rxgmask);
+@@ -1376,11 +1375,9 @@ static int flexcan_probe(struct platform
+ priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP];
+ else
+ priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO];
+- priv->tx_mb_idx = FLEXCAN_TX_MB;
+- priv->tx_mb = ®s->mb[priv->tx_mb_idx];
+
+ priv->reg_imask1_default = 0;
+- priv->reg_imask2_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
++ priv->reg_imask2_default = FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB);
+
+ priv->offload.mailbox_read = flexcan_mailbox_read;
+
--- /dev/null
+From 5178b7cd8e42448b1041716f124734eaaa36ca50 Mon Sep 17 00:00:00 2001
+From: Pankaj Bansal <pankaj.bansal@nxp.com>
+Date: Wed, 1 Aug 2018 19:36:46 +0530
+Subject: can: flexcan: Unlock the MB unconditionally
+
+From: Pankaj Bansal <pankaj.bansal@nxp.com>
+
+commit 5178b7cd8e42448b1041716f124734eaaa36ca50 upstream.
+
+Unlock the MB irrespective of reception method being FIFO or timestamp
+based. It is optional but recommended to unlock Mailbox as soon as
+possible and make it available for reception.
+
+Reported-by: Alexander Stein <alexander.stein@systec-electronic.com>
+Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/flexcan.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -720,9 +720,14 @@ static unsigned int flexcan_mailbox_read
+ priv->write(BIT(n - 32), ®s->iflag2);
+ } else {
+ priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
+- priv->read(®s->timer);
+ }
+
++ /* Read the Free Running Timer. It is optional but recommended
++ * to unlock Mailbox as soon as possible and make it available
++ * for reception.
++ */
++ priv->read(®s->timer);
++
+ return 1;
+ }
+
--- /dev/null
+From d788905f68fd4714c82936f6f7f1d3644d7ae7ef Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+Date: Tue, 18 Sep 2018 11:40:41 +0200
+Subject: can: flexcan: use can_rx_offload_queue_sorted() for flexcan_irq_bus_*()
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+commit d788905f68fd4714c82936f6f7f1d3644d7ae7ef upstream.
+
+Currently, in case of bus error, driver will generate error message and put
+in the tail of the message queue. To avoid confusions, this change should
+place the bus related messages in proper order.
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/flexcan.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -563,9 +563,13 @@ static netdev_tx_t flexcan_start_xmit(st
+ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
+ {
+ struct flexcan_priv *priv = netdev_priv(dev);
++ struct flexcan_regs __iomem *regs = priv->regs;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ bool rx_errors = false, tx_errors = false;
++ u32 timestamp;
++
++ timestamp = priv->read(®s->timer) << 16;
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (unlikely(!skb))
+@@ -612,17 +616,21 @@ static void flexcan_irq_bus_err(struct n
+ if (tx_errors)
+ dev->stats.tx_errors++;
+
+- can_rx_offload_queue_tail(&priv->offload, skb);
++ can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
+ }
+
+ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
+ {
+ struct flexcan_priv *priv = netdev_priv(dev);
++ struct flexcan_regs __iomem *regs = priv->regs;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ enum can_state new_state, rx_state, tx_state;
+ int flt;
+ struct can_berr_counter bec;
++ u32 timestamp;
++
++ timestamp = priv->read(®s->timer) << 16;
+
+ flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
+ if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
+@@ -652,7 +660,7 @@ static void flexcan_irq_state(struct net
+ if (unlikely(new_state == CAN_STATE_BUS_OFF))
+ can_bus_off(dev);
+
+- can_rx_offload_queue_tail(&priv->offload, skb);
++ can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
+ }
+
+ static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
--- /dev/null
+From f164d0204b1156a7e0d8d1622c1a8d25752befec Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sat, 27 Oct 2018 10:36:54 +0200
+Subject: can: hi311x: Use level-triggered interrupt
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit f164d0204b1156a7e0d8d1622c1a8d25752befec upstream.
+
+If the hi3110 shares the SPI bus with another traffic-intensive device
+and packets are received in high volume (by a separate machine sending
+with "cangen -g 0 -i -x"), reception stops after a few minutes and the
+counter in /proc/interrupts stops incrementing. Bus state is "active".
+Bringing the interface down and back up reconvenes the reception. The
+issue is not observed when the hi3110 is the sole device on the SPI bus.
+
+Using a level-triggered interrupt makes the issue go away and lets the
+hi3110 successfully receive 2 GByte over the course of 5 days while a
+ks8851 Ethernet chip on the same SPI bus handles 6 GByte of traffic.
+
+Unfortunately the hi3110 datasheet is mum on the trigger type. The pin
+description on page 3 only specifies the polarity (active high):
+http://www.holtic.com/documents/371-hi-3110_v-rev-kpdf.do
+
+Cc: Mathias Duckeck <m.duckeck@kunbus.de>
+Cc: Akshay Bhat <akshay.bhat@timesys.com>
+Cc: Casey Fitzpatrick <casey.fitzpatrick@timesys.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/devicetree/bindings/net/can/holt_hi311x.txt | 2 +-
+ drivers/net/can/spi/hi311x.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/net/can/holt_hi311x.txt
++++ b/Documentation/devicetree/bindings/net/can/holt_hi311x.txt
+@@ -17,7 +17,7 @@ Example:
+ reg = <1>;
+ clocks = <&clk32m>;
+ interrupt-parent = <&gpio4>;
+- interrupts = <13 IRQ_TYPE_EDGE_RISING>;
++ interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
+ vdd-supply = <®5v0>;
+ xceiver-supply = <®5v0>;
+ };
+--- a/drivers/net/can/spi/hi311x.c
++++ b/drivers/net/can/spi/hi311x.c
+@@ -760,7 +760,7 @@ static int hi3110_open(struct net_device
+ {
+ struct hi3110_priv *priv = netdev_priv(net);
+ struct spi_device *spi = priv->spi;
+- unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_RISING;
++ unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_HIGH;
+ int ret;
+
+ ret = open_candev(net);
--- /dev/null
+From a43608fa77213ad5ac5f75994254b9f65d57cfa0 Mon Sep 17 00:00:00 2001
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+Date: Wed, 24 Oct 2018 10:27:12 +0200
+Subject: can: raw: check for CAN FD capable netdev in raw_sendmsg()
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+commit a43608fa77213ad5ac5f75994254b9f65d57cfa0 upstream.
+
+When the socket is CAN FD enabled it can handle CAN FD frame
+transmissions. Add an additional check in raw_sendmsg() as a CAN2.0 CAN
+driver (non CAN FD) should never see a CAN FD frame. Due to the commonly
+used can_dropped_invalid_skb() function the CAN 2.0 driver would drop
+that CAN FD frame anyway - but with this patch the user gets a proper
+-EINVAL return code.
+
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/can/raw.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -745,18 +745,19 @@ static int raw_sendmsg(struct socket *so
+ } else
+ ifindex = ro->ifindex;
+
+- if (ro->fd_frames) {
++ dev = dev_get_by_index(sock_net(sk), ifindex);
++ if (!dev)
++ return -ENXIO;
++
++ err = -EINVAL;
++ if (ro->fd_frames && dev->mtu == CANFD_MTU) {
+ if (unlikely(size != CANFD_MTU && size != CAN_MTU))
+- return -EINVAL;
++ goto put_dev;
+ } else {
+ if (unlikely(size != CAN_MTU))
+- return -EINVAL;
++ goto put_dev;
+ }
+
+- dev = dev_get_by_index(sock_net(sk), ifindex);
+- if (!dev)
+- return -ENXIO;
+-
+ skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv),
+ msg->msg_flags & MSG_DONTWAIT, &err);
+ if (!skb)
--- /dev/null
+From 55059f2b7f868cd43b3ad30e28e18347e1b46ace Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+Date: Tue, 18 Sep 2018 11:40:38 +0200
+Subject: can: rx-offload: introduce can_rx_offload_get_echo_skb() and can_rx_offload_queue_sorted() functions
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+commit 55059f2b7f868cd43b3ad30e28e18347e1b46ace upstream.
+
+Current CAN framework can't guarantee proper/chronological order
+of RX and TX-ECHO messages. To make this possible, drivers should use
+this functions instead of can_get_echo_skb().
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/rx-offload.c | 46 +++++++++++++++++++++++++++++++++++++++++
+ include/linux/can/rx-offload.h | 4 +++
+ 2 files changed, 50 insertions(+)
+
+--- a/drivers/net/can/rx-offload.c
++++ b/drivers/net/can/rx-offload.c
+@@ -209,6 +209,52 @@ int can_rx_offload_irq_offload_fifo(stru
+ }
+ EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo);
+
++int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
++ struct sk_buff *skb, u32 timestamp)
++{
++ struct can_rx_offload_cb *cb;
++ unsigned long flags;
++
++ if (skb_queue_len(&offload->skb_queue) >
++ offload->skb_queue_len_max)
++ return -ENOMEM;
++
++ cb = can_rx_offload_get_cb(skb);
++ cb->timestamp = timestamp;
++
++ spin_lock_irqsave(&offload->skb_queue.lock, flags);
++ __skb_queue_add_sort(&offload->skb_queue, skb, can_rx_offload_compare);
++ spin_unlock_irqrestore(&offload->skb_queue.lock, flags);
++
++ can_rx_offload_schedule(offload);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted);
++
++unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
++ unsigned int idx, u32 timestamp)
++{
++ struct net_device *dev = offload->dev;
++ struct net_device_stats *stats = &dev->stats;
++ struct sk_buff *skb;
++ u8 len;
++ int err;
++
++ skb = __can_get_echo_skb(dev, idx, &len);
++ if (!skb)
++ return 0;
++
++ err = can_rx_offload_queue_sorted(offload, skb, timestamp);
++ if (err) {
++ stats->rx_errors++;
++ stats->tx_fifo_errors++;
++ }
++
++ return len;
++}
++EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb);
++
+ int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb)
+ {
+ if (skb_queue_len(&offload->skb_queue) >
+--- a/include/linux/can/rx-offload.h
++++ b/include/linux/can/rx-offload.h
+@@ -41,6 +41,10 @@ int can_rx_offload_add_timestamp(struct
+ int can_rx_offload_add_fifo(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight);
+ int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 reg);
+ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload);
++int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
++ struct sk_buff *skb, u32 timestamp);
++unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
++ unsigned int idx, u32 timestamp);
+ int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb);
+ void can_rx_offload_reset(struct can_rx_offload *offload);
+ void can_rx_offload_del(struct can_rx_offload *offload);
--- /dev/null
+From 4530ec36bb1e0d24f41c33229694adacda3d5d89 Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+Date: Tue, 18 Sep 2018 11:40:40 +0200
+Subject: can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to can_rx_offload_queue_tail()
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+commit 4530ec36bb1e0d24f41c33229694adacda3d5d89 upstream.
+
+This function has nothing todo with error.
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Cc: linux-stable <stable@vger.kernel.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/flexcan.c | 4 ++--
+ drivers/net/can/rx-offload.c | 5 +++--
+ include/linux/can/rx-offload.h | 3 ++-
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -612,7 +612,7 @@ static void flexcan_irq_bus_err(struct n
+ if (tx_errors)
+ dev->stats.tx_errors++;
+
+- can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
++ can_rx_offload_queue_tail(&priv->offload, skb);
+ }
+
+ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
+@@ -652,7 +652,7 @@ static void flexcan_irq_state(struct net
+ if (unlikely(new_state == CAN_STATE_BUS_OFF))
+ can_bus_off(dev);
+
+- can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
++ can_rx_offload_queue_tail(&priv->offload, skb);
+ }
+
+ static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
+--- a/drivers/net/can/rx-offload.c
++++ b/drivers/net/can/rx-offload.c
+@@ -255,7 +255,8 @@ unsigned int can_rx_offload_get_echo_skb
+ }
+ EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb);
+
+-int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb)
++int can_rx_offload_queue_tail(struct can_rx_offload *offload,
++ struct sk_buff *skb)
+ {
+ if (skb_queue_len(&offload->skb_queue) >
+ offload->skb_queue_len_max)
+@@ -266,7 +267,7 @@ int can_rx_offload_irq_queue_err_skb(str
+
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(can_rx_offload_irq_queue_err_skb);
++EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail);
+
+ static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight)
+ {
+--- a/include/linux/can/rx-offload.h
++++ b/include/linux/can/rx-offload.h
+@@ -45,7 +45,8 @@ int can_rx_offload_queue_sorted(struct c
+ struct sk_buff *skb, u32 timestamp);
+ unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
+ unsigned int idx, u32 timestamp);
+-int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb);
++int can_rx_offload_queue_tail(struct can_rx_offload *offload,
++ struct sk_buff *skb);
+ void can_rx_offload_reset(struct can_rx_offload *offload);
+ void can_rx_offload_del(struct can_rx_offload *offload);
+ void can_rx_offload_enable(struct can_rx_offload *offload);
--- /dev/null
+From 8d4d7c58994759bbd9f4fec32d88bf0e0b89302e Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 19 Nov 2018 12:55:12 +0100
+Subject: drm/amdgpu: Add missing firmware entry for HAINAN
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 8d4d7c58994759bbd9f4fec32d88bf0e0b89302e upstream.
+
+Due to lack of MODULE_FIRMWARE() with hainan_mc.bin, the driver
+doesn't work properly in initrd. Let's add it.
+
+Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1116239
+Fixes: 8eaf2b1faaf4 ("drm/amdgpu: switch firmware path for SI parts")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+@@ -45,6 +45,7 @@ MODULE_FIRMWARE("amdgpu/tahiti_mc.bin");
+ MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin");
+ MODULE_FIRMWARE("amdgpu/verde_mc.bin");
+ MODULE_FIRMWARE("amdgpu/oland_mc.bin");
++MODULE_FIRMWARE("amdgpu/hainan_mc.bin");
+ MODULE_FIRMWARE("amdgpu/si58_mc.bin");
+
+ #define MC_SEQ_MISC0__MT__MASK 0xf0000000
--- /dev/null
+From 919a52fc4ca137c871f295224507fa3401e08472 Mon Sep 17 00:00:00 2001
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+Date: Fri, 20 Jul 2018 11:37:25 -0400
+Subject: drm/amdgpu: Fix oops when pp_funcs->switch_power_profile is unset
+
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+
+commit 919a52fc4ca137c871f295224507fa3401e08472 upstream.
+
+On Vega20 and other pre-production GPUs, powerplay is not enabled yet.
+Check for NULL pointers before calling pp_funcs function pointers.
+
+Also affects Kaveri.
+
+CC: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Tested-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+@@ -496,8 +496,11 @@ void amdgpu_amdkfd_set_compute_idle(stru
+ {
+ struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
+
+- amdgpu_dpm_switch_power_profile(adev,
+- PP_SMC_POWER_PROFILE_COMPUTE, !idle);
++ if (adev->powerplay.pp_funcs &&
++ adev->powerplay.pp_funcs->switch_power_profile)
++ amdgpu_dpm_switch_power_profile(adev,
++ PP_SMC_POWER_PROFILE_COMPUTE,
++ !idle);
+ }
+
+ bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
--- /dev/null
+From 1a37bd823891568f8721989aed0615835632d81a Mon Sep 17 00:00:00 2001
+From: "Y.C. Chen" <yc_chen@aspeedtech.com>
+Date: Wed, 3 Oct 2018 14:57:47 +0800
+Subject: drm/ast: change resolution may cause screen blurred
+
+From: Y.C. Chen <yc_chen@aspeedtech.com>
+
+commit 1a37bd823891568f8721989aed0615835632d81a upstream.
+
+The value of pitches is not correct while calling mode_set.
+The issue we found so far on following system:
+- Debian8 with XFCE Desktop
+- Ubuntu with KDE Desktop
+- SUSE15 with KDE Desktop
+
+Signed-off-by: Y.C. Chen <yc_chen@aspeedtech.com>
+Cc: <stable@vger.kernel.org>
+Tested-by: Jean Delvare <jdelvare@suse.de>
+Reviewed-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ast/ast_mode.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/ast/ast_mode.c
++++ b/drivers/gpu/drm/ast/ast_mode.c
+@@ -568,6 +568,7 @@ static int ast_crtc_do_set_base(struct d
+ }
+ ast_bo_unreserve(bo);
+
++ ast_set_offset_reg(crtc);
+ ast_set_start_address_crt1(crtc, (u32)gpu_addr);
+
+ return 0;
--- /dev/null
+From 7989b9ee8bafe5cc625381dd0c3c4586de27ca26 Mon Sep 17 00:00:00 2001
+From: "Y.C. Chen" <yc_chen@aspeedtech.com>
+Date: Tue, 30 Oct 2018 11:34:46 +0800
+Subject: drm/ast: fixed cursor may disappear sometimes
+
+From: Y.C. Chen <yc_chen@aspeedtech.com>
+
+commit 7989b9ee8bafe5cc625381dd0c3c4586de27ca26 upstream.
+
+Signed-off-by: Y.C. Chen <yc_chen@aspeedtech.com>
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ast/ast_mode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/ast/ast_mode.c
++++ b/drivers/gpu/drm/ast/ast_mode.c
+@@ -1255,7 +1255,7 @@ static int ast_cursor_move(struct drm_cr
+ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07));
+
+ /* dummy write to fire HWC */
+- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xCB, 0xFF, 0x00);
++ ast_show_cursor(crtc);
+
+ return 0;
+ }
--- /dev/null
+From 5478ad10e7850ce3d8b7056db05ddfa3c9ddad9a Mon Sep 17 00:00:00 2001
+From: Thomas Zimmermann <tzimmermann@suse.de>
+Date: Thu, 15 Nov 2018 11:42:16 +0100
+Subject: drm/ast: Remove existing framebuffers before loading driver
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+commit 5478ad10e7850ce3d8b7056db05ddfa3c9ddad9a upstream.
+
+If vesafb attaches to the AST device, it configures the framebuffer memory
+for uncached access by default. When ast.ko later tries to attach itself to
+the device, it wants to use write-combining on the framebuffer memory, but
+vesefb's existing configuration for uncached access takes precedence. This
+results in reduced performance.
+
+Removing the framebuffer's configuration before loding the AST driver fixes
+the problem. Other DRM drivers already contain equivalent code.
+
+Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1112963
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: <stable@vger.kernel.org>
+Tested-by: Y.C. Chen <yc_chen@aspeedtech.com>
+Reviewed-by: Jean Delvare <jdelvare@suse.de>
+Tested-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ast/ast_drv.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/drivers/gpu/drm/ast/ast_drv.c
++++ b/drivers/gpu/drm/ast/ast_drv.c
+@@ -60,8 +60,29 @@ static const struct pci_device_id pciidl
+
+ MODULE_DEVICE_TABLE(pci, pciidlist);
+
++static void ast_kick_out_firmware_fb(struct pci_dev *pdev)
++{
++ struct apertures_struct *ap;
++ bool primary = false;
++
++ ap = alloc_apertures(1);
++ if (!ap)
++ return;
++
++ ap->ranges[0].base = pci_resource_start(pdev, 0);
++ ap->ranges[0].size = pci_resource_len(pdev, 0);
++
++#ifdef CONFIG_X86
++ primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
++#endif
++ drm_fb_helper_remove_conflicting_framebuffers(ap, "astdrmfb", primary);
++ kfree(ap);
++}
++
+ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
++ ast_kick_out_firmware_fb(pdev);
++
+ return drm_get_pci_dev(pdev, ent, &driver);
+ }
+
--- /dev/null
+From 8fd3b90300bec541806dac271de2fd44e2e4e2d2 Mon Sep 17 00:00:00 2001
+From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+Date: Thu, 15 Nov 2018 17:32:48 +0100
+Subject: drm/fb-helper: Blacklist writeback when adding connectors to fbdev
+
+From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+
+commit 8fd3b90300bec541806dac271de2fd44e2e4e2d2 upstream.
+
+Writeback connectors do not produce any on-screen output and require
+special care for use. Such connectors are hidden from enumeration in
+DRM resources by default, but they are still picked-up by fbdev.
+This makes rather little sense since fbdev is not really adapted for
+dealing with writeback.
+
+Moreover, this is also a source of issues when userspace disables the
+CRTC (and associated plane) without detaching the CRTC from the
+connector (which is hidden by default). In this case, the connector is
+still using the CRTC, leading to am "enabled/connectors mismatch" and
+eventually the failure of the associated atomic commit. This situation
+happens with VC4 testing under IGT GPU Tools.
+
+Filter out writeback connectors in the fbdev helper to solve this.
+
+Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
+Reviewed-by: Maxime Ripard <maxime.ripard@bootlin.com>
+Tested-by: Maxime Ripard <maxime.ripard@bootlin.com>
+Fixes: 935774cd71fe ("drm: Add writeback connector type")
+Cc: <stable@vger.kernel.org> # v4.19+
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20181115163248.21168-1-paul.kocialkowski@bootlin.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_fb_helper.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/gpu/drm/drm_fb_helper.c
++++ b/drivers/gpu/drm/drm_fb_helper.c
+@@ -200,6 +200,9 @@ int drm_fb_helper_single_add_all_connect
+ mutex_lock(&fb_helper->lock);
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
++ if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
++ continue;
++
+ ret = __drm_fb_helper_add_one_connector(fb_helper, connector);
+ if (ret)
+ goto fail;
--- /dev/null
+From 21556350ade3cb5d7afecc8b3544e56431d21695 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Wed, 14 Nov 2018 19:34:40 +0200
+Subject: drm/i915: Disable LP3 watermarks on all SNB machines
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 21556350ade3cb5d7afecc8b3544e56431d21695 upstream.
+
+I have a Thinkpad X220 Tablet in my hands that is losing vblank
+interrupts whenever LP3 watermarks are used.
+
+If I nudge the latency value written to the WM3 register just
+by one in either direction the problem disappears. That to me
+suggests that the punit will not enter the corrsponding
+powersave mode (MPLL shutdown IIRC) unless the latency value
+in the register matches exactly what we read from SSKPD. Ie.
+it's not really a latency value but rather just a cookie
+by which the punit can identify the desired power saving state.
+On HSW/BDW this was changed such that we actually just write
+the WM level number into those bits, which makes much more
+sense given the observed behaviour.
+
+We could try to handle this by disallowing LP3 watermarks
+only when vblank interrupts are enabled but we'd first have
+to prove that only vblank interrupts are affected, which
+seems unlikely. Also we can't grab the wm mutex from the
+vblank enable/disable hooks because those are called with
+various spinlocks held. Thus we'd have to redesigne the
+watermark locking. So to play it safe and keep the code
+simple we simply disable LP3 watermarks on all SNB machines.
+
+To do that we simply zero out the latency values for
+watermark level 3, and we adjust the watermark computation
+to check for that. The behaviour now matches that of the
+g4x/vlv/skl wm code in the presence of a zeroed latency
+value.
+
+v2: s/USHRT_MAX/U32_MAX/ for consistency with the types (Chris)
+
+Cc: stable@vger.kernel.org
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101269
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103713
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20181114173440.6730-1-ville.syrjala@linux.intel.com
+(cherry picked from commit 03981c6ebec4fc7056b9b45f847393aeac90d060)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_pm.c | 41 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 40 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2492,6 +2492,9 @@ static uint32_t ilk_compute_pri_wm(const
+ uint32_t method1, method2;
+ int cpp;
+
++ if (mem_value == 0)
++ return U32_MAX;
++
+ if (!intel_wm_plane_visible(cstate, pstate))
+ return 0;
+
+@@ -2521,6 +2524,9 @@ static uint32_t ilk_compute_spr_wm(const
+ uint32_t method1, method2;
+ int cpp;
+
++ if (mem_value == 0)
++ return U32_MAX;
++
+ if (!intel_wm_plane_visible(cstate, pstate))
+ return 0;
+
+@@ -2544,6 +2550,9 @@ static uint32_t ilk_compute_cur_wm(const
+ {
+ int cpp;
+
++ if (mem_value == 0)
++ return U32_MAX;
++
+ if (!intel_wm_plane_visible(cstate, pstate))
+ return 0;
+
+@@ -2998,6 +3007,34 @@ static void snb_wm_latency_quirk(struct
+ intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
+ }
+
++static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv)
++{
++ /*
++ * On some SNB machines (Thinkpad X220 Tablet at least)
++ * LP3 usage can cause vblank interrupts to be lost.
++ * The DEIIR bit will go high but it looks like the CPU
++ * never gets interrupted.
++ *
++ * It's not clear whether other interrupt source could
++ * be affected or if this is somehow limited to vblank
++ * interrupts only. To play it safe we disable LP3
++ * watermarks entirely.
++ */
++ if (dev_priv->wm.pri_latency[3] == 0 &&
++ dev_priv->wm.spr_latency[3] == 0 &&
++ dev_priv->wm.cur_latency[3] == 0)
++ return;
++
++ dev_priv->wm.pri_latency[3] = 0;
++ dev_priv->wm.spr_latency[3] = 0;
++ dev_priv->wm.cur_latency[3] = 0;
++
++ DRM_DEBUG_KMS("LP3 watermarks disabled due to potential for lost interrupts\n");
++ intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency);
++ intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency);
++ intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
++}
++
+ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv)
+ {
+ intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency);
+@@ -3014,8 +3051,10 @@ static void ilk_setup_wm_latency(struct
+ intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency);
+ intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency);
+
+- if (IS_GEN6(dev_priv))
++ if (IS_GEN6(dev_priv)) {
+ snb_wm_latency_quirk(dev_priv);
++ snb_wm_lp3_irq_quirk(dev_priv);
++ }
+ }
+
+ static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
--- /dev/null
+From fcc86cb45d38ca2f24bcea9c29c7f4742041caed Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@bootlin.com>
+Date: Thu, 15 Nov 2018 11:58:52 +0100
+Subject: drm/vc4: Set ->legacy_cursor_update to false when doing non-async updates
+
+From: Boris Brezillon <boris.brezillon@bootlin.com>
+
+commit fcc86cb45d38ca2f24bcea9c29c7f4742041caed upstream.
+
+drm_atomic_helper_setup_commit() auto-completes commit->flip_done when
+state->legacy_cursor_update is true, but we know for sure that we want
+a sync update when we call drm_atomic_helper_setup_commit() from
+vc4_atomic_commit().
+
+Explicitly set state->legacy_cursor_update to false to prevent this
+auto-completion.
+
+Fixes: 184d3cf4f738 ("drm/vc4: Use wait_for_flip_done() instead of wait_for_vblanks()")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Link: https://patchwork.freedesktop.org/patch/msgid/20181115105852.9844-2-boris.brezillon@bootlin.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -216,6 +216,12 @@ static int vc4_atomic_commit(struct drm_
+ return 0;
+ }
+
++ /* We know for sure we don't want an async update here. Set
++ * state->legacy_cursor_update to false to prevent
++ * drm_atomic_helper_setup_commit() from auto-completing
++ * commit->flip_done.
++ */
++ state->legacy_cursor_update = false;
+ ret = drm_atomic_helper_setup_commit(state, nonblock);
+ if (ret)
+ return ret;
mm-don-t-warn-about-large-allocations-for-slab.patch
mm-memory.c-recheck-page-table-entry-with-page-table-lock-held.patch
tcp-do-not-release-socket-ownership-in-tcp_close.patch
+drm-fb-helper-blacklist-writeback-when-adding-connectors-to-fbdev.patch
+drm-amdgpu-add-missing-firmware-entry-for-hainan.patch
+drm-vc4-set-legacy_cursor_update-to-false-when-doing-non-async-updates.patch
+drm-amdgpu-fix-oops-when-pp_funcs-switch_power_profile-is-unset.patch
+drm-i915-disable-lp3-watermarks-on-all-snb-machines.patch
+drm-ast-change-resolution-may-cause-screen-blurred.patch
+drm-ast-fixed-cursor-may-disappear-sometimes.patch
+drm-ast-remove-existing-framebuffers-before-loading-driver.patch
+can-flexcan-unlock-the-mb-unconditionally.patch
+can-dev-can_get_echo_skb-factor-out-non-sending-code-to-__can_get_echo_skb.patch
+can-dev-__can_get_echo_skb-replace-struct-can_frame-by-canfd_frame-to-access-frame-length.patch
+can-dev-__can_get_echo_skb-don-t-crash-the-kernel-if-can_priv-echo_skb-is-accessed-out-of-bounds.patch
+can-dev-__can_get_echo_skb-print-error-message-if-trying-to-echo-non-existing-skb.patch
+can-rx-offload-introduce-can_rx_offload_get_echo_skb-and-can_rx_offload_queue_sorted-functions.patch
+can-rx-offload-rename-can_rx_offload_irq_queue_err_skb-to-can_rx_offload_queue_tail.patch
+can-flexcan-use-can_rx_offload_queue_sorted-for-flexcan_irq_bus_.patch
+can-flexcan-handle-tx-complete-can-frames-via-rx-offload-infrastructure.patch
+can-raw-check-for-can-fd-capable-netdev-in-raw_sendmsg.patch
+can-hi311x-use-level-triggered-interrupt.patch
+can-flexcan-always-use-last-mailbox-for-tx.patch
+can-flexcan-remove-not-needed-struct-flexcan_priv-tx_mb-and-struct-flexcan_priv-tx_mb_idx.patch