aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-03-12 11:16:40 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-12 11:16:40 -0400
commit4665c6b04651e96c1e2eb9129a30d6055040ff73 (patch)
tree6180e9d85532d4f8d519881f6eeebd1b8e3da4e9
parentbf2ae2e4bf9360e07c0cdfa166bcdc0afd92f4ce (diff)
parentc9b3bce18da4a0aebc27853052dea39aa64b7d75 (diff)
Merge tag 'linux-can-fixes-for-4.16-20180312' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2018-03-12 this is a pull reqeust of 6 patches for net/master. The first patch is by Wolfram Sang and fixes a bitshift vs. comparison mistake in the m_can driver. Two patches of Marek Vasut repair the error handling in the ifi driver. The two patches by Stephane Grosjean fix a "echo_skb is occupied!" bug in the peak/pcie_fd driver. Bich HEMON's patch adds pinctrl select state calls to the m_can's driver to further improve power saving during suspend. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/can/ifi_canfd/ifi_canfd.c75
-rw-r--r--drivers/net/can/m_can/m_can.c7
-rw-r--r--drivers/net/can/peak_canfd/peak_canfd.c25
-rw-r--r--drivers/net/can/peak_canfd/peak_pciefd_main.c8
4 files changed, 67 insertions, 48 deletions
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 2772d05ff11c..fedd927ba6ed 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -30,6 +30,7 @@
30#define IFI_CANFD_STCMD_ERROR_ACTIVE BIT(2) 30#define IFI_CANFD_STCMD_ERROR_ACTIVE BIT(2)
31#define IFI_CANFD_STCMD_ERROR_PASSIVE BIT(3) 31#define IFI_CANFD_STCMD_ERROR_PASSIVE BIT(3)
32#define IFI_CANFD_STCMD_BUSOFF BIT(4) 32#define IFI_CANFD_STCMD_BUSOFF BIT(4)
33#define IFI_CANFD_STCMD_ERROR_WARNING BIT(5)
33#define IFI_CANFD_STCMD_BUSMONITOR BIT(16) 34#define IFI_CANFD_STCMD_BUSMONITOR BIT(16)
34#define IFI_CANFD_STCMD_LOOPBACK BIT(18) 35#define IFI_CANFD_STCMD_LOOPBACK BIT(18)
35#define IFI_CANFD_STCMD_DISABLE_CANFD BIT(24) 36#define IFI_CANFD_STCMD_DISABLE_CANFD BIT(24)
@@ -52,7 +53,10 @@
52#define IFI_CANFD_TXSTCMD_OVERFLOW BIT(13) 53#define IFI_CANFD_TXSTCMD_OVERFLOW BIT(13)
53 54
54#define IFI_CANFD_INTERRUPT 0xc 55#define IFI_CANFD_INTERRUPT 0xc
56#define IFI_CANFD_INTERRUPT_ERROR_BUSOFF BIT(0)
55#define IFI_CANFD_INTERRUPT_ERROR_WARNING BIT(1) 57#define IFI_CANFD_INTERRUPT_ERROR_WARNING BIT(1)
58#define IFI_CANFD_INTERRUPT_ERROR_STATE_CHG BIT(2)
59#define IFI_CANFD_INTERRUPT_ERROR_REC_TEC_INC BIT(3)
56#define IFI_CANFD_INTERRUPT_ERROR_COUNTER BIT(10) 60#define IFI_CANFD_INTERRUPT_ERROR_COUNTER BIT(10)
57#define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY BIT(16) 61#define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY BIT(16)
58#define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE BIT(22) 62#define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE BIT(22)
@@ -61,6 +65,10 @@
61#define IFI_CANFD_INTERRUPT_SET_IRQ ((u32)BIT(31)) 65#define IFI_CANFD_INTERRUPT_SET_IRQ ((u32)BIT(31))
62 66
63#define IFI_CANFD_IRQMASK 0x10 67#define IFI_CANFD_IRQMASK 0x10
68#define IFI_CANFD_IRQMASK_ERROR_BUSOFF BIT(0)
69#define IFI_CANFD_IRQMASK_ERROR_WARNING BIT(1)
70#define IFI_CANFD_IRQMASK_ERROR_STATE_CHG BIT(2)
71#define IFI_CANFD_IRQMASK_ERROR_REC_TEC_INC BIT(3)
64#define IFI_CANFD_IRQMASK_SET_ERR BIT(7) 72#define IFI_CANFD_IRQMASK_SET_ERR BIT(7)
65#define IFI_CANFD_IRQMASK_SET_TS BIT(15) 73#define IFI_CANFD_IRQMASK_SET_TS BIT(15)
66#define IFI_CANFD_IRQMASK_TXFIFO_EMPTY BIT(16) 74#define IFI_CANFD_IRQMASK_TXFIFO_EMPTY BIT(16)
@@ -136,6 +144,8 @@
136#define IFI_CANFD_SYSCLOCK 0x50 144#define IFI_CANFD_SYSCLOCK 0x50
137 145
138#define IFI_CANFD_VER 0x54 146#define IFI_CANFD_VER 0x54
147#define IFI_CANFD_VER_REV_MASK 0xff
148#define IFI_CANFD_VER_REV_MIN_SUPPORTED 0x15
139 149
140#define IFI_CANFD_IP_ID 0x58 150#define IFI_CANFD_IP_ID 0x58
141#define IFI_CANFD_IP_ID_VALUE 0xD073CAFD 151#define IFI_CANFD_IP_ID_VALUE 0xD073CAFD
@@ -220,7 +230,10 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable)
220 230
221 if (enable) { 231 if (enable) {
222 enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY | 232 enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY |
223 IFI_CANFD_IRQMASK_RXFIFO_NEMPTY; 233 IFI_CANFD_IRQMASK_RXFIFO_NEMPTY |
234 IFI_CANFD_IRQMASK_ERROR_STATE_CHG |
235 IFI_CANFD_IRQMASK_ERROR_WARNING |
236 IFI_CANFD_IRQMASK_ERROR_BUSOFF;
224 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) 237 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
225 enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER; 238 enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER;
226 } 239 }
@@ -361,12 +374,13 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev)
361 return 1; 374 return 1;
362} 375}
363 376
364static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr) 377static int ifi_canfd_handle_lec_err(struct net_device *ndev)
365{ 378{
366 struct ifi_canfd_priv *priv = netdev_priv(ndev); 379 struct ifi_canfd_priv *priv = netdev_priv(ndev);
367 struct net_device_stats *stats = &ndev->stats; 380 struct net_device_stats *stats = &ndev->stats;
368 struct can_frame *cf; 381 struct can_frame *cf;
369 struct sk_buff *skb; 382 struct sk_buff *skb;
383 u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
370 const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST | 384 const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST |
371 IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST | 385 IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST |
372 IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST | 386 IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST |
@@ -449,6 +463,11 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
449 463
450 switch (new_state) { 464 switch (new_state) {
451 case CAN_STATE_ERROR_ACTIVE: 465 case CAN_STATE_ERROR_ACTIVE:
466 /* error active state */
467 priv->can.can_stats.error_warning++;
468 priv->can.state = CAN_STATE_ERROR_ACTIVE;
469 break;
470 case CAN_STATE_ERROR_WARNING:
452 /* error warning state */ 471 /* error warning state */
453 priv->can.can_stats.error_warning++; 472 priv->can.can_stats.error_warning++;
454 priv->can.state = CAN_STATE_ERROR_WARNING; 473 priv->can.state = CAN_STATE_ERROR_WARNING;
@@ -477,7 +496,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
477 ifi_canfd_get_berr_counter(ndev, &bec); 496 ifi_canfd_get_berr_counter(ndev, &bec);
478 497
479 switch (new_state) { 498 switch (new_state) {
480 case CAN_STATE_ERROR_ACTIVE: 499 case CAN_STATE_ERROR_WARNING:
481 /* error warning state */ 500 /* error warning state */
482 cf->can_id |= CAN_ERR_CRTL; 501 cf->can_id |= CAN_ERR_CRTL;
483 cf->data[1] = (bec.txerr > bec.rxerr) ? 502 cf->data[1] = (bec.txerr > bec.rxerr) ?
@@ -510,22 +529,21 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
510 return 1; 529 return 1;
511} 530}
512 531
513static int ifi_canfd_handle_state_errors(struct net_device *ndev, u32 stcmd) 532static int ifi_canfd_handle_state_errors(struct net_device *ndev)
514{ 533{
515 struct ifi_canfd_priv *priv = netdev_priv(ndev); 534 struct ifi_canfd_priv *priv = netdev_priv(ndev);
535 u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
516 int work_done = 0; 536 int work_done = 0;
517 u32 isr;
518 537
519 /* 538 if ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) &&
520 * The ErrWarn condition is a little special, since the bit is 539 (priv->can.state != CAN_STATE_ERROR_ACTIVE)) {
521 * located in the INTERRUPT register instead of STCMD register. 540 netdev_dbg(ndev, "Error, entered active state\n");
522 */ 541 work_done += ifi_canfd_handle_state_change(ndev,
523 isr = readl(priv->base + IFI_CANFD_INTERRUPT); 542 CAN_STATE_ERROR_ACTIVE);
524 if ((isr & IFI_CANFD_INTERRUPT_ERROR_WARNING) && 543 }
544
545 if ((stcmd & IFI_CANFD_STCMD_ERROR_WARNING) &&
525 (priv->can.state != CAN_STATE_ERROR_WARNING)) { 546 (priv->can.state != CAN_STATE_ERROR_WARNING)) {
526 /* Clear the interrupt */
527 writel(IFI_CANFD_INTERRUPT_ERROR_WARNING,
528 priv->base + IFI_CANFD_INTERRUPT);
529 netdev_dbg(ndev, "Error, entered warning state\n"); 547 netdev_dbg(ndev, "Error, entered warning state\n");
530 work_done += ifi_canfd_handle_state_change(ndev, 548 work_done += ifi_canfd_handle_state_change(ndev,
531 CAN_STATE_ERROR_WARNING); 549 CAN_STATE_ERROR_WARNING);
@@ -552,18 +570,11 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
552{ 570{
553 struct net_device *ndev = napi->dev; 571 struct net_device *ndev = napi->dev;
554 struct ifi_canfd_priv *priv = netdev_priv(ndev); 572 struct ifi_canfd_priv *priv = netdev_priv(ndev);
555 const u32 stcmd_state_mask = IFI_CANFD_STCMD_ERROR_PASSIVE |
556 IFI_CANFD_STCMD_BUSOFF;
557 int work_done = 0;
558
559 u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
560 u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD); 573 u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD);
561 u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR); 574 int work_done = 0;
562 575
563 /* Handle bus state changes */ 576 /* Handle bus state changes */
564 if ((stcmd & stcmd_state_mask) || 577 work_done += ifi_canfd_handle_state_errors(ndev);
565 ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) == 0))
566 work_done += ifi_canfd_handle_state_errors(ndev, stcmd);
567 578
568 /* Handle lost messages on RX */ 579 /* Handle lost messages on RX */
569 if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW) 580 if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW)
@@ -571,7 +582,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
571 582
572 /* Handle lec errors on the bus */ 583 /* Handle lec errors on the bus */
573 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) 584 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
574 work_done += ifi_canfd_handle_lec_err(ndev, errctr); 585 work_done += ifi_canfd_handle_lec_err(ndev);
575 586
576 /* Handle normal messages on RX */ 587 /* Handle normal messages on RX */
577 if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY)) 588 if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY))
@@ -592,12 +603,13 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
592 struct net_device_stats *stats = &ndev->stats; 603 struct net_device_stats *stats = &ndev->stats;
593 const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY | 604 const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
594 IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER | 605 IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
606 IFI_CANFD_INTERRUPT_ERROR_COUNTER |
607 IFI_CANFD_INTERRUPT_ERROR_STATE_CHG |
595 IFI_CANFD_INTERRUPT_ERROR_WARNING | 608 IFI_CANFD_INTERRUPT_ERROR_WARNING |
596 IFI_CANFD_INTERRUPT_ERROR_COUNTER; 609 IFI_CANFD_INTERRUPT_ERROR_BUSOFF;
597 const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY | 610 const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
598 IFI_CANFD_INTERRUPT_TXFIFO_REMOVE; 611 IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
599 const u32 clr_irq_mask = ~((u32)(IFI_CANFD_INTERRUPT_SET_IRQ | 612 const u32 clr_irq_mask = ~((u32)IFI_CANFD_INTERRUPT_SET_IRQ);
600 IFI_CANFD_INTERRUPT_ERROR_WARNING));
601 u32 isr; 613 u32 isr;
602 614
603 isr = readl(priv->base + IFI_CANFD_INTERRUPT); 615 isr = readl(priv->base + IFI_CANFD_INTERRUPT);
@@ -933,7 +945,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
933 struct resource *res; 945 struct resource *res;
934 void __iomem *addr; 946 void __iomem *addr;
935 int irq, ret; 947 int irq, ret;
936 u32 id; 948 u32 id, rev;
937 949
938 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 950 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
939 addr = devm_ioremap_resource(dev, res); 951 addr = devm_ioremap_resource(dev, res);
@@ -947,6 +959,13 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
947 return -EINVAL; 959 return -EINVAL;
948 } 960 }
949 961
962 rev = readl(addr + IFI_CANFD_VER) & IFI_CANFD_VER_REV_MASK;
963 if (rev < IFI_CANFD_VER_REV_MIN_SUPPORTED) {
964 dev_err(dev, "This block is too old (rev %i), minimum supported is rev %i\n",
965 rev, IFI_CANFD_VER_REV_MIN_SUPPORTED);
966 return -EINVAL;
967 }
968
950 ndev = alloc_candev(sizeof(*priv), 1); 969 ndev = alloc_candev(sizeof(*priv), 1);
951 if (!ndev) 970 if (!ndev)
952 return -ENOMEM; 971 return -ENOMEM;
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 2594f7779c6f..b397a33f3d32 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -26,6 +26,7 @@
26#include <linux/pm_runtime.h> 26#include <linux/pm_runtime.h>
27#include <linux/iopoll.h> 27#include <linux/iopoll.h>
28#include <linux/can/dev.h> 28#include <linux/can/dev.h>
29#include <linux/pinctrl/consumer.h>
29 30
30/* napi related */ 31/* napi related */
31#define M_CAN_NAPI_WEIGHT 64 32#define M_CAN_NAPI_WEIGHT 64
@@ -253,7 +254,7 @@ enum m_can_mram_cfg {
253 254
254/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */ 255/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */
255#define RXFC_FWM_SHIFT 24 256#define RXFC_FWM_SHIFT 24
256#define RXFC_FWM_MASK (0x7f < RXFC_FWM_SHIFT) 257#define RXFC_FWM_MASK (0x7f << RXFC_FWM_SHIFT)
257#define RXFC_FS_SHIFT 16 258#define RXFC_FS_SHIFT 16
258#define RXFC_FS_MASK (0x7f << RXFC_FS_SHIFT) 259#define RXFC_FS_MASK (0x7f << RXFC_FS_SHIFT)
259 260
@@ -1700,6 +1701,8 @@ static __maybe_unused int m_can_suspend(struct device *dev)
1700 m_can_clk_stop(priv); 1701 m_can_clk_stop(priv);
1701 } 1702 }
1702 1703
1704 pinctrl_pm_select_sleep_state(dev);
1705
1703 priv->can.state = CAN_STATE_SLEEPING; 1706 priv->can.state = CAN_STATE_SLEEPING;
1704 1707
1705 return 0; 1708 return 0;
@@ -1710,6 +1713,8 @@ static __maybe_unused int m_can_resume(struct device *dev)
1710 struct net_device *ndev = dev_get_drvdata(dev); 1713 struct net_device *ndev = dev_get_drvdata(dev);
1711 struct m_can_priv *priv = netdev_priv(ndev); 1714 struct m_can_priv *priv = netdev_priv(ndev);
1712 1715
1716 pinctrl_pm_select_default_state(dev);
1717
1713 m_can_init_ram(priv); 1718 m_can_init_ram(priv);
1714 1719
1715 priv->can.state = CAN_STATE_ERROR_ACTIVE; 1720 priv->can.state = CAN_STATE_ERROR_ACTIVE;
diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
index 55513411a82e..ed8561d4a90f 100644
--- a/drivers/net/can/peak_canfd/peak_canfd.c
+++ b/drivers/net/can/peak_canfd/peak_canfd.c
@@ -262,7 +262,6 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,
262 262
263 spin_lock_irqsave(&priv->echo_lock, flags); 263 spin_lock_irqsave(&priv->echo_lock, flags);
264 can_get_echo_skb(priv->ndev, msg->client); 264 can_get_echo_skb(priv->ndev, msg->client);
265 spin_unlock_irqrestore(&priv->echo_lock, flags);
266 265
267 /* count bytes of the echo instead of skb */ 266 /* count bytes of the echo instead of skb */
268 stats->tx_bytes += cf_len; 267 stats->tx_bytes += cf_len;
@@ -271,6 +270,7 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,
271 /* restart tx queue (a slot is free) */ 270 /* restart tx queue (a slot is free) */
272 netif_wake_queue(priv->ndev); 271 netif_wake_queue(priv->ndev);
273 272
273 spin_unlock_irqrestore(&priv->echo_lock, flags);
274 return 0; 274 return 0;
275 } 275 }
276 276
@@ -333,7 +333,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
333 333
334 /* this STATUS is the CNF of the RX_BARRIER: Tx path can be setup */ 334 /* this STATUS is the CNF of the RX_BARRIER: Tx path can be setup */
335 if (pucan_status_is_rx_barrier(msg)) { 335 if (pucan_status_is_rx_barrier(msg)) {
336 unsigned long flags;
337 336
338 if (priv->enable_tx_path) { 337 if (priv->enable_tx_path) {
339 int err = priv->enable_tx_path(priv); 338 int err = priv->enable_tx_path(priv);
@@ -342,16 +341,8 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
342 return err; 341 return err;
343 } 342 }
344 343
345 /* restart network queue only if echo skb array is free */ 344 /* start network queue (echo_skb array is empty) */
346 spin_lock_irqsave(&priv->echo_lock, flags); 345 netif_start_queue(ndev);
347
348 if (!priv->can.echo_skb[priv->echo_idx]) {
349 spin_unlock_irqrestore(&priv->echo_lock, flags);
350
351 netif_wake_queue(ndev);
352 } else {
353 spin_unlock_irqrestore(&priv->echo_lock, flags);
354 }
355 346
356 return 0; 347 return 0;
357 } 348 }
@@ -726,11 +717,6 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
726 */ 717 */
727 should_stop_tx_queue = !!(priv->can.echo_skb[priv->echo_idx]); 718 should_stop_tx_queue = !!(priv->can.echo_skb[priv->echo_idx]);
728 719
729 spin_unlock_irqrestore(&priv->echo_lock, flags);
730
731 /* write the skb on the interface */
732 priv->write_tx_msg(priv, msg);
733
734 /* stop network tx queue if not enough room to save one more msg too */ 720 /* stop network tx queue if not enough room to save one more msg too */
735 if (priv->can.ctrlmode & CAN_CTRLMODE_FD) 721 if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
736 should_stop_tx_queue |= (room_left < 722 should_stop_tx_queue |= (room_left <
@@ -742,6 +728,11 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
742 if (should_stop_tx_queue) 728 if (should_stop_tx_queue)
743 netif_stop_queue(ndev); 729 netif_stop_queue(ndev);
744 730
731 spin_unlock_irqrestore(&priv->echo_lock, flags);
732
733 /* write the skb on the interface */
734 priv->write_tx_msg(priv, msg);
735
745 return NETDEV_TX_OK; 736 return NETDEV_TX_OK;
746} 737}
747 738
diff --git a/drivers/net/can/peak_canfd/peak_pciefd_main.c b/drivers/net/can/peak_canfd/peak_pciefd_main.c
index 788c3464a3b0..3c51a884db87 100644
--- a/drivers/net/can/peak_canfd/peak_pciefd_main.c
+++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c
@@ -349,8 +349,12 @@ static irqreturn_t pciefd_irq_handler(int irq, void *arg)
349 priv->tx_pages_free++; 349 priv->tx_pages_free++;
350 spin_unlock_irqrestore(&priv->tx_lock, flags); 350 spin_unlock_irqrestore(&priv->tx_lock, flags);
351 351
352 /* wake producer up */ 352 /* wake producer up (only if enough room in echo_skb array) */
353 netif_wake_queue(priv->ucan.ndev); 353 spin_lock_irqsave(&priv->ucan.echo_lock, flags);
354 if (!priv->ucan.can.echo_skb[priv->ucan.echo_idx])
355 netif_wake_queue(priv->ucan.ndev);
356
357 spin_unlock_irqrestore(&priv->ucan.echo_lock, flags);
354 } 358 }
355 359
356 /* re-enable Rx DMA transfer for this CAN */ 360 /* re-enable Rx DMA transfer for this CAN */