From 1e6cacdbae2701d33068eebb8d453d67f962cd93 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Wed, 5 Mar 2014 21:31:56 +0400 Subject: [PATCH 01/12] can: mcp251x: Make driver more quiet This patch moves one diagnostic message used for debugging purposes to dev_dbg() and removes one useless message. Signed-off-by: Alexander Shiyan Signed-off-by: Marc Kleine-Budde --- drivers/net/can/mcp251x.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index cdb9808d12dbc..7cc9705bfa4b7 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -601,10 +601,10 @@ static int mcp251x_do_set_bittiming(struct net_device *net) (bt->prop_seg - 1)); mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK, (bt->phase_seg2 - 1)); - dev_info(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n", - mcp251x_read_reg(spi, CNF1), - mcp251x_read_reg(spi, CNF2), - mcp251x_read_reg(spi, CNF3)); + dev_dbg(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n", + mcp251x_read_reg(spi, CNF1), + mcp251x_read_reg(spi, CNF2), + mcp251x_read_reg(spi, CNF3)); return 0; } @@ -1155,8 +1155,6 @@ static int mcp251x_can_probe(struct spi_device *spi) devm_can_led_init(net); - dev_info(&spi->dev, "probed\n"); - return ret; error_probe: From f16a42107377e892d6d4535bbfc46308b4a1cdea Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 22 Feb 2014 09:51:14 +0400 Subject: [PATCH 02/12] can: mcp251x: Remove #ifdef CONFIG_PM_SLEEP This patch removes #ifdef CONFIG_PM_SLEEP to improve compile coverage. Signed-off-by: Alexander Shiyan Signed-off-by: Marc Kleine-Budde --- drivers/net/can/mcp251x.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 7cc9705bfa4b7..50aa630c7dd4f 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -1195,9 +1195,7 @@ static int mcp251x_can_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_PM_SLEEP - -static int mcp251x_can_suspend(struct device *dev) +static int __maybe_unused mcp251x_can_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct mcp251x_priv *priv = spi_get_drvdata(spi); @@ -1227,7 +1225,7 @@ static int mcp251x_can_suspend(struct device *dev) return 0; } -static int mcp251x_can_resume(struct device *dev) +static int __maybe_unused mcp251x_can_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct mcp251x_priv *priv = spi_get_drvdata(spi); @@ -1247,7 +1245,6 @@ static int mcp251x_can_resume(struct device *dev) enable_irq(spi->irq); return 0; } -#endif static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend, mcp251x_can_resume); From 08c6d35154069becb01243176fb72b3bc60ff3cb Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 5 Mar 2014 19:10:44 +0100 Subject: [PATCH 03/12] can: flexcan: Remove #ifdef CONFIG_PM_SLEEP This patch removes #ifdef CONFIG_PM_SLEEP to improve compile coverage. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 61376abdab395..efa1bbc9a1ec0 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1201,8 +1201,7 @@ static int flexcan_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int flexcan_suspend(struct device *device) +static int __maybe_unused flexcan_suspend(struct device *device) { struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); @@ -1221,7 +1220,7 @@ static int flexcan_suspend(struct device *device) return 0; } -static int flexcan_resume(struct device *device) +static int __maybe_unused flexcan_resume(struct device *device) { struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); @@ -1233,7 +1232,6 @@ static int flexcan_resume(struct device *device) } return flexcan_chip_enable(priv); } -#endif /* CONFIG_PM_SLEEP */ static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); From d0873e6fc06686cf2dfb9adabb6ca65e9967c60f Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 4 Mar 2014 22:04:22 +0100 Subject: [PATCH 04/12] can: flexcan: make use of platform_get_device_id() This patch replaces an open coded pdev->id_entry by platform_get_device_id(). Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index efa1bbc9a1ec0..c94d698b73c2d 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1132,9 +1132,9 @@ static int flexcan_probe(struct platform_device *pdev) of_id = of_match_device(flexcan_of_match, &pdev->dev); if (of_id) { devtype_data = of_id->data; - } else if (pdev->id_entry->driver_data) { + } else if (platform_get_device_id(pdev)->driver_data) { devtype_data = (struct flexcan_devtype_data *) - pdev->id_entry->driver_data; + platform_get_device_id(pdev)->driver_data; } else { return -ENODEV; } From a8ca2efce43f81153b81c712f7d8faf7666f55cc Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 4 Mar 2014 22:00:47 +0100 Subject: [PATCH 05/12] can: janz-ican3: convert dev_ printing to netdev_ This patch converts the dev_ printing to netdev_, this makes it possible to remove the "struct device *dev" pointer from the "struct ican3_dev". Cc: Ira W. Snyder Signed-off-by: Marc Kleine-Budde --- drivers/net/can/janz-ican3.c | 64 +++++++++++++++++------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index 71594e5676fdc..b47df5e482fa5 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -198,9 +198,6 @@ struct ican3_dev { struct net_device *ndev; struct napi_struct napi; - /* Device for printing */ - struct device *dev; - /* module number */ unsigned int num; @@ -295,7 +292,7 @@ static int ican3_old_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) xord = locl ^ peer; if ((xord & MSYNC_RB_MASK) == 0x00) { - dev_dbg(mod->dev, "no mbox for reading\n"); + netdev_dbg(mod->ndev, "no mbox for reading\n"); return -ENOMEM; } @@ -340,7 +337,7 @@ static int ican3_old_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) xord = locl ^ peer; if ((xord & MSYNC_WB_MASK) == MSYNC_WB_MASK) { - dev_err(mod->dev, "no mbox for writing\n"); + netdev_err(mod->ndev, "no mbox for writing\n"); return -ENOMEM; } @@ -542,7 +539,7 @@ static int ican3_new_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) memcpy_fromio(&desc, desc_addr, sizeof(desc)); if (!(desc.control & DESC_VALID)) { - dev_dbg(mod->dev, "%s: no free buffers\n", __func__); + netdev_dbg(mod->ndev, "%s: no free buffers\n", __func__); return -ENOMEM; } @@ -573,7 +570,7 @@ static int ican3_new_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) memcpy_fromio(&desc, desc_addr, sizeof(desc)); if (!(desc.control & DESC_VALID)) { - dev_dbg(mod->dev, "%s: no buffers to recv\n", __func__); + netdev_dbg(mod->ndev, "%s: no buffers to recv\n", __func__); return -ENOMEM; } @@ -883,7 +880,7 @@ static void can_frame_to_ican3(struct ican3_dev *mod, */ static void ican3_handle_idvers(struct ican3_dev *mod, struct ican3_msg *msg) { - dev_dbg(mod->dev, "IDVERS response: %s\n", msg->data); + netdev_dbg(mod->ndev, "IDVERS response: %s\n", msg->data); } static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg) @@ -899,7 +896,7 @@ static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg) * error frame for userspace */ if (msg->spec == MSG_MSGLOST) { - dev_err(mod->dev, "lost %d control messages\n", msg->data[0]); + netdev_err(mod->ndev, "lost %d control messages\n", msg->data[0]); return; } @@ -939,13 +936,13 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) /* we can only handle the SJA1000 part */ if (msg->data[1] != CEVTIND_CHIP_SJA1000) { - dev_err(mod->dev, "unable to handle errors on non-SJA1000\n"); + netdev_err(mod->ndev, "unable to handle errors on non-SJA1000\n"); return -ENODEV; } /* check the message length for sanity */ if (le16_to_cpu(msg->len) < 6) { - dev_err(mod->dev, "error message too short\n"); + netdev_err(mod->ndev, "error message too short\n"); return -EINVAL; } @@ -967,7 +964,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) */ if (isrc == CEVTIND_BEI) { int ret; - dev_dbg(mod->dev, "bus error interrupt\n"); + netdev_dbg(mod->ndev, "bus error interrupt\n"); /* TX error */ if (!(ecc & ECC_DIR)) { @@ -983,7 +980,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) */ ret = ican3_set_buserror(mod, 1); if (ret) { - dev_err(mod->dev, "unable to re-enable bus-error\n"); + netdev_err(mod->ndev, "unable to re-enable bus-error\n"); return ret; } @@ -998,7 +995,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) /* data overrun interrupt */ if (isrc == CEVTIND_DOI || isrc == CEVTIND_LOST) { - dev_dbg(mod->dev, "data overrun interrupt\n"); + netdev_dbg(mod->ndev, "data overrun interrupt\n"); cf->can_id |= CAN_ERR_CRTL; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; @@ -1007,7 +1004,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) /* error warning + passive interrupt */ if (isrc == CEVTIND_EI) { - dev_dbg(mod->dev, "error warning + passive interrupt\n"); + netdev_dbg(mod->ndev, "error warning + passive interrupt\n"); if (status & SR_BS) { state = CAN_STATE_BUS_OFF; cf->can_id |= CAN_ERR_BUSOFF; @@ -1088,7 +1085,7 @@ static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) complete(&mod->termination_comp); break; default: - dev_err(mod->dev, "received an unknown inquiry response\n"); + netdev_err(mod->ndev, "received an unknown inquiry response\n"); break; } } @@ -1096,7 +1093,7 @@ static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) static void ican3_handle_unknown_message(struct ican3_dev *mod, struct ican3_msg *msg) { - dev_warn(mod->dev, "received unknown message: spec 0x%.2x length %d\n", + netdev_warn(mod->ndev, "received unknown message: spec 0x%.2x length %d\n", msg->spec, le16_to_cpu(msg->len)); } @@ -1105,7 +1102,7 @@ static void ican3_handle_unknown_message(struct ican3_dev *mod, */ static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg) { - dev_dbg(mod->dev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__, + netdev_dbg(mod->ndev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__, mod->num, msg->spec, le16_to_cpu(msg->len)); switch (msg->spec) { @@ -1406,7 +1403,7 @@ static int ican3_reset_module(struct ican3_dev *mod) msleep(10); } while (time_before(jiffies, start + HZ / 4)); - dev_err(mod->dev, "failed to reset CAN module\n"); + netdev_err(mod->ndev, "failed to reset CAN module\n"); return -ETIMEDOUT; } @@ -1425,7 +1422,7 @@ static int ican3_startup_module(struct ican3_dev *mod) ret = ican3_reset_module(mod); if (ret) { - dev_err(mod->dev, "unable to reset module\n"); + netdev_err(mod->ndev, "unable to reset module\n"); return ret; } @@ -1434,41 +1431,41 @@ static int ican3_startup_module(struct ican3_dev *mod) ret = ican3_msg_connect(mod); if (ret) { - dev_err(mod->dev, "unable to connect to module\n"); + netdev_err(mod->ndev, "unable to connect to module\n"); return ret; } ican3_init_new_host_interface(mod); ret = ican3_msg_newhostif(mod); if (ret) { - dev_err(mod->dev, "unable to switch to new-style interface\n"); + netdev_err(mod->ndev, "unable to switch to new-style interface\n"); return ret; } /* default to "termination on" */ ret = ican3_set_termination(mod, true); if (ret) { - dev_err(mod->dev, "unable to enable termination\n"); + netdev_err(mod->ndev, "unable to enable termination\n"); return ret; } /* default to "bus errors enabled" */ ret = ican3_set_buserror(mod, 1); if (ret) { - dev_err(mod->dev, "unable to set bus-error\n"); + netdev_err(mod->ndev, "unable to set bus-error\n"); return ret; } ican3_init_fast_host_interface(mod); ret = ican3_msg_fasthostif(mod); if (ret) { - dev_err(mod->dev, "unable to switch to fast host interface\n"); + netdev_err(mod->ndev, "unable to switch to fast host interface\n"); return ret; } ret = ican3_set_id_filter(mod, true); if (ret) { - dev_err(mod->dev, "unable to set acceptance filter\n"); + netdev_err(mod->ndev, "unable to set acceptance filter\n"); return ret; } @@ -1487,14 +1484,14 @@ static int ican3_open(struct net_device *ndev) /* open the CAN layer */ ret = open_candev(ndev); if (ret) { - dev_err(mod->dev, "unable to start CAN layer\n"); + netdev_err(mod->ndev, "unable to start CAN layer\n"); return ret; } /* bring the bus online */ ret = ican3_set_bus_state(mod, true); if (ret) { - dev_err(mod->dev, "unable to set bus-on\n"); + netdev_err(mod->ndev, "unable to set bus-on\n"); close_candev(ndev); return ret; } @@ -1518,7 +1515,7 @@ static int ican3_stop(struct net_device *ndev) /* bring the bus offline, stop receiving packets */ ret = ican3_set_bus_state(mod, false); if (ret) { - dev_err(mod->dev, "unable to set bus-off\n"); + netdev_err(mod->ndev, "unable to set bus-off\n"); return ret; } @@ -1545,7 +1542,7 @@ static int ican3_xmit(struct sk_buff *skb, struct net_device *ndev) /* check that we can actually transmit */ if (!ican3_txok(mod)) { - dev_err(mod->dev, "BUG: no free descriptors\n"); + netdev_err(mod->ndev, "BUG: no free descriptors\n"); spin_unlock_irqrestore(&mod->lock, flags); return NETDEV_TX_BUSY; } @@ -1657,7 +1654,7 @@ static int ican3_set_mode(struct net_device *ndev, enum can_mode mode) /* bring the bus online */ ret = ican3_set_bus_state(mod, true); if (ret) { - dev_err(mod->dev, "unable to set bus-on\n"); + netdev_err(ndev, "unable to set bus-on\n"); return ret; } @@ -1682,7 +1679,7 @@ static int ican3_get_berr_counter(const struct net_device *ndev, ret = wait_for_completion_timeout(&mod->buserror_comp, HZ); if (ret == 0) { - dev_info(mod->dev, "%s timed out\n", __func__); + netdev_info(mod->ndev, "%s timed out\n", __func__); return -ETIMEDOUT; } @@ -1708,7 +1705,7 @@ static ssize_t ican3_sysfs_show_term(struct device *dev, ret = wait_for_completion_timeout(&mod->termination_comp, HZ); if (ret == 0) { - dev_info(mod->dev, "%s timed out\n", __func__); + netdev_info(mod->ndev, "%s timed out\n", __func__); return -ETIMEDOUT; } @@ -1778,7 +1775,6 @@ static int ican3_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); mod = netdev_priv(ndev); mod->ndev = ndev; - mod->dev = &pdev->dev; mod->num = pdata->modno; netif_napi_add(ndev, &mod->napi, ican3_napi, ICAN3_RX_BUFFERS); skb_queue_head_init(&mod->echoq); From a94bc9c46e8e3e1bb5f707e81fd8c60fd93266e6 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 28 Feb 2014 16:36:19 +0100 Subject: [PATCH 06/12] can: preserve skbuff protocol in can_put_echo_skb The skbuff protocol value was formerly fixed/sanitized to ETH_P_CAN in can_put_echo_skb(). With CAN FD this value has to be preserved. This patch changes the hard assignment of the protocol value to a check of valid protocol values for CAN and CAN FD. Signed-off-by: Oliver Hartkopp Acked-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index c0563f1837217..e1a37413d53ee 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -317,7 +317,9 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, BUG_ON(idx >= priv->echo_skb_max); /* check flag whether this packet has to be looped back */ - if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) { + if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK || + (skb->protocol != htons(ETH_P_CAN) && + skb->protocol != htons(ETH_P_CANFD))) { kfree_skb(skb); return; } @@ -329,7 +331,6 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, return; /* make settings for echo to reduce code in irq context */ - skb->protocol = htons(ETH_P_CAN); skb->pkt_type = PACKET_BROADCAST; skb->ip_summed = CHECKSUM_UNNECESSARY; skb->dev = dev; From b30749fdfb9b72f4b1f03673cb5e45b8d4331188 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 28 Feb 2014 16:36:20 +0100 Subject: [PATCH 07/12] can: only send bitrate data via netlink when available When setting the bitrate both can_calc_bittiming() and can_fixup_bittiming() lead to the bitrate variable to be set, when a proper bit timing is available. Only then the bitrate configuration is stored for the device, so checking for priv->bittiming.bitrate is always sufficient. Signed-off-by: Oliver Hartkopp Acked-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index e1a37413d53ee..de04eac7c5f38 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -606,7 +606,7 @@ int open_candev(struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); - if (!priv->bittiming.tq && !priv->bittiming.bitrate) { + if (!priv->bittiming.bitrate) { netdev_err(dev, "bit-timing not yet defined\n"); return -EINVAL; } @@ -719,7 +719,8 @@ static size_t can_get_size(const struct net_device *dev) struct can_priv *priv = netdev_priv(dev); size_t size = 0; - size += nla_total_size(sizeof(struct can_bittiming)); /* IFLA_CAN_BITTIMING */ + if (priv->bittiming.bitrate) /* IFLA_CAN_BITTIMING */ + size += nla_total_size(sizeof(struct can_bittiming)); if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ size += nla_total_size(sizeof(struct can_bittiming_const)); size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ @@ -741,8 +742,9 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) if (priv->do_get_state) priv->do_get_state(dev, &state); - if (nla_put(skb, IFLA_CAN_BITTIMING, - sizeof(priv->bittiming), &priv->bittiming) || + if ((priv->bittiming.bitrate && + nla_put(skb, IFLA_CAN_BITTIMING, + sizeof(priv->bittiming), &priv->bittiming)) || (priv->bittiming_const && nla_put(skb, IFLA_CAN_BITTIMING_CONST, sizeof(*priv->bittiming_const), priv->bittiming_const)) || From d5298dffebae76810a6a942bc6467f893bc11eee Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 28 Feb 2014 16:36:21 +0100 Subject: [PATCH 08/12] can: move sanity check for bitrate and tq into can_get_bittiming This patch moves a sanity check in order to have a second user for CAN FD. Also simplify the return value generation in can_get_bittiming() as only correct return values of can_[calc|fixup]_bittiming() lead to a return value of zero. Signed-off-by: Oliver Hartkopp Acked-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index de04eac7c5f38..e5f1faf36d8ff 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -260,20 +260,23 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) int err; /* Check if the CAN device has bit-timing parameters */ - if (priv->bittiming_const) { + if (!priv->bittiming_const) + return 0; - /* Non-expert mode? Check if the bitrate has been pre-defined */ - if (!bt->tq) - /* Determine bit-timing parameters */ - err = can_calc_bittiming(dev, bt); - else - /* Check bit-timing params and calculate proper brp */ - err = can_fixup_bittiming(dev, bt); - if (err) - return err; - } + /* + * Depending on the given can_bittiming parameter structure the CAN + * timing parameters are calculated based on the provided bitrate OR + * alternatively the CAN timing parameters (tq, prop_seg, etc.) are + * provided directly which are then checked and fixed up. + */ + if (!bt->tq && bt->bitrate) + err = can_calc_bittiming(dev, bt); + else if (bt->tq && !bt->bitrate) + err = can_fixup_bittiming(dev, bt); + else + err = -EINVAL; - return 0; + return err; } /* @@ -667,8 +670,6 @@ static int can_changelink(struct net_device *dev, if (dev->flags & IFF_UP) return -EBUSY; memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); - if ((!bt.bitrate && !bt.tq) || (bt.bitrate && bt.tq)) - return -EINVAL; err = can_get_bittiming(dev, &bt); if (err) return err; From 08da7da41ea490eab08ad9e2674e3b92d6aa2b07 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 28 Feb 2014 16:36:22 +0100 Subject: [PATCH 09/12] can: provide a separate bittiming_const parameter to bittiming functions As the bittiming calculation functions are to be used with different bittiming_const structures for CAN and CAN FD the direct reference to priv->bittiming_const inside these functions has to be removed. Also moved the check for existing bittiming const to one place. Signed-off-by: Oliver Hartkopp Acked-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index e5f1faf36d8ff..8141290e4c183 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -99,10 +99,10 @@ static int can_update_spt(const struct can_bittiming_const *btc, return 1000 * (tseg + 1 - *tseg2) / (tseg + 1); } -static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) { struct can_priv *priv = netdev_priv(dev); - const struct can_bittiming_const *btc = priv->bittiming_const; long rate, best_rate = 0; long best_error = 1000000000, error = 0; int best_tseg = 0, best_brp = 0, brp = 0; @@ -110,9 +110,6 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) int spt_error = 1000, spt = 0, sampl_pt; u64 v64; - if (!priv->bittiming_const) - return -ENOTSUPP; - /* Use CIA recommended sample points */ if (bt->sample_point) { sampl_pt = bt->sample_point; @@ -204,7 +201,8 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) return 0; } #else /* !CONFIG_CAN_CALC_BITTIMING */ -static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) { netdev_err(dev, "bit-timing calculation not available\n"); return -EINVAL; @@ -217,16 +215,13 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) * prescaler value brp. You can find more information in the header * file linux/can/netlink.h. */ -static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) { struct can_priv *priv = netdev_priv(dev); - const struct can_bittiming_const *btc = priv->bittiming_const; int tseg1, alltseg; u64 brp64; - if (!priv->bittiming_const) - return -ENOTSUPP; - tseg1 = bt->prop_seg + bt->phase_seg1; if (!bt->sjw) bt->sjw = 1; @@ -254,14 +249,14 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt) return 0; } -static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) { - struct can_priv *priv = netdev_priv(dev); int err; /* Check if the CAN device has bit-timing parameters */ - if (!priv->bittiming_const) - return 0; + if (!btc) + return -ENOTSUPP; /* * Depending on the given can_bittiming parameter structure the CAN @@ -270,9 +265,9 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) * provided directly which are then checked and fixed up. */ if (!bt->tq && bt->bitrate) - err = can_calc_bittiming(dev, bt); + err = can_calc_bittiming(dev, bt, btc); else if (bt->tq && !bt->bitrate) - err = can_fixup_bittiming(dev, bt); + err = can_fixup_bittiming(dev, bt, btc); else err = -EINVAL; @@ -670,7 +665,7 @@ static int can_changelink(struct net_device *dev, if (dev->flags & IFF_UP) return -EBUSY; memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); - err = can_get_bittiming(dev, &bt); + err = can_get_bittiming(dev, &bt, priv->bittiming_const); if (err) return err; memcpy(&priv->bittiming, &bt, sizeof(bt)); From 9859ccd2c8be63ce939522e63e265f2b0caa1109 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 28 Feb 2014 16:36:23 +0100 Subject: [PATCH 10/12] can: introduce the data bitrate configuration for CAN FD As CAN FD offers a second bitrate for the data section of the CAN frame the infrastructure for storing and configuring this second bitrate is introduced. Improved the readability of the if-statement by inserting some newlines. Signed-off-by: Oliver Hartkopp Acked-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 45 +++++++++++++++++++++++++++++++- include/linux/can/dev.h | 6 +++-- include/uapi/linux/can/netlink.h | 2 ++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 8141290e4c183..8ebe112458c46 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -647,6 +647,10 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { = { .len = sizeof(struct can_bittiming_const) }, [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, + [IFLA_CAN_DATA_BITTIMING] + = { .len = sizeof(struct can_bittiming) }, + [IFLA_CAN_DATA_BITTIMING_CONST] + = { .len = sizeof(struct can_bittiming_const) }, }; static int can_changelink(struct net_device *dev, @@ -707,6 +711,27 @@ static int can_changelink(struct net_device *dev, return err; } + if (data[IFLA_CAN_DATA_BITTIMING]) { + struct can_bittiming dbt; + + /* Do not allow changing bittiming while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), + sizeof(dbt)); + err = can_get_bittiming(dev, &dbt, priv->data_bittiming_const); + if (err) + return err; + memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); + + if (priv->do_set_data_bittiming) { + /* Finally, set the bit-timing registers */ + err = priv->do_set_data_bittiming(dev); + if (err) + return err; + } + } + return 0; } @@ -725,6 +750,10 @@ static size_t can_get_size(const struct net_device *dev) size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ size += nla_total_size(sizeof(struct can_berr_counter)); + if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ + size += nla_total_size(sizeof(struct can_bittiming)); + if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ + size += nla_total_size(sizeof(struct can_bittiming_const)); return size; } @@ -738,20 +767,34 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) if (priv->do_get_state) priv->do_get_state(dev, &state); + if ((priv->bittiming.bitrate && nla_put(skb, IFLA_CAN_BITTIMING, sizeof(priv->bittiming), &priv->bittiming)) || + (priv->bittiming_const && nla_put(skb, IFLA_CAN_BITTIMING_CONST, sizeof(*priv->bittiming_const), priv->bittiming_const)) || + nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) || nla_put_u32(skb, IFLA_CAN_STATE, state) || nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || + (priv->do_get_berr_counter && !priv->do_get_berr_counter(dev, &bec) && - nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec))) + nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) || + + (priv->data_bittiming.bitrate && + nla_put(skb, IFLA_CAN_DATA_BITTIMING, + sizeof(priv->data_bittiming), &priv->data_bittiming)) || + + (priv->data_bittiming_const && + nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST, + sizeof(*priv->data_bittiming_const), + priv->data_bittiming_const))) return -EMSGSIZE; + return 0; } diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index dc5f9026b67fb..8adaee96f2928 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -33,8 +33,9 @@ enum can_mode { struct can_priv { struct can_device_stats can_stats; - struct can_bittiming bittiming; - const struct can_bittiming_const *bittiming_const; + struct can_bittiming bittiming, data_bittiming; + const struct can_bittiming_const *bittiming_const, + *data_bittiming_const; struct can_clock clock; enum can_state state; @@ -45,6 +46,7 @@ struct can_priv { struct timer_list restart_timer; int (*do_set_bittiming)(struct net_device *dev); + int (*do_set_data_bittiming)(struct net_device *dev); int (*do_set_mode)(struct net_device *dev, enum can_mode mode); int (*do_get_state)(const struct net_device *dev, enum can_state *state); diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h index df944ed206a8e..b41933d6bdcd2 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -122,6 +122,8 @@ enum { IFLA_CAN_RESTART_MS, IFLA_CAN_RESTART, IFLA_CAN_BERR_COUNTER, + IFLA_CAN_DATA_BITTIMING, + IFLA_CAN_DATA_BITTIMING_CONST, __IFLA_CAN_MAX }; From bc05a8944a344acdb81a65de055ca6febbf9657c Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 28 Feb 2014 16:36:24 +0100 Subject: [PATCH 11/12] can: allow to change the device mtu for CAN FD capable devices The configuration for CAN FD depends on CAN_CTRLMODE_FD enabled in the driver specific ctrlmode_supported capabilities. The configuration can be done either with the 'fd { on | off }' option in the 'ip' tool from iproute2 or by setting the CAN netdevice MTU to CAN_MTU (16) or to CANFD_MTU (72). Signed-off-by: Oliver Hartkopp Acked-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 39 ++++++++++++++++++++++++++++++++ include/linux/can/dev.h | 1 + include/uapi/linux/can/netlink.h | 1 + 3 files changed, 41 insertions(+) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 8ebe112458c46..4e20d82b799e4 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -594,6 +594,39 @@ void free_candev(struct net_device *dev) } EXPORT_SYMBOL_GPL(free_candev); +/* + * changing MTU and control mode for CAN/CANFD devices + */ +int can_change_mtu(struct net_device *dev, int new_mtu) +{ + struct can_priv *priv = netdev_priv(dev); + + /* Do not allow changing the MTU while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + + /* allow change of MTU according to the CANFD ability of the device */ + switch (new_mtu) { + case CAN_MTU: + priv->ctrlmode &= ~CAN_CTRLMODE_FD; + break; + + case CANFD_MTU: + if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD)) + return -EINVAL; + + priv->ctrlmode |= CAN_CTRLMODE_FD; + break; + + default: + return -EINVAL; + } + + dev->mtu = new_mtu; + return 0; +} +EXPORT_SYMBOL_GPL(can_change_mtu); + /* * Common open function when the device gets opened. * @@ -693,6 +726,12 @@ static int can_changelink(struct net_device *dev, return -EOPNOTSUPP; priv->ctrlmode &= ~cm->mask; priv->ctrlmode |= cm->flags; + + /* CAN_CTRLMODE_FD can only be set when driver supports FD */ + if (priv->ctrlmode & CAN_CTRLMODE_FD) + dev->mtu = CANFD_MTU; + else + dev->mtu = CAN_MTU; } if (data[IFLA_CAN_RESTART_MS]) { diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 8adaee96f2928..3ce5e526525f8 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -113,6 +113,7 @@ struct can_priv *safe_candev_priv(struct net_device *dev); int open_candev(struct net_device *dev); void close_candev(struct net_device *dev); +int can_change_mtu(struct net_device *dev, int new_mtu); int register_candev(struct net_device *dev); void unregister_candev(struct net_device *dev); diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h index b41933d6bdcd2..7e2e1863db16e 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -96,6 +96,7 @@ struct can_ctrlmode { #define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */ #define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */ #define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */ +#define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */ /* * CAN device statistics From dd22586dec4c1444608affd83b1fedd520280ab4 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 28 Feb 2014 16:36:25 +0100 Subject: [PATCH 12/12] can: add bittiming check at interface open for CAN FD Additionally to have the second (data) bitrate available the data bitrate has to be greater or equal to the arbitration bitrate in CAN FD. Signed-off-by: Oliver Hartkopp Acked-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 4e20d82b799e4..c7a260478749a 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -642,6 +642,14 @@ int open_candev(struct net_device *dev) return -EINVAL; } + /* For CAN FD the data bitrate has to be >= the arbitration bitrate */ + if ((priv->ctrlmode & CAN_CTRLMODE_FD) && + (!priv->data_bittiming.bitrate || + (priv->data_bittiming.bitrate < priv->bittiming.bitrate))) { + netdev_err(dev, "incorrect/missing data bit-timing\n"); + return -EINVAL; + } + /* Switch carrier on if device was stopped while in bus-off state */ if (!netif_carrier_ok(dev)) netif_carrier_on(dev);