diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-12 11:16:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-12 11:16:40 -0400 |
commit | 4665c6b04651e96c1e2eb9129a30d6055040ff73 (patch) | |
tree | 6180e9d85532d4f8d519881f6eeebd1b8e3da4e9 | |
parent | bf2ae2e4bf9360e07c0cdfa166bcdc0afd92f4ce (diff) | |
parent | c9b3bce18da4a0aebc27853052dea39aa64b7d75 (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.c | 75 | ||||
-rw-r--r-- | drivers/net/can/m_can/m_can.c | 7 | ||||
-rw-r--r-- | drivers/net/can/peak_canfd/peak_canfd.c | 25 | ||||
-rw-r--r-- | drivers/net/can/peak_canfd/peak_pciefd_main.c | 8 |
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 | ||
364 | static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr) | 377 | static 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 | ||
513 | static int ifi_canfd_handle_state_errors(struct net_device *ndev, u32 stcmd) | 532 | static 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 */ |