Commit 4315ef8d authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-fixes-for-3.19-20150115' of...

Merge tag 'linux-can-fixes-for-3.19-20150115' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2015-01-15

this is a pull request of 8 patches.

Ahmed S. Darwish contributes 4 fixes for the kvaser_usb driver. The two patches
by Oliver Hartkopp mark the m_can driver as non-ISO, as the CANFD standard was
updated. Roger Quadros's patch for the c_can driver fixes the register access
during RAMINIT. And one patch by my, which updates the MAINTAINERS file, as we
moved the git repos to the kernel.org infrastructure.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5eff6dad a58518cc
...@@ -2346,7 +2346,8 @@ CAN NETWORK LAYER ...@@ -2346,7 +2346,8 @@ CAN NETWORK LAYER
M: Oliver Hartkopp <socketcan@hartkopp.net> M: Oliver Hartkopp <socketcan@hartkopp.net>
L: linux-can@vger.kernel.org L: linux-can@vger.kernel.org
W: http://gitorious.org/linux-can W: http://gitorious.org/linux-can
T: git git://gitorious.org/linux-can/linux-can-next.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git
S: Maintained S: Maintained
F: Documentation/networking/can.txt F: Documentation/networking/can.txt
F: net/can/ F: net/can/
...@@ -2361,7 +2362,8 @@ M: Wolfgang Grandegger <wg@grandegger.com> ...@@ -2361,7 +2362,8 @@ M: Wolfgang Grandegger <wg@grandegger.com>
M: Marc Kleine-Budde <mkl@pengutronix.de> M: Marc Kleine-Budde <mkl@pengutronix.de>
L: linux-can@vger.kernel.org L: linux-can@vger.kernel.org
W: http://gitorious.org/linux-can W: http://gitorious.org/linux-can
T: git git://gitorious.org/linux-can/linux-can-next.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git
S: Maintained S: Maintained
F: drivers/net/can/ F: drivers/net/can/
F: include/linux/can/dev.h F: include/linux/can/dev.h
......
...@@ -103,27 +103,34 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable) ...@@ -103,27 +103,34 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
mask = 1 << raminit->bits.start | 1 << raminit->bits.done; mask = 1 << raminit->bits.start | 1 << raminit->bits.done;
regmap_read(raminit->syscon, raminit->reg, &ctrl); regmap_read(raminit->syscon, raminit->reg, &ctrl);
/* We clear the done and start bit first. The start bit is /* We clear the start bit first. The start bit is
* looking at the 0 -> transition, but is not self clearing; * looking at the 0 -> transition, but is not self clearing;
* And we clear the init done bit as well.
* NOTE: DONE must be written with 1 to clear it. * NOTE: DONE must be written with 1 to clear it.
* We can't clear the DONE bit here using regmap_update_bits()
* as it will bypass the write if initial condition is START:0 DONE:1
* e.g. on DRA7 which needs START pulse.
*/ */
ctrl &= ~(1 << raminit->bits.start); ctrl &= ~mask; /* START = 0, DONE = 0 */
ctrl |= 1 << raminit->bits.done; regmap_update_bits(raminit->syscon, raminit->reg, mask, ctrl);
regmap_write(raminit->syscon, raminit->reg, ctrl);
ctrl &= ~(1 << raminit->bits.done); /* check if START bit is 0. Ignore DONE bit for now
c_can_hw_raminit_wait_syscon(priv, mask, ctrl); * as it can be either 0 or 1.
*/
c_can_hw_raminit_wait_syscon(priv, 1 << raminit->bits.start, ctrl);
if (enable) { if (enable) {
/* Set start bit and wait for the done bit. */ /* Clear DONE bit & set START bit. */
ctrl |= 1 << raminit->bits.start; ctrl |= 1 << raminit->bits.start;
regmap_write(raminit->syscon, raminit->reg, ctrl); /* DONE must be written with 1 to clear it */
ctrl |= 1 << raminit->bits.done;
regmap_update_bits(raminit->syscon, raminit->reg, mask, ctrl);
/* prevent further clearing of DONE bit */
ctrl &= ~(1 << raminit->bits.done);
/* clear START bit if start pulse is needed */ /* clear START bit if start pulse is needed */
if (raminit->needs_pulse) { if (raminit->needs_pulse) {
ctrl &= ~(1 << raminit->bits.start); ctrl &= ~(1 << raminit->bits.start);
regmap_write(raminit->syscon, raminit->reg, ctrl); regmap_update_bits(raminit->syscon, raminit->reg,
mask, ctrl);
} }
ctrl |= 1 << raminit->bits.done; ctrl |= 1 << raminit->bits.done;
......
...@@ -807,10 +807,14 @@ static int can_changelink(struct net_device *dev, ...@@ -807,10 +807,14 @@ static int can_changelink(struct net_device *dev,
if (dev->flags & IFF_UP) if (dev->flags & IFF_UP)
return -EBUSY; return -EBUSY;
cm = nla_data(data[IFLA_CAN_CTRLMODE]); cm = nla_data(data[IFLA_CAN_CTRLMODE]);
if (cm->flags & ~priv->ctrlmode_supported)
/* check whether changed bits are allowed to be modified */
if (cm->mask & ~priv->ctrlmode_supported)
return -EOPNOTSUPP; return -EOPNOTSUPP;
/* clear bits to be modified and copy the flag values */
priv->ctrlmode &= ~cm->mask; priv->ctrlmode &= ~cm->mask;
priv->ctrlmode |= cm->flags; priv->ctrlmode |= (cm->flags & cm->mask);
/* CAN_CTRLMODE_FD can only be set when driver supports FD */ /* CAN_CTRLMODE_FD can only be set when driver supports FD */
if (priv->ctrlmode & CAN_CTRLMODE_FD) if (priv->ctrlmode & CAN_CTRLMODE_FD)
......
...@@ -955,6 +955,11 @@ static struct net_device *alloc_m_can_dev(void) ...@@ -955,6 +955,11 @@ static struct net_device *alloc_m_can_dev(void)
priv->can.data_bittiming_const = &m_can_data_bittiming_const; priv->can.data_bittiming_const = &m_can_data_bittiming_const;
priv->can.do_set_mode = m_can_set_mode; priv->can.do_set_mode = m_can_set_mode;
priv->can.do_get_berr_counter = m_can_get_berr_counter; priv->can.do_get_berr_counter = m_can_get_berr_counter;
/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.1 */
priv->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO;
/* CAN_CTRLMODE_FD_NON_ISO can not be changed with M_CAN IP v3.0.1 */
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_BERR_REPORTING |
......
...@@ -520,10 +520,10 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, ...@@ -520,10 +520,10 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
skb = alloc_can_err_skb(priv->netdev, &cf); skb = alloc_can_err_skb(priv->netdev, &cf);
if (skb) { if (skb) {
cf->can_id |= CAN_ERR_RESTARTED; cf->can_id |= CAN_ERR_RESTARTED;
netif_rx(skb);
stats->rx_packets++; stats->rx_packets++;
stats->rx_bytes += cf->can_dlc; stats->rx_bytes += cf->can_dlc;
netif_rx(skb);
} else { } else {
netdev_err(priv->netdev, netdev_err(priv->netdev,
"No memory left for err_skb\n"); "No memory left for err_skb\n");
...@@ -770,10 +770,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, ...@@ -770,10 +770,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
priv->can.state = new_state; priv->can.state = new_state;
netif_rx(skb);
stats->rx_packets++; stats->rx_packets++;
stats->rx_bytes += cf->can_dlc; stats->rx_bytes += cf->can_dlc;
netif_rx(skb);
} }
static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv,
...@@ -805,10 +804,9 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, ...@@ -805,10 +804,9 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv,
stats->rx_over_errors++; stats->rx_over_errors++;
stats->rx_errors++; stats->rx_errors++;
netif_rx(skb);
stats->rx_packets++; stats->rx_packets++;
stats->rx_bytes += cf->can_dlc; stats->rx_bytes += cf->can_dlc;
netif_rx(skb);
} }
} }
...@@ -887,10 +885,9 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, ...@@ -887,10 +885,9 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
cf->can_dlc); cf->can_dlc);
} }
netif_rx(skb);
stats->rx_packets++; stats->rx_packets++;
stats->rx_bytes += cf->can_dlc; stats->rx_bytes += cf->can_dlc;
netif_rx(skb);
} }
static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev, static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev,
...@@ -1246,6 +1243,9 @@ static int kvaser_usb_close(struct net_device *netdev) ...@@ -1246,6 +1243,9 @@ static int kvaser_usb_close(struct net_device *netdev)
if (err) if (err)
netdev_warn(netdev, "Cannot stop device, error %d\n", err); netdev_warn(netdev, "Cannot stop device, error %d\n", err);
/* reset tx contexts */
kvaser_usb_unlink_tx_urbs(priv);
priv->can.state = CAN_STATE_STOPPED; priv->can.state = CAN_STATE_STOPPED;
close_candev(priv->netdev); close_candev(priv->netdev);
...@@ -1294,12 +1294,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, ...@@ -1294,12 +1294,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (!urb) { if (!urb) {
netdev_err(netdev, "No memory left for URBs\n"); netdev_err(netdev, "No memory left for URBs\n");
stats->tx_dropped++; stats->tx_dropped++;
goto nourbmem; dev_kfree_skb(skb);
return NETDEV_TX_OK;
} }
buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
if (!buf) { if (!buf) {
stats->tx_dropped++; stats->tx_dropped++;
dev_kfree_skb(skb);
goto nobufmem; goto nobufmem;
} }
...@@ -1334,6 +1336,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, ...@@ -1334,6 +1336,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
} }
} }
/* This should never happen; it implies a flow control bug */
if (!context) { if (!context) {
netdev_warn(netdev, "cannot find free context\n"); netdev_warn(netdev, "cannot find free context\n");
ret = NETDEV_TX_BUSY; ret = NETDEV_TX_BUSY;
...@@ -1364,9 +1367,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, ...@@ -1364,9 +1367,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (unlikely(err)) { if (unlikely(err)) {
can_free_echo_skb(netdev, context->echo_index); can_free_echo_skb(netdev, context->echo_index);
skb = NULL; /* set to NULL to avoid double free in
* dev_kfree_skb(skb) */
atomic_dec(&priv->active_tx_urbs); atomic_dec(&priv->active_tx_urbs);
usb_unanchor_urb(urb); usb_unanchor_urb(urb);
...@@ -1388,8 +1388,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, ...@@ -1388,8 +1388,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
kfree(buf); kfree(buf);
nobufmem: nobufmem:
usb_free_urb(urb); usb_free_urb(urb);
nourbmem:
dev_kfree_skb(skb);
return ret; return ret;
} }
...@@ -1502,6 +1500,10 @@ static int kvaser_usb_init_one(struct usb_interface *intf, ...@@ -1502,6 +1500,10 @@ static int kvaser_usb_init_one(struct usb_interface *intf,
struct kvaser_usb_net_priv *priv; struct kvaser_usb_net_priv *priv;
int i, err; int i, err;
err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, channel);
if (err)
return err;
netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS);
if (!netdev) { if (!netdev) {
dev_err(&intf->dev, "Cannot alloc candev\n"); dev_err(&intf->dev, "Cannot alloc candev\n");
...@@ -1606,9 +1608,6 @@ static int kvaser_usb_probe(struct usb_interface *intf, ...@@ -1606,9 +1608,6 @@ static int kvaser_usb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, dev); usb_set_intfdata(intf, dev);
for (i = 0; i < MAX_NET_DEVICES; i++)
kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i);
err = kvaser_usb_get_software_info(dev); err = kvaser_usb_get_software_info(dev);
if (err) { if (err) {
dev_err(&intf->dev, dev_err(&intf->dev,
......
...@@ -98,6 +98,7 @@ struct can_ctrlmode { ...@@ -98,6 +98,7 @@ struct can_ctrlmode {
#define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */ #define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */
#define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */ #define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */
#define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */ #define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */
#define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */
/* /*
* CAN device statistics * CAN device statistics
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment