summaryrefslogtreecommitdiff
path: root/drivers/net/can/sja1000/sja1000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/sja1000/sja1000.c')
-rw-r--r--drivers/net/can/sja1000/sja1000.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index f31499a32d7d..d1692154ed1b 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -141,6 +141,7 @@ static void set_normal_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
unsigned char status = priv->read_reg(priv, SJA1000_MOD);
+ u8 mod_reg_val = 0x00;
int i;
for (i = 0; i < 100; i++) {
@@ -158,9 +159,10 @@ static void set_normal_mode(struct net_device *dev)
/* set chip to normal mode */
if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
- priv->write_reg(priv, SJA1000_MOD, MOD_LOM);
- else
- priv->write_reg(priv, SJA1000_MOD, 0x00);
+ mod_reg_val |= MOD_LOM;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_PRESUME_ACK)
+ mod_reg_val |= MOD_STM;
+ priv->write_reg(priv, SJA1000_MOD, mod_reg_val);
udelay(10);
@@ -278,6 +280,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
uint8_t dlc;
canid_t id;
uint8_t dreg;
+ u8 cmd_reg_val = 0x00;
int i;
if (can_dropped_invalid_skb(dev, skb))
@@ -312,9 +315,14 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
can_put_echo_skb(skb, dev, 0);
if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
- sja1000_write_cmdreg(priv, CMD_TR | CMD_AT);
+ cmd_reg_val |= CMD_AT;
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
+ cmd_reg_val |= CMD_SRR;
else
- sja1000_write_cmdreg(priv, CMD_TR);
+ cmd_reg_val |= CMD_TR;
+
+ sja1000_write_cmdreg(priv, cmd_reg_val);
return NETDEV_TX_OK;
}
@@ -622,9 +630,12 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
priv->can.do_set_bittiming = sja1000_set_bittiming;
priv->can.do_set_mode = sja1000_set_mode;
priv->can.do_get_berr_counter = sja1000_get_berr_counter;
- priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
- CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_LISTENONLY |
- CAN_CTRLMODE_ONE_SHOT;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
+ CAN_CTRLMODE_LISTENONLY |
+ CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_ONE_SHOT |
+ CAN_CTRLMODE_BERR_REPORTING |
+ CAN_CTRLMODE_PRESUME_ACK;
spin_lock_init(&priv->cmdreg_lock);