Skip to content

Commit

Permalink
Merge tag 'linux-can-next-for-5.16-20211024' of git://git.kernel.org/…
Browse files Browse the repository at this point in the history
…pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2021-10-24

this is a pull request of 15 patches for net-next/master.

The first patch is by Thomas Gleixner and makes use of
hrtimer_forward_now() in the CAN broad cast manager (bcm).

The next patch is by me and changes the type of the variables used in
the CAN bit timing calculation can_fixup_bittiming() to unsigned int.

Vincent Mailhol provides 6 patches targeting the CAN device
infrastructure. The CAN-FD specific Transmitter Delay Compensation
(TDC) is updated and configuration via the CAN netlink interface is
added.

Qing Wang's patch updates the at91 and janz-ican3 drivers to use
sysfs_emit() instead of snprintf() in the sysfs show functions.

Geert Uytterhoeven's patch drops the unneeded ARM dependency from the
rar Kconfig.

Cai Huoqing's patch converts the mscan driver to make use of the
dev_err_probe() helper function.

A patch by me against the gsusb driver changes the printf format
strings to use %u to print unsigned values.

Stephane Grosjean's patch updates the peak_usb CAN-FD driver to use
the 64 bit timestamps provided by the hardware.

The last 2 patches target the xilinx_can driver. Michal Simek provides
a patch that removes repeated word from the kernel-doc and Dongliang
Mu's patch removes a redundant netif_napi_del() from the xcan_remove()
function.
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Oct 25, 2021
2 parents 45f850c + b9b8218 commit 12f241f
Show file tree
Hide file tree
Showing 16 changed files with 402 additions and 70 deletions.
4 changes: 2 additions & 2 deletions drivers/net/can/at91_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -1170,9 +1170,9 @@ static ssize_t mb0_id_show(struct device *dev,
struct at91_priv *priv = netdev_priv(to_net_dev(dev));

if (priv->mb0_id & CAN_EFF_FLAG)
return snprintf(buf, PAGE_SIZE, "0x%08x\n", priv->mb0_id);
return sysfs_emit(buf, "0x%08x\n", priv->mb0_id);
else
return snprintf(buf, PAGE_SIZE, "0x%03x\n", priv->mb0_id);
return sysfs_emit(buf, "0x%03x\n", priv->mb0_id);
}

static ssize_t mb0_id_store(struct device *dev,
Expand Down
30 changes: 16 additions & 14 deletions drivers/net/can/dev/bittiming.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,27 +175,29 @@ int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
return 0;
}

void can_calc_tdco(struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
const struct can_bittiming *dbt = &priv->data_bittiming;
struct can_tdc *tdc = &priv->tdc;
const struct can_tdc_const *tdc_const = priv->tdc_const;
void can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_const,
const struct can_bittiming *dbt,
u32 *ctrlmode, u32 ctrlmode_supported)

if (!tdc_const)
{
if (!tdc_const || !(ctrlmode_supported & CAN_CTRLMODE_TDC_AUTO))
return;

*ctrlmode &= ~CAN_CTRLMODE_TDC_MASK;

/* As specified in ISO 11898-1 section 11.3.3 "Transmitter
* delay compensation" (TDC) is only applicable if data BRP is
* one or two.
*/
if (dbt->brp == 1 || dbt->brp == 2) {
/* Reuse "normal" sample point and convert it to time quanta */
u32 sample_point_in_tq = can_bit_time(dbt) * dbt->sample_point / 1000;

tdc->tdco = min(sample_point_in_tq, tdc_const->tdco_max);
} else {
tdc->tdco = 0;
/* Sample point in clock periods */
u32 sample_point_in_tc = (CAN_SYNC_SEG + dbt->prop_seg +
dbt->phase_seg1) * dbt->brp;

if (sample_point_in_tc < tdc_const->tdco_min)
return;
tdc->tdco = min(sample_point_in_tc, tdc_const->tdco_max);
*ctrlmode |= CAN_CTRLMODE_TDC_AUTO;
}
}
#endif /* CONFIG_CAN_CALC_BITTIMING */
Expand All @@ -209,7 +211,7 @@ 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);
int tseg1, alltseg;
unsigned int tseg1, alltseg;
u64 brp64;

tseg1 = bt->prop_seg + bt->phase_seg1;
Expand Down
221 changes: 217 additions & 4 deletions drivers/net/can/dev/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
* Copyright (C) 2006 Andrey Volkov, Varma Electronics
* Copyright (C) 2008-2009 Wolfgang Grandegger <[email protected]>
* Copyright (C) 2021 Vincent Mailhol <[email protected]>
*/

#include <linux/can/dev.h>
Expand All @@ -19,6 +20,19 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
[IFLA_CAN_DATA_BITTIMING] = { .len = sizeof(struct can_bittiming) },
[IFLA_CAN_DATA_BITTIMING_CONST] = { .len = sizeof(struct can_bittiming_const) },
[IFLA_CAN_TERMINATION] = { .type = NLA_U16 },
[IFLA_CAN_TDC] = { .type = NLA_NESTED },
};

static const struct nla_policy can_tdc_policy[IFLA_CAN_TDC_MAX + 1] = {
[IFLA_CAN_TDC_TDCV_MIN] = { .type = NLA_U32 },
[IFLA_CAN_TDC_TDCV_MAX] = { .type = NLA_U32 },
[IFLA_CAN_TDC_TDCO_MIN] = { .type = NLA_U32 },
[IFLA_CAN_TDC_TDCO_MAX] = { .type = NLA_U32 },
[IFLA_CAN_TDC_TDCF_MIN] = { .type = NLA_U32 },
[IFLA_CAN_TDC_TDCF_MAX] = { .type = NLA_U32 },
[IFLA_CAN_TDC_TDCV] = { .type = NLA_U32 },
[IFLA_CAN_TDC_TDCO] = { .type = NLA_U32 },
[IFLA_CAN_TDC_TDCF] = { .type = NLA_U32 },
};

static int can_validate(struct nlattr *tb[], struct nlattr *data[],
Expand All @@ -30,35 +44,120 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
* - nominal/arbitration bittiming
* - data bittiming
* - control mode with CAN_CTRLMODE_FD set
* - TDC parameters are coherent (details below)
*/

if (!data)
return 0;

if (data[IFLA_CAN_CTRLMODE]) {
struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
u32 tdc_flags = cm->flags & CAN_CTRLMODE_TDC_MASK;

is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD;

/* CAN_CTRLMODE_TDC_{AUTO,MANUAL} are mutually exclusive */
if (tdc_flags == CAN_CTRLMODE_TDC_MASK)
return -EOPNOTSUPP;
/* If one of the CAN_CTRLMODE_TDC_* flag is set then
* TDC must be set and vice-versa
*/
if (!!tdc_flags != !!data[IFLA_CAN_TDC])
return -EOPNOTSUPP;
/* If providing TDC parameters, at least TDCO is
* needed. TDCV is needed if and only if
* CAN_CTRLMODE_TDC_MANUAL is set
*/
if (data[IFLA_CAN_TDC]) {
struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1];
int err;

err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX,
data[IFLA_CAN_TDC],
can_tdc_policy, extack);
if (err)
return err;

if (tb_tdc[IFLA_CAN_TDC_TDCV]) {
if (tdc_flags & CAN_CTRLMODE_TDC_AUTO)
return -EOPNOTSUPP;
} else {
if (tdc_flags & CAN_CTRLMODE_TDC_MANUAL)
return -EOPNOTSUPP;
}

if (!tb_tdc[IFLA_CAN_TDC_TDCO])
return -EOPNOTSUPP;
}
}

if (is_can_fd) {
if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING])
return -EOPNOTSUPP;
}

if (data[IFLA_CAN_DATA_BITTIMING]) {
if (data[IFLA_CAN_DATA_BITTIMING] || data[IFLA_CAN_TDC]) {
if (!is_can_fd)
return -EOPNOTSUPP;
}

return 0;
}

static int can_tdc_changelink(struct can_priv *priv, const struct nlattr *nla,
struct netlink_ext_ack *extack)
{
struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1];
struct can_tdc tdc = { 0 };
const struct can_tdc_const *tdc_const = priv->tdc_const;
int err;

if (!tdc_const || !can_tdc_is_enabled(priv))
return -EOPNOTSUPP;

err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX, nla,
can_tdc_policy, extack);
if (err)
return err;

if (tb_tdc[IFLA_CAN_TDC_TDCV]) {
u32 tdcv = nla_get_u32(tb_tdc[IFLA_CAN_TDC_TDCV]);

if (tdcv < tdc_const->tdcv_min || tdcv > tdc_const->tdcv_max)
return -EINVAL;

tdc.tdcv = tdcv;
}

if (tb_tdc[IFLA_CAN_TDC_TDCO]) {
u32 tdco = nla_get_u32(tb_tdc[IFLA_CAN_TDC_TDCO]);

if (tdco < tdc_const->tdco_min || tdco > tdc_const->tdco_max)
return -EINVAL;

tdc.tdco = tdco;
}

if (tb_tdc[IFLA_CAN_TDC_TDCF]) {
u32 tdcf = nla_get_u32(tb_tdc[IFLA_CAN_TDC_TDCF]);

if (tdcf < tdc_const->tdcf_min || tdcf > tdc_const->tdcf_max)
return -EINVAL;

tdc.tdcf = tdcf;
}

priv->tdc = tdc;

return 0;
}

static int can_changelink(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
{
struct can_priv *priv = netdev_priv(dev);
u32 tdc_mask = 0;
int err;

/* We need synchronization with dev->stop() */
Expand Down Expand Up @@ -138,7 +237,16 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
dev->mtu = CAN_MTU;
memset(&priv->data_bittiming, 0,
sizeof(priv->data_bittiming));
priv->ctrlmode &= ~CAN_CTRLMODE_TDC_MASK;
memset(&priv->tdc, 0, sizeof(priv->tdc));
}

tdc_mask = cm->mask & CAN_CTRLMODE_TDC_MASK;
/* CAN_CTRLMODE_TDC_{AUTO,MANUAL} are mutually
* exclusive: make sure to turn the other one off
*/
if (tdc_mask)
priv->ctrlmode &= cm->flags | ~CAN_CTRLMODE_TDC_MASK;
}

if (data[IFLA_CAN_RESTART_MS]) {
Expand Down Expand Up @@ -187,9 +295,26 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
return -EINVAL;
}

memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
memset(&priv->tdc, 0, sizeof(priv->tdc));
if (data[IFLA_CAN_TDC]) {
/* TDC parameters are provided: use them */
err = can_tdc_changelink(priv, data[IFLA_CAN_TDC],
extack);
if (err) {
priv->ctrlmode &= ~CAN_CTRLMODE_TDC_MASK;
return err;
}
} else if (!tdc_mask) {
/* Neither of TDC parameters nor TDC flags are
* provided: do calculation
*/
can_calc_tdco(&priv->tdc, priv->tdc_const, &priv->data_bittiming,
&priv->ctrlmode, priv->ctrlmode_supported);
} /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly
* turned off. TDC is disabled: do nothing
*/

can_calc_tdco(dev);
memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));

if (priv->do_set_data_bittiming) {
/* Finally, set the bit-timing registers */
Expand Down Expand Up @@ -226,6 +351,38 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
return 0;
}

static size_t can_tdc_get_size(const struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
size_t size;

if (!priv->tdc_const)
return 0;

size = nla_total_size(0); /* nest IFLA_CAN_TDC */
if (priv->ctrlmode_supported & CAN_CTRLMODE_TDC_MANUAL) {
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCV_MIN */
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCV_MAX */
}
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCO_MIN */
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCO_MAX */
if (priv->tdc_const->tdcf_max) {
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCF_MIN */
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCF_MAX */
}

if (can_tdc_is_enabled(priv)) {
if (priv->ctrlmode & CAN_CTRLMODE_TDC_MANUAL ||
priv->do_get_auto_tdcv)
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCV */
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCO */
if (priv->tdc_const->tdcf_max)
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCF */
}

return size;
}

static size_t can_get_size(const struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
Expand Down Expand Up @@ -257,10 +414,64 @@ static size_t can_get_size(const struct net_device *dev)
size += nla_total_size(sizeof(*priv->data_bitrate_const) *
priv->data_bitrate_const_cnt);
size += sizeof(priv->bitrate_max); /* IFLA_CAN_BITRATE_MAX */
size += can_tdc_get_size(dev); /* IFLA_CAN_TDC */

return size;
}

static int can_tdc_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
struct nlattr *nest;
struct can_priv *priv = netdev_priv(dev);
struct can_tdc *tdc = &priv->tdc;
const struct can_tdc_const *tdc_const = priv->tdc_const;

if (!tdc_const)
return 0;

nest = nla_nest_start(skb, IFLA_CAN_TDC);
if (!nest)
return -EMSGSIZE;

if (priv->ctrlmode_supported & CAN_CTRLMODE_TDC_MANUAL &&
(nla_put_u32(skb, IFLA_CAN_TDC_TDCV_MIN, tdc_const->tdcv_min) ||
nla_put_u32(skb, IFLA_CAN_TDC_TDCV_MAX, tdc_const->tdcv_max)))
goto err_cancel;
if (nla_put_u32(skb, IFLA_CAN_TDC_TDCO_MIN, tdc_const->tdco_min) ||
nla_put_u32(skb, IFLA_CAN_TDC_TDCO_MAX, tdc_const->tdco_max))
goto err_cancel;
if (tdc_const->tdcf_max &&
(nla_put_u32(skb, IFLA_CAN_TDC_TDCF_MIN, tdc_const->tdcf_min) ||
nla_put_u32(skb, IFLA_CAN_TDC_TDCF_MAX, tdc_const->tdcf_max)))
goto err_cancel;

if (can_tdc_is_enabled(priv)) {
u32 tdcv;
int err = -EINVAL;

if (priv->ctrlmode & CAN_CTRLMODE_TDC_MANUAL) {
tdcv = tdc->tdcv;
err = 0;
} else if (priv->do_get_auto_tdcv) {
err = priv->do_get_auto_tdcv(dev, &tdcv);
}
if (!err && nla_put_u32(skb, IFLA_CAN_TDC_TDCV, tdcv))
goto err_cancel;
if (nla_put_u32(skb, IFLA_CAN_TDC_TDCO, tdc->tdco))
goto err_cancel;
if (tdc_const->tdcf_max &&
nla_put_u32(skb, IFLA_CAN_TDC_TDCF, tdc->tdcf))
goto err_cancel;
}

nla_nest_end(skb, nest);
return 0;

err_cancel:
nla_nest_cancel(skb, nest);
return -EMSGSIZE;
}

static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
Expand Down Expand Up @@ -318,7 +529,9 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)

(nla_put(skb, IFLA_CAN_BITRATE_MAX,
sizeof(priv->bitrate_max),
&priv->bitrate_max))
&priv->bitrate_max)) ||

(can_tdc_fill_info(skb, dev))
)

return -EMSGSIZE;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/janz-ican3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1831,7 +1831,7 @@ static ssize_t termination_show(struct device *dev,
return -ETIMEDOUT;
}

return snprintf(buf, PAGE_SIZE, "%u\n", mod->termination_enabled);
return sysfs_emit(buf, "%u\n", mod->termination_enabled);
}

static ssize_t termination_store(struct device *dev,
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/can/mscan/mpc5xxx_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,8 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
return -EINVAL;

base = of_iomap(np, 0);
if (!base) {
dev_err(&ofdev->dev, "couldn't ioremap\n");
return err;
}
if (!base)
return dev_err_probe(&ofdev->dev, err, "couldn't ioremap\n");

irq = irq_of_parse_and_map(np, 0);
if (!irq) {
Expand Down
Loading

0 comments on commit 12f241f

Please sign in to comment.