can: kvaser_pciefd: Do not send EFLUSH command on TFD interrupt
commit262d7a52baupstream. Under certain circumstances we send two EFLUSH commands, resulting in two EFLUSH ack packets, while only expecting a single EFLUSH ack. This can cause the driver Tx flush completion to get out of sync. To avoid this problem, don't enable the "Transmit buffer flush done" (TFD) interrupt and remove the code handling it. Now we only send EFLUSH command after receiving status packet with "Init detected" (IDET) bit set. Fixes:26ad340e58("can: kvaser_pciefd: Add driver for Kvaser PCIEcan devices") Cc: stable@vger.kernel.org Signed-off-by: Jimmy Assarsson <extja@kvaser.com> Link: https://lore.kernel.org/r/20230516134318.104279-6-extja@kvaser.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
65e85232ff
commit
7a7ec807fe
1 changed files with 4 additions and 17 deletions
|
|
@ -533,7 +533,7 @@ static int kvaser_pciefd_set_tx_irq(struct kvaser_pciefd_can *can)
|
|||
KVASER_PCIEFD_KCAN_IRQ_TOF | KVASER_PCIEFD_KCAN_IRQ_ABD |
|
||||
KVASER_PCIEFD_KCAN_IRQ_TAE | KVASER_PCIEFD_KCAN_IRQ_TAL |
|
||||
KVASER_PCIEFD_KCAN_IRQ_FDIC | KVASER_PCIEFD_KCAN_IRQ_BPP |
|
||||
KVASER_PCIEFD_KCAN_IRQ_TAR | KVASER_PCIEFD_KCAN_IRQ_TFD;
|
||||
KVASER_PCIEFD_KCAN_IRQ_TAR;
|
||||
|
||||
iowrite32(msk, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
|
||||
|
||||
|
|
@ -581,7 +581,7 @@ static void kvaser_pciefd_start_controller_flush(struct kvaser_pciefd_can *can)
|
|||
|
||||
spin_lock_irqsave(&can->lock, irq);
|
||||
iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
|
||||
iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD | KVASER_PCIEFD_KCAN_IRQ_TFD,
|
||||
iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
|
||||
can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
|
||||
|
||||
status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG);
|
||||
|
|
@ -624,7 +624,7 @@ static int kvaser_pciefd_bus_on(struct kvaser_pciefd_can *can)
|
|||
iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
|
||||
iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
|
||||
|
||||
iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD | KVASER_PCIEFD_KCAN_IRQ_TFD,
|
||||
iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
|
||||
can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
|
||||
|
||||
mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
|
||||
|
|
@ -1011,8 +1011,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
|
|||
SET_NETDEV_DEV(netdev, &pcie->pci->dev);
|
||||
|
||||
iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
|
||||
iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD |
|
||||
KVASER_PCIEFD_KCAN_IRQ_TFD,
|
||||
iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
|
||||
can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
|
||||
|
||||
pcie->can[i] = can;
|
||||
|
|
@ -1441,9 +1440,6 @@ static int kvaser_pciefd_handle_status_packet(struct kvaser_pciefd *pcie,
|
|||
cmd = KVASER_PCIEFD_KCAN_CMD_AT;
|
||||
cmd |= ++can->cmd_seq << KVASER_PCIEFD_KCAN_CMD_SEQ_SHIFT;
|
||||
iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG);
|
||||
|
||||
iowrite32(KVASER_PCIEFD_KCAN_IRQ_TFD,
|
||||
can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
|
||||
} else if (p->header[0] & KVASER_PCIEFD_SPACK_IDET &&
|
||||
p->header[0] & KVASER_PCIEFD_SPACK_IRM &&
|
||||
cmdseq == (p->header[1] & KVASER_PCIEFD_PACKET_SEQ_MSK) &&
|
||||
|
|
@ -1732,15 +1728,6 @@ static int kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
|
|||
if (irq & KVASER_PCIEFD_KCAN_IRQ_TOF)
|
||||
netdev_err(can->can.dev, "Tx FIFO overflow\n");
|
||||
|
||||
if (irq & KVASER_PCIEFD_KCAN_IRQ_TFD) {
|
||||
u8 count = ioread32(can->reg_base +
|
||||
KVASER_PCIEFD_KCAN_TX_NPACKETS_REG) & 0xff;
|
||||
|
||||
if (count == 0)
|
||||
iowrite32(KVASER_PCIEFD_KCAN_CTRL_EFLUSH,
|
||||
can->reg_base + KVASER_PCIEFD_KCAN_CTRL_REG);
|
||||
}
|
||||
|
||||
if (irq & KVASER_PCIEFD_KCAN_IRQ_BPP)
|
||||
netdev_err(can->can.dev,
|
||||
"Fail to change bittiming, when not in reset mode\n");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue