Skip to content

Commit 7146b2d

Browse files
andreas-gaislerdavem330
authored andcommitted
can: sja1000: Add support for listen-only mode and one-shot mode
One-shot mode uses the TCS bit of the status register to discern whether a transmission was successful or not. On a failed transmission, the frame is not echoed back. Signed-off-by: Andreas Larsson <[email protected]> Acked-by: Wolfgang Grandegger <[email protected]> Acked-by: Oliver Hartkopp <[email protected]> Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent f61bd05 commit 7146b2d

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

drivers/net/can/sja1000/sja1000.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,13 @@ static void set_normal_mode(struct net_device *dev)
156156
}
157157

158158
/* set chip to normal mode */
159-
priv->write_reg(priv, REG_MOD, 0x00);
159+
if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
160+
priv->write_reg(priv, REG_MOD, MOD_LOM);
161+
else
162+
priv->write_reg(priv, REG_MOD, 0x00);
163+
160164
udelay(10);
165+
161166
status = priv->read_reg(priv, REG_MOD);
162167
}
163168

@@ -310,7 +315,10 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
310315

311316
can_put_echo_skb(skb, dev, 0);
312317

313-
sja1000_write_cmdreg(priv, CMD_TR);
318+
if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
319+
sja1000_write_cmdreg(priv, CMD_TR | CMD_AT);
320+
else
321+
sja1000_write_cmdreg(priv, CMD_TR);
314322

315323
return NETDEV_TX_OK;
316324
}
@@ -505,10 +513,18 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
505513
netdev_warn(dev, "wakeup interrupt\n");
506514

507515
if (isrc & IRQ_TI) {
508-
/* transmission complete interrupt */
509-
stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xf;
510-
stats->tx_packets++;
511-
can_get_echo_skb(dev, 0);
516+
/* transmission buffer released */
517+
if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT &&
518+
!(status & SR_TCS)) {
519+
stats->tx_errors++;
520+
can_free_echo_skb(dev, 0);
521+
} else {
522+
/* transmission complete */
523+
stats->tx_bytes +=
524+
priv->read_reg(priv, REG_FI) & 0xf;
525+
stats->tx_packets++;
526+
can_get_echo_skb(dev, 0);
527+
}
512528
netif_wake_queue(dev);
513529
}
514530
if (isrc & IRQ_RI) {
@@ -605,7 +621,8 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
605621
priv->can.do_set_mode = sja1000_set_mode;
606622
priv->can.do_get_berr_counter = sja1000_get_berr_counter;
607623
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
608-
CAN_CTRLMODE_BERR_REPORTING;
624+
CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_LISTENONLY |
625+
CAN_CTRLMODE_ONE_SHOT;
609626

610627
spin_lock_init(&priv->cmdreg_lock);
611628

0 commit comments

Comments
 (0)