summaryrefslogtreecommitdiff
path: root/drivers/net/can/mcp251x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/mcp251x.c')
-rw-r--r--drivers/net/can/mcp251x.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index 1a72ca066a17..bbe186b5a0ed 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -494,12 +494,8 @@ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
- if (skb->len != sizeof(struct can_frame)) {
- dev_err(&spi->dev, "dropping packet - bad length\n");
- dev_kfree_skb(skb);
- net->stats.tx_dropped++;
+ if (can_dropped_invalid_skb(net, skb))
return NETDEV_TX_OK;
- }
netif_stop_queue(net);
priv->tx_skb = skb;
@@ -543,9 +539,14 @@ static void mcp251x_set_normal_mode(struct spi_device *spi)
if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
/* Put device into loopback mode */
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+ /* Put device into listen-only mode */
+ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY);
} else {
/* Put device into normal mode */
- mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);
+ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL |
+ (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT ?
+ CANCTRL_OSM : 0));
/* Wait for the device to enter normal mode */
timeout = jiffies + HZ;
@@ -952,6 +953,10 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
priv->can.bittiming_const = &mcp251x_bittiming_const;
priv->can.do_set_mode = mcp251x_do_set_mode;
priv->can.clock.freq = pdata->oscillator_frequency / 2;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
+ if (pdata->model == CAN_MCP251X_MCP2515)
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;
priv->net = net;
dev_set_drvdata(&spi->dev, priv);