Skip to content

Commit ad72c34

Browse files
Christian Pellegrindavem330
authored andcommitted
can: Proper ctrlmode handling for CAN devices
This patch adds error checking of ctrlmode values for CAN devices. As an example all availabe bits are implemented in the mcp251x driver. Signed-off-by: Christian Pellegrin <[email protected]> Acked-by: Wolfgang Grandegger <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1954dc1 commit ad72c34

File tree

9 files changed

+19
-1
lines changed

9 files changed

+19
-1
lines changed

drivers/net/can/at91_can.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,7 @@ static int __init at91_can_probe(struct platform_device *pdev)
10731073
priv->can.bittiming_const = &at91_bittiming_const;
10741074
priv->can.do_set_bittiming = at91_set_bittiming;
10751075
priv->can.do_set_mode = at91_set_mode;
1076+
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
10761077
priv->reg_base = addr;
10771078
priv->dev = dev;
10781079
priv->clk = clk;

drivers/net/can/bfin_can.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ struct net_device *alloc_bfin_candev(void)
603603
priv->can.bittiming_const = &bfin_can_bittiming_const;
604604
priv->can.do_set_bittiming = bfin_can_set_bittiming;
605605
priv->can.do_set_mode = bfin_can_set_mode;
606+
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
606607

607608
return dev;
608609
}

drivers/net/can/dev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,8 @@ static int can_changelink(struct net_device *dev,
592592
if (dev->flags & IFF_UP)
593593
return -EBUSY;
594594
cm = nla_data(data[IFLA_CAN_CTRLMODE]);
595+
if (cm->flags & ~priv->ctrlmode_supported)
596+
return -EOPNOTSUPP;
595597
priv->ctrlmode &= ~cm->mask;
596598
priv->ctrlmode |= cm->flags;
597599
}

drivers/net/can/mcp251x.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,14 @@ static void mcp251x_set_normal_mode(struct spi_device *spi)
539539
if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
540540
/* Put device into loopback mode */
541541
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
542+
} else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
543+
/* Put device into listen-only mode */
544+
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY);
542545
} else {
543546
/* Put device into normal mode */
544-
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);
547+
mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL |
548+
(priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT ?
549+
CANCTRL_OSM : 0));
545550

546551
/* Wait for the device to enter normal mode */
547552
timeout = jiffies + HZ;
@@ -948,6 +953,10 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
948953
priv->can.bittiming_const = &mcp251x_bittiming_const;
949954
priv->can.do_set_mode = mcp251x_do_set_mode;
950955
priv->can.clock.freq = pdata->oscillator_frequency / 2;
956+
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
957+
CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
958+
if (pdata->model == CAN_MCP251X_MCP2515)
959+
priv->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;
951960
priv->net = net;
952961
dev_set_drvdata(&spi->dev, priv);
953962

drivers/net/can/mscan/mscan.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ struct net_device *alloc_mscandev(void)
686686
priv->can.bittiming_const = &mscan_bittiming_const;
687687
priv->can.do_set_bittiming = mscan_do_set_bittiming;
688688
priv->can.do_set_mode = mscan_do_set_mode;
689+
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
689690

690691
for (i = 0; i < TX_QUEUE_SIZE; i++) {
691692
priv->tx_queue[i].id = i;

drivers/net/can/sja1000/sja1000.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
567567
priv->can.bittiming_const = &sja1000_bittiming_const;
568568
priv->can.do_set_bittiming = sja1000_set_bittiming;
569569
priv->can.do_set_mode = sja1000_set_mode;
570+
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
570571

571572
if (sizeof_priv)
572573
priv->priv = (void *)priv + sizeof(struct sja1000_priv);

drivers/net/can/ti_hecc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
909909
priv->can.bittiming_const = &ti_hecc_bittiming_const;
910910
priv->can.do_set_mode = ti_hecc_do_set_mode;
911911
priv->can.do_get_state = ti_hecc_get_state;
912+
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
912913

913914
ndev->irq = irq->start;
914915
ndev->flags |= IFF_ECHO;

drivers/net/can/usb/ems_usb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,7 @@ static int ems_usb_probe(struct usb_interface *intf,
10221022
dev->can.bittiming_const = &ems_usb_bittiming_const;
10231023
dev->can.do_set_bittiming = ems_usb_set_bittiming;
10241024
dev->can.do_set_mode = ems_usb_set_mode;
1025+
dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
10251026

10261027
netdev->flags |= IFF_ECHO; /* we support local echo */
10271028

include/linux/can/dev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct can_priv {
3838

3939
enum can_state state;
4040
u32 ctrlmode;
41+
u32 ctrlmode_supported;
4142

4243
int restart_ms;
4344
struct timer_list restart_timer;

0 commit comments

Comments
 (0)