Re: [net-next 06/13] can: dev: move netlink related code into seperate file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Le dim. 10 janv. 2021 à 02:40, Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> a écrit :
>
> This patch moves the netlink related code of the CAN device infrastructure into
> a separate file.
>
> Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx>
> ---
>  drivers/net/can/dev/dev.c     | 370 +--------------------------------
>  drivers/net/can/dev/netlink.c | 379 ++++++++++++++++++++++++++++++++++
>  include/linux/can/dev.h       |   6 +
>  3 files changed, 388 insertions(+), 367 deletions(-)
>  create mode 100644 drivers/net/can/dev/netlink.c
>
> diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
> index fe71ff9ef8c9..f580f0ac6497 100644
> --- a/drivers/net/can/dev/dev.c
> +++ b/drivers/net/can/dev/dev.c
> @@ -14,10 +14,8 @@
>  #include <linux/can/can-ml.h>
>  #include <linux/can/dev.h>
>  #include <linux/can/skb.h>
> -#include <linux/can/netlink.h>
>  #include <linux/can/led.h>
>  #include <linux/of.h>
> -#include <net/rtnetlink.h>
>
>  #define MOD_DESC "CAN device driver interface"
>
> @@ -223,7 +221,7 @@ void can_bus_off(struct net_device *dev)
>  }
>  EXPORT_SYMBOL_GPL(can_bus_off);
>
> -static void can_setup(struct net_device *dev)
> +void can_setup(struct net_device *dev)
>  {
>         dev->type = ARPHRD_CAN;
>         dev->mtu = CAN_MTU;
> @@ -399,368 +397,6 @@ void close_candev(struct net_device *dev)
>  }
>  EXPORT_SYMBOL_GPL(close_candev);
>
> -/* CAN netlink interface */
> -static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
> -       [IFLA_CAN_STATE]        = { .type = NLA_U32 },
> -       [IFLA_CAN_CTRLMODE]     = { .len = sizeof(struct can_ctrlmode) },
> -       [IFLA_CAN_RESTART_MS]   = { .type = NLA_U32 },
> -       [IFLA_CAN_RESTART]      = { .type = NLA_U32 },
> -       [IFLA_CAN_BITTIMING]    = { .len = sizeof(struct can_bittiming) },
> -       [IFLA_CAN_BITTIMING_CONST]
> -                               = { .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) },
> -       [IFLA_CAN_TERMINATION]  = { .type = NLA_U16 },
> -};
> -
> -static int can_validate(struct nlattr *tb[], struct nlattr *data[],
> -                       struct netlink_ext_ack *extack)
> -{
> -       bool is_can_fd = false;
> -
> -       /* Make sure that valid CAN FD configurations always consist of
> -        * - nominal/arbitration bittiming
> -        * - data bittiming
> -        * - control mode with CAN_CTRLMODE_FD set
> -        */
> -
> -       if (!data)
> -               return 0;
> -
> -       if (data[IFLA_CAN_CTRLMODE]) {
> -               struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
> -
> -               is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD;
> -       }
> -
> -       if (is_can_fd) {
> -               if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING])
> -                       return -EOPNOTSUPP;
> -       }
> -
> -       if (data[IFLA_CAN_DATA_BITTIMING]) {
> -               if (!is_can_fd || !data[IFLA_CAN_BITTIMING])
> -                       return -EOPNOTSUPP;
> -       }
> -
> -       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);
> -       int err;
> -
> -       /* We need synchronization with dev->stop() */
> -       ASSERT_RTNL();
> -
> -       if (data[IFLA_CAN_BITTIMING]) {
> -               struct can_bittiming bt;
> -
> -               /* Do not allow changing bittiming while running */
> -               if (dev->flags & IFF_UP)
> -                       return -EBUSY;
> -
> -               /* Calculate bittiming parameters based on
> -                * bittiming_const if set, otherwise pass bitrate
> -                * directly via do_set_bitrate(). Bail out if neither
> -                * is given.
> -                */
> -               if (!priv->bittiming_const && !priv->do_set_bittiming)
> -                       return -EOPNOTSUPP;
> -
> -               memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
> -               err = can_get_bittiming(dev, &bt,
> -                                       priv->bittiming_const,
> -                                       priv->bitrate_const,
> -                                       priv->bitrate_const_cnt);
> -               if (err)
> -                       return err;
> -
> -               if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) {
> -                       netdev_err(dev, "arbitration bitrate surpasses transceiver capabilities of %d bps\n",
> -                                  priv->bitrate_max);
> -                       return -EINVAL;
> -               }
> -
> -               memcpy(&priv->bittiming, &bt, sizeof(bt));
> -
> -               if (priv->do_set_bittiming) {
> -                       /* Finally, set the bit-timing registers */
> -                       err = priv->do_set_bittiming(dev);
> -                       if (err)
> -                               return err;
> -               }
> -       }
> -
> -       if (data[IFLA_CAN_CTRLMODE]) {
> -               struct can_ctrlmode *cm;
> -               u32 ctrlstatic;
> -               u32 maskedflags;
> -
> -               /* Do not allow changing controller mode while running */
> -               if (dev->flags & IFF_UP)
> -                       return -EBUSY;
> -               cm = nla_data(data[IFLA_CAN_CTRLMODE]);
> -               ctrlstatic = priv->ctrlmode_static;
> -               maskedflags = cm->flags & cm->mask;
> -
> -               /* check whether provided bits are allowed to be passed */
> -               if (cm->mask & ~(priv->ctrlmode_supported | ctrlstatic))
> -                       return -EOPNOTSUPP;
> -
> -               /* do not check for static fd-non-iso if 'fd' is disabled */
> -               if (!(maskedflags & CAN_CTRLMODE_FD))
> -                       ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO;
> -
> -               /* make sure static options are provided by configuration */
> -               if ((maskedflags & ctrlstatic) != ctrlstatic)
> -                       return -EOPNOTSUPP;
> -
> -               /* clear bits to be modified and copy the flag values */
> -               priv->ctrlmode &= ~cm->mask;
> -               priv->ctrlmode |= maskedflags;
> -
> -               /* 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]) {
> -               /* Do not allow changing restart delay while running */
> -               if (dev->flags & IFF_UP)
> -                       return -EBUSY;
> -               priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]);
> -       }
> -
> -       if (data[IFLA_CAN_RESTART]) {
> -               /* Do not allow a restart while not running */
> -               if (!(dev->flags & IFF_UP))
> -                       return -EINVAL;
> -               err = can_restart_now(dev);
> -               if (err)
> -                       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;
> -
> -               /* Calculate bittiming parameters based on
> -                * data_bittiming_const if set, otherwise pass bitrate
> -                * directly via do_set_bitrate(). Bail out if neither
> -                * is given.
> -                */
> -               if (!priv->data_bittiming_const && !priv->do_set_data_bittiming)
> -                       return -EOPNOTSUPP;
> -
> -               memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
> -                      sizeof(dbt));
> -               err = can_get_bittiming(dev, &dbt,
> -                                       priv->data_bittiming_const,
> -                                       priv->data_bitrate_const,
> -                                       priv->data_bitrate_const_cnt);
> -               if (err)
> -                       return err;
> -
> -               if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) {
> -                       netdev_err(dev, "canfd data bitrate surpasses transceiver capabilities of %d bps\n",
> -                                  priv->bitrate_max);
> -                       return -EINVAL;
> -               }
> -
> -               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;
> -               }
> -       }
> -
> -       if (data[IFLA_CAN_TERMINATION]) {
> -               const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]);
> -               const unsigned int num_term = priv->termination_const_cnt;
> -               unsigned int i;
> -
> -               if (!priv->do_set_termination)
> -                       return -EOPNOTSUPP;
> -
> -               /* check whether given value is supported by the interface */
> -               for (i = 0; i < num_term; i++) {
> -                       if (termval == priv->termination_const[i])
> -                               break;
> -               }
> -               if (i >= num_term)
> -                       return -EINVAL;
> -
> -               /* Finally, set the termination value */
> -               err = priv->do_set_termination(dev, termval);
> -               if (err)
> -                       return err;
> -
> -               priv->termination = termval;
> -       }
> -
> -       return 0;
> -}
> -
> -static size_t can_get_size(const struct net_device *dev)
> -{
> -       struct can_priv *priv = netdev_priv(dev);
> -       size_t size = 0;
> -
> -       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 */
> -       size += nla_total_size(sizeof(u32));                    /* IFLA_CAN_STATE */
> -       size += nla_total_size(sizeof(struct can_ctrlmode));    /* IFLA_CAN_CTRLMODE */
> -       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));
> -       if (priv->termination_const) {
> -               size += nla_total_size(sizeof(priv->termination));              /* IFLA_CAN_TERMINATION */
> -               size += nla_total_size(sizeof(*priv->termination_const) *       /* IFLA_CAN_TERMINATION_CONST */
> -                                      priv->termination_const_cnt);
> -       }
> -       if (priv->bitrate_const)                                /* IFLA_CAN_BITRATE_CONST */
> -               size += nla_total_size(sizeof(*priv->bitrate_const) *
> -                                      priv->bitrate_const_cnt);
> -       if (priv->data_bitrate_const)                           /* IFLA_CAN_DATA_BITRATE_CONST */
> -               size += nla_total_size(sizeof(*priv->data_bitrate_const) *
> -                                      priv->data_bitrate_const_cnt);
> -       size += sizeof(priv->bitrate_max);                      /* IFLA_CAN_BITRATE_MAX */
> -
> -       return size;
> -}
> -
> -static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
> -{
> -       struct can_priv *priv = netdev_priv(dev);
> -       struct can_ctrlmode cm = {.flags = priv->ctrlmode};
> -       struct can_berr_counter bec;
> -       enum can_state state = priv->state;
> -
> -       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(priv->clock), &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)) ||
> -
> -           (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)) ||
> -
> -           (priv->termination_const &&
> -            (nla_put_u16(skb, IFLA_CAN_TERMINATION, priv->termination) ||
> -             nla_put(skb, IFLA_CAN_TERMINATION_CONST,
> -                     sizeof(*priv->termination_const) *
> -                     priv->termination_const_cnt,
> -                     priv->termination_const))) ||
> -
> -           (priv->bitrate_const &&
> -            nla_put(skb, IFLA_CAN_BITRATE_CONST,
> -                    sizeof(*priv->bitrate_const) *
> -                    priv->bitrate_const_cnt,
> -                    priv->bitrate_const)) ||
> -
> -           (priv->data_bitrate_const &&
> -            nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST,
> -                    sizeof(*priv->data_bitrate_const) *
> -                    priv->data_bitrate_const_cnt,
> -                    priv->data_bitrate_const)) ||
> -
> -           (nla_put(skb, IFLA_CAN_BITRATE_MAX,
> -                    sizeof(priv->bitrate_max),
> -                    &priv->bitrate_max))
> -           )
> -
> -               return -EMSGSIZE;
> -
> -       return 0;
> -}
> -
> -static size_t can_get_xstats_size(const struct net_device *dev)
> -{
> -       return sizeof(struct can_device_stats);
> -}
> -
> -static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
> -{
> -       struct can_priv *priv = netdev_priv(dev);
> -
> -       if (nla_put(skb, IFLA_INFO_XSTATS,
> -                   sizeof(priv->can_stats), &priv->can_stats))
> -               goto nla_put_failure;
> -       return 0;
> -
> -nla_put_failure:
> -       return -EMSGSIZE;
> -}
> -
> -static int can_newlink(struct net *src_net, struct net_device *dev,
> -                      struct nlattr *tb[], struct nlattr *data[],
> -                      struct netlink_ext_ack *extack)
> -{
> -       return -EOPNOTSUPP;
> -}
> -
> -static void can_dellink(struct net_device *dev, struct list_head *head)
> -{
> -}
> -
> -static struct rtnl_link_ops can_link_ops __read_mostly = {
> -       .kind           = "can",
> -       .maxtype        = IFLA_CAN_MAX,
> -       .policy         = can_policy,
> -       .setup          = can_setup,
> -       .validate       = can_validate,
> -       .newlink        = can_newlink,
> -       .changelink     = can_changelink,
> -       .dellink        = can_dellink,
> -       .get_size       = can_get_size,
> -       .fill_info      = can_fill_info,
> -       .get_xstats_size = can_get_xstats_size,
> -       .fill_xstats    = can_fill_xstats,
> -};
> -
>  /* Register the CAN network device */
>  int register_candev(struct net_device *dev)
>  {
> @@ -812,7 +448,7 @@ static __init int can_dev_init(void)
>
>         can_led_notifier_init();
>
> -       err = rtnl_link_register(&can_link_ops);
> +       err = can_netlink_register();
>         if (!err)
>                 pr_info(MOD_DESC "\n");
>
> @@ -822,7 +458,7 @@ module_init(can_dev_init);
>
>  static __exit void can_dev_exit(void)
>  {
> -       rtnl_link_unregister(&can_link_ops);
> +       can_netlink_unregister();
>
>         can_led_notifier_exit();
>  }
> diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
> new file mode 100644
> index 000000000000..3ae884cdf677
> --- /dev/null
> +++ b/drivers/net/can/dev/netlink.c
> @@ -0,0 +1,379 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
> + * Copyright (C) 2006 Andrey Volkov, Varma Electronics
> + * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@xxxxxxxxxxxxxx>
> + */
> +
> +#include <linux/can/dev.h>
> +#include <net/rtnetlink.h>
> +
> +static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
> +       [IFLA_CAN_STATE]        = { .type = NLA_U32 },
> +       [IFLA_CAN_CTRLMODE]     = { .len = sizeof(struct can_ctrlmode) },
> +       [IFLA_CAN_RESTART_MS]   = { .type = NLA_U32 },
> +       [IFLA_CAN_RESTART]      = { .type = NLA_U32 },
> +       [IFLA_CAN_BITTIMING]    = { .len = sizeof(struct can_bittiming) },
> +       [IFLA_CAN_BITTIMING_CONST]
> +                               = { .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) },
> +       [IFLA_CAN_TERMINATION]  = { .type = NLA_U16 },
> +};
> +
> +static int can_validate(struct nlattr *tb[], struct nlattr *data[],
> +                       struct netlink_ext_ack *extack)
> +{
> +       bool is_can_fd = false;
> +
> +       /* Make sure that valid CAN FD configurations always consist of
> +        * - nominal/arbitration bittiming
> +        * - data bittiming
> +        * - control mode with CAN_CTRLMODE_FD set
> +        */
> +
> +       if (!data)
> +               return 0;
> +
> +       if (data[IFLA_CAN_CTRLMODE]) {
> +               struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
> +
> +               is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD;
> +       }
> +
> +       if (is_can_fd) {
> +               if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING])
> +                       return -EOPNOTSUPP;
> +       }
> +
> +       if (data[IFLA_CAN_DATA_BITTIMING]) {
> +               if (!is_can_fd || !data[IFLA_CAN_BITTIMING])
> +                       return -EOPNOTSUPP;
> +       }
> +
> +       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);
> +       int err;
> +
> +       /* We need synchronization with dev->stop() */
> +       ASSERT_RTNL();
> +
> +       if (data[IFLA_CAN_BITTIMING]) {
> +               struct can_bittiming bt;
> +
> +               /* Do not allow changing bittiming while running */
> +               if (dev->flags & IFF_UP)
> +                       return -EBUSY;
> +
> +               /* Calculate bittiming parameters based on
> +                * bittiming_const if set, otherwise pass bitrate
> +                * directly via do_set_bitrate(). Bail out if neither
> +                * is given.
> +                */
> +               if (!priv->bittiming_const && !priv->do_set_bittiming)
> +                       return -EOPNOTSUPP;
> +
> +               memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
> +               err = can_get_bittiming(dev, &bt,
> +                                       priv->bittiming_const,
> +                                       priv->bitrate_const,
> +                                       priv->bitrate_const_cnt);
> +               if (err)
> +                       return err;
> +
> +               if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) {
> +                       netdev_err(dev, "arbitration bitrate surpasses transceiver capabilities of %d bps\n",
> +                                  priv->bitrate_max);
> +                       return -EINVAL;
> +               }
> +
> +               memcpy(&priv->bittiming, &bt, sizeof(bt));
> +
> +               if (priv->do_set_bittiming) {
> +                       /* Finally, set the bit-timing registers */
> +                       err = priv->do_set_bittiming(dev);
> +                       if (err)
> +                               return err;
> +               }
> +       }
> +
> +       if (data[IFLA_CAN_CTRLMODE]) {
> +               struct can_ctrlmode *cm;
> +               u32 ctrlstatic;
> +               u32 maskedflags;
> +
> +               /* Do not allow changing controller mode while running */
> +               if (dev->flags & IFF_UP)
> +                       return -EBUSY;
> +               cm = nla_data(data[IFLA_CAN_CTRLMODE]);
> +               ctrlstatic = priv->ctrlmode_static;
> +               maskedflags = cm->flags & cm->mask;
> +
> +               /* check whether provided bits are allowed to be passed */
> +               if (cm->mask & ~(priv->ctrlmode_supported | ctrlstatic))
> +                       return -EOPNOTSUPP;
> +
> +               /* do not check for static fd-non-iso if 'fd' is disabled */
> +               if (!(maskedflags & CAN_CTRLMODE_FD))
> +                       ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO;
> +
> +               /* make sure static options are provided by configuration */
> +               if ((maskedflags & ctrlstatic) != ctrlstatic)
> +                       return -EOPNOTSUPP;
> +
> +               /* clear bits to be modified and copy the flag values */
> +               priv->ctrlmode &= ~cm->mask;
> +               priv->ctrlmode |= maskedflags;
> +
> +               /* 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]) {
> +               /* Do not allow changing restart delay while running */
> +               if (dev->flags & IFF_UP)
> +                       return -EBUSY;
> +               priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]);
> +       }
> +
> +       if (data[IFLA_CAN_RESTART]) {
> +               /* Do not allow a restart while not running */
> +               if (!(dev->flags & IFF_UP))
> +                       return -EINVAL;
> +               err = can_restart_now(dev);
> +               if (err)
> +                       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;
> +
> +               /* Calculate bittiming parameters based on
> +                * data_bittiming_const if set, otherwise pass bitrate
> +                * directly via do_set_bitrate(). Bail out if neither
> +                * is given.
> +                */
> +               if (!priv->data_bittiming_const && !priv->do_set_data_bittiming)
> +                       return -EOPNOTSUPP;
> +
> +               memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
> +                      sizeof(dbt));
> +               err = can_get_bittiming(dev, &dbt,
> +                                       priv->data_bittiming_const,
> +                                       priv->data_bitrate_const,
> +                                       priv->data_bitrate_const_cnt);
> +               if (err)
> +                       return err;
> +
> +               if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) {
> +                       netdev_err(dev, "canfd data bitrate surpasses transceiver capabilities of %d bps\n",
> +                                  priv->bitrate_max);
> +                       return -EINVAL;
> +               }
> +
> +               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;
> +               }
> +       }
> +
> +       if (data[IFLA_CAN_TERMINATION]) {
> +               const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]);
> +               const unsigned int num_term = priv->termination_const_cnt;
> +               unsigned int i;
> +
> +               if (!priv->do_set_termination)
> +                       return -EOPNOTSUPP;
> +
> +               /* check whether given value is supported by the interface */
> +               for (i = 0; i < num_term; i++) {
> +                       if (termval == priv->termination_const[i])
> +                               break;
> +               }
> +               if (i >= num_term)
> +                       return -EINVAL;
> +
> +               /* Finally, set the termination value */
> +               err = priv->do_set_termination(dev, termval);
> +               if (err)
> +                       return err;
> +
> +               priv->termination = termval;
> +       }
> +
> +       return 0;
> +}
> +
> +static size_t can_get_size(const struct net_device *dev)
> +{
> +       struct can_priv *priv = netdev_priv(dev);
> +       size_t size = 0;
> +
> +       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 */
> +       size += nla_total_size(sizeof(u32));                    /* IFLA_CAN_STATE */
> +       size += nla_total_size(sizeof(struct can_ctrlmode));    /* IFLA_CAN_CTRLMODE */
> +       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));
> +       if (priv->termination_const) {
> +               size += nla_total_size(sizeof(priv->termination));              /* IFLA_CAN_TERMINATION */
> +               size += nla_total_size(sizeof(*priv->termination_const) *       /* IFLA_CAN_TERMINATION_CONST */
> +                                      priv->termination_const_cnt);
> +       }
> +       if (priv->bitrate_const)                                /* IFLA_CAN_BITRATE_CONST */
> +               size += nla_total_size(sizeof(*priv->bitrate_const) *
> +                                      priv->bitrate_const_cnt);
> +       if (priv->data_bitrate_const)                           /* IFLA_CAN_DATA_BITRATE_CONST */
> +               size += nla_total_size(sizeof(*priv->data_bitrate_const) *
> +                                      priv->data_bitrate_const_cnt);
> +       size += sizeof(priv->bitrate_max);                      /* IFLA_CAN_BITRATE_MAX */
> +
> +       return size;
> +}
> +
> +static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
> +{
> +       struct can_priv *priv = netdev_priv(dev);
> +       struct can_ctrlmode cm = {.flags = priv->ctrlmode};
> +       struct can_berr_counter bec;
> +       enum can_state state = priv->state;
> +
> +       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(priv->clock), &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)) ||
> +
> +           (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)) ||
> +
> +           (priv->termination_const &&
> +            (nla_put_u16(skb, IFLA_CAN_TERMINATION, priv->termination) ||
> +             nla_put(skb, IFLA_CAN_TERMINATION_CONST,
> +                     sizeof(*priv->termination_const) *
> +                     priv->termination_const_cnt,
> +                     priv->termination_const))) ||
> +
> +           (priv->bitrate_const &&
> +            nla_put(skb, IFLA_CAN_BITRATE_CONST,
> +                    sizeof(*priv->bitrate_const) *
> +                    priv->bitrate_const_cnt,
> +                    priv->bitrate_const)) ||
> +
> +           (priv->data_bitrate_const &&
> +            nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST,
> +                    sizeof(*priv->data_bitrate_const) *
> +                    priv->data_bitrate_const_cnt,
> +                    priv->data_bitrate_const)) ||
> +
> +           (nla_put(skb, IFLA_CAN_BITRATE_MAX,
> +                    sizeof(priv->bitrate_max),
> +                    &priv->bitrate_max))
> +           )
> +
> +               return -EMSGSIZE;
> +
> +       return 0;
> +}
> +
> +static size_t can_get_xstats_size(const struct net_device *dev)
> +{
> +       return sizeof(struct can_device_stats);
> +}
> +
> +static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
> +{
> +       struct can_priv *priv = netdev_priv(dev);
> +
> +       if (nla_put(skb, IFLA_INFO_XSTATS,
> +                   sizeof(priv->can_stats), &priv->can_stats))
> +               goto nla_put_failure;
> +       return 0;
> +
> +nla_put_failure:
> +       return -EMSGSIZE;
> +}
> +
> +static int can_newlink(struct net *src_net, struct net_device *dev,
> +                      struct nlattr *tb[], struct nlattr *data[],
> +                      struct netlink_ext_ack *extack)
> +{
> +       return -EOPNOTSUPP;
> +}
> +
> +static void can_dellink(struct net_device *dev, struct list_head *head)
> +{
> +}
> +
> +struct rtnl_link_ops can_link_ops __read_mostly = {
> +       .kind           = "can",
> +       .maxtype        = IFLA_CAN_MAX,
> +       .policy         = can_policy,
> +       .setup          = can_setup,
> +       .validate       = can_validate,
> +       .newlink        = can_newlink,
> +       .changelink     = can_changelink,
> +       .dellink        = can_dellink,
> +       .get_size       = can_get_size,
> +       .fill_info      = can_fill_info,
> +       .get_xstats_size = can_get_xstats_size,
> +       .fill_xstats    = can_fill_xstats,
> +};
> +
> +int can_netlink_register(void)
> +{
> +       return rtnl_link_register(&can_link_ops);
> +}
> +
> +void can_netlink_unregister(void)
> +{
> +       rtnl_link_unregister(&can_link_ops);
> +}
> diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
> index 4a26e128af7f..7faf6a37d5b2 100644
> --- a/include/linux/can/dev.h
> +++ b/include/linux/can/dev.h
> @@ -100,6 +100,8 @@ static inline void can_set_static_ctrlmode(struct net_device *dev,
>                 dev->mtu = CANFD_MTU;
>  }
>
> +void can_setup(struct net_device *dev);
> +
>  struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
>                                     unsigned int txqs, unsigned int rxqs);
>  #define alloc_candev(sizeof_priv, echo_skb_max) \
> @@ -130,4 +132,8 @@ void of_can_transceiver(struct net_device *dev);
>  static inline void of_can_transceiver(struct net_device *dev) { }
>  #endif
>
> +extern struct rtnl_link_ops can_link_ops;
> +int can_netlink_register(void);
> +void can_netlink_unregister(void);
> +
>  #endif /* !_CAN_DEV_H */
> --
> 2.29.2
>
>

Same as previous message but for netlink: fails to build. I think
you just forgot to include the changes on
drivers/net/can/dev/Makefile (c.f. below).

diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile
index 2c38bd532157..6624be65de6f 100644
--- a/drivers/net/can/dev/Makefile
+++ b/drivers/net/can/dev/Makefile
@@ -6,5 +6,6 @@ can-dev-y            += dev.o
 can-dev-y            += length.o
 can-dev-y            += rx-offload.o
 can-dev-y            += skb.o
+can-dev-y            += netlink.o

 can-dev-$(CONFIG_CAN_LEDS)    += led.o



[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux