Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad72c347 authored by Christian Pellegrin's avatar Christian Pellegrin Committed by David S. Miller
Browse files

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: default avatarChristian Pellegrin <chripell@fsfe.org>
Acked-by: default avatarWolfgang Grandegger <wg@grandegger.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1954dc11
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1073,6 +1073,7 @@ static int __init at91_can_probe(struct platform_device *pdev)
	priv->can.bittiming_const = &at91_bittiming_const;
	priv->can.do_set_bittiming = at91_set_bittiming;
	priv->can.do_set_mode = at91_set_mode;
	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
	priv->reg_base = addr;
	priv->dev = dev;
	priv->clk = clk;
+1 −0
Original line number Diff line number Diff line
@@ -603,6 +603,7 @@ struct net_device *alloc_bfin_candev(void)
	priv->can.bittiming_const = &bfin_can_bittiming_const;
	priv->can.do_set_bittiming = bfin_can_set_bittiming;
	priv->can.do_set_mode = bfin_can_set_mode;
	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;

	return dev;
}
+2 −0
Original line number Diff line number Diff line
@@ -592,6 +592,8 @@ static int can_changelink(struct net_device *dev,
		if (dev->flags & IFF_UP)
			return -EBUSY;
		cm = nla_data(data[IFLA_CAN_CTRLMODE]);
		if (cm->flags & ~priv->ctrlmode_supported)
			return -EOPNOTSUPP;
		priv->ctrlmode &= ~cm->mask;
		priv->ctrlmode |= cm->flags;
	}
+10 −1
Original line number Diff line number Diff line
@@ -539,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;
@@ -948,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);

+1 −0
Original line number Diff line number Diff line
@@ -686,6 +686,7 @@ struct net_device *alloc_mscandev(void)
	priv->can.bittiming_const = &mscan_bittiming_const;
	priv->can.do_set_bittiming = mscan_do_set_bittiming;
	priv->can.do_set_mode = mscan_do_set_mode;
	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;

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