From: Roopa Prabhu <roopa@nvidia.com>
To: intel-wired-lan@osuosl.org
Subject: [Intel-wired-lan] [PATCH net-next 4/6] rtnetlink: Add support for SyncE recovered clock configuration
Date: Thu, 4 Nov 2021 11:24:46 -0700 [thread overview]
Message-ID: <2d379392-a381-e60a-7658-5ac695c30df1@nvidia.com> (raw)
In-Reply-To: <20211104081231.1982753-5-maciej.machnikowski@intel.com>
On 11/4/21 1:12 AM, Maciej Machnikowski wrote:
> Add support for RTNL messages for reading/configuring SyncE recovered
> clocks.
> The messages are:
> RTM_GETRCLKRANGE: Reads the allowed pin index range for the recovered
> clock outputs. This can be aligned to PHY outputs or
> to EEC inputs, whichever is better for a given
> application
>
> RTM_GETRCLKSTATE: Read the state of recovered pins that output recovered
> clock from a given port. The message will contain the
> number of assigned clocks (IFLA_RCLK_STATE_COUNT) and
> a N pin inexes in IFLA_RCLK_STATE_OUT_IDX
>
> RTM_SETRCLKSTATE: Sets the redirection of the recovered clock for
> a given pin
>
> Signed-off-by: Maciej Machnikowski <maciej.machnikowski@intel.com>
> ---
Can't we just use a single RTM msg with nested attributes ?
With separate RTM msgtype for each syncE attribute we will end up
bloating the RTM msg namespace.
(these api's could also be in ethtool given its directly querying the
drivers)
> include/linux/netdevice.h | 9 ++
> include/uapi/linux/if_link.h | 26 +++++
> include/uapi/linux/rtnetlink.h | 7 ++
> net/core/rtnetlink.c | 174 +++++++++++++++++++++++++++++++++
> security/selinux/nlmsgtab.c | 3 +
> 5 files changed, 219 insertions(+)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index ef2b381dae0c..708bd8336155 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1576,6 +1576,15 @@ struct net_device_ops {
> int (*ndo_get_eec_src)(struct net_device *dev,
> u32 *src,
> struct netlink_ext_ack *extack);
> + int (*ndo_get_rclk_range)(struct net_device *dev,
> + u32 *min_idx, u32 *max_idx,
> + struct netlink_ext_ack *extack);
> + int (*ndo_set_rclk_out)(struct net_device *dev,
> + u32 out_idx, bool ena,
> + struct netlink_ext_ack *extack);
> + int (*ndo_get_rclk_state)(struct net_device *dev,
> + u32 out_idx, bool *ena,
> + struct netlink_ext_ack *extack);
> };
>
> /**
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index 8eae80f287e9..e27c153cfba3 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -1304,4 +1304,30 @@ enum {
>
> #define IFLA_EEC_MAX (__IFLA_EEC_MAX - 1)
>
> +struct if_rclk_range_msg {
> + __u32 ifindex;
> +};
> +
> +enum {
> + IFLA_RCLK_RANGE_UNSPEC,
> + IFLA_RCLK_RANGE_MIN_PIN,
> + IFLA_RCLK_RANGE_MAX_PIN,
> + __IFLA_RCLK_RANGE_MAX,
> +};
> +
> +struct if_set_rclk_msg {
> + __u32 ifindex;
> + __u32 out_idx;
> + __u32 flags;
> +};
> +
> +#define SET_RCLK_FLAGS_ENA (1U << 0)
> +
> +enum {
> + IFLA_RCLK_STATE_UNSPEC,
> + IFLA_RCLK_STATE_OUT_IDX,
> + IFLA_RCLK_STATE_COUNT,
> + __IFLA_RCLK_STATE_MAX,
> +};
> +
> #endif /* _UAPI_LINUX_IF_LINK_H */
> diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
> index 1d8662afd6bd..6c0d96d56ec7 100644
> --- a/include/uapi/linux/rtnetlink.h
> +++ b/include/uapi/linux/rtnetlink.h
> @@ -185,6 +185,13 @@ enum {
> RTM_GETNEXTHOPBUCKET,
> #define RTM_GETNEXTHOPBUCKET RTM_GETNEXTHOPBUCKET
>
> + RTM_GETRCLKRANGE = 120,
> +#define RTM_GETRCLKRANGE RTM_GETRCLKRANGE
> + RTM_GETRCLKSTATE = 121,
> +#define RTM_GETRCLKSTATE RTM_GETRCLKSTATE
> + RTM_SETRCLKSTATE = 122,
> +#define RTM_SETRCLKSTATE RTM_SETRCLKSTATE
> +
> RTM_GETEECSTATE = 124,
> #define RTM_GETEECSTATE RTM_GETEECSTATE
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 03bc773d0e69..bc1e050f6d38 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -5544,6 +5544,176 @@ static int rtnl_eec_state_get(struct sk_buff *skb, struct nlmsghdr *nlh,
> return err;
> }
>
> +static int rtnl_fill_rclk_range(struct sk_buff *skb, struct net_device *dev,
> + u32 portid, u32 seq,
> + struct netlink_callback *cb, int flags,
> + struct netlink_ext_ack *extack)
> +{
> + const struct net_device_ops *ops = dev->netdev_ops;
> + struct if_rclk_range_msg *state_msg;
> + struct nlmsghdr *nlh;
> + u32 min_idx, max_idx;
> + int err;
> +
> + ASSERT_RTNL();
> +
> + if (!ops->ndo_get_rclk_range)
> + return -EOPNOTSUPP;
> +
> + err = ops->ndo_get_rclk_range(dev, &min_idx, &max_idx, extack);
> + if (err)
> + return err;
> +
> + nlh = nlmsg_put(skb, portid, seq, RTM_GETRCLKRANGE, sizeof(*state_msg),
> + flags);
> + if (!nlh)
> + return -EMSGSIZE;
> +
> + state_msg = nlmsg_data(nlh);
> + state_msg->ifindex = dev->ifindex;
> +
> + if (nla_put_u32(skb, IFLA_RCLK_RANGE_MIN_PIN, min_idx) ||
> + nla_put_u32(skb, IFLA_RCLK_RANGE_MAX_PIN, max_idx))
> + return -EMSGSIZE;
> +
> + nlmsg_end(skb, nlh);
> + return 0;
> +}
> +
> +static int rtnl_rclk_range_get(struct sk_buff *skb, struct nlmsghdr *nlh,
> + struct netlink_ext_ack *extack)
> +{
> + struct net *net = sock_net(skb->sk);
> + struct if_eec_state_msg *state;
> + struct net_device *dev;
> + struct sk_buff *nskb;
> + int err;
> +
> + state = nlmsg_data(nlh);
> + dev = __dev_get_by_index(net, state->ifindex);
> + if (!dev) {
> + NL_SET_ERR_MSG(extack, "unknown ifindex");
> + return -ENODEV;
> + }
> +
> + nskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> + if (!nskb)
> + return -ENOBUFS;
> +
> + err = rtnl_fill_rclk_range(nskb, dev, NETLINK_CB(skb).portid,
> + nlh->nlmsg_seq, NULL, nlh->nlmsg_flags,
> + extack);
> + if (err < 0)
> + kfree_skb(nskb);
> + else
> + err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid);
> +
> + return err;
> +}
> +
> +static int rtnl_fill_rclk_state(struct sk_buff *skb, struct net_device *dev,
> + u32 portid, u32 seq,
> + struct netlink_callback *cb, int flags,
> + struct netlink_ext_ack *extack)
> +{
> + const struct net_device_ops *ops = dev->netdev_ops;
> + u32 min_idx, max_idx, src_idx, count = 0;
> + struct if_eec_state_msg *state_msg;
> + struct nlmsghdr *nlh;
> + bool ena;
> + int err;
> +
> + ASSERT_RTNL();
> +
> + if (!ops->ndo_get_rclk_state || !ops->ndo_get_rclk_range)
> + return -EOPNOTSUPP;
> +
> + err = ops->ndo_get_rclk_range(dev, &min_idx, &max_idx, extack);
> + if (err)
> + return err;
> +
> + nlh = nlmsg_put(skb, portid, seq, RTM_GETRCLKSTATE, sizeof(*state_msg),
> + flags);
> + if (!nlh)
> + return -EMSGSIZE;
> +
> + state_msg = nlmsg_data(nlh);
> + state_msg->ifindex = dev->ifindex;
> +
> + for (src_idx = min_idx; src_idx <= max_idx; src_idx++) {
> + ops->ndo_get_rclk_state(dev, src_idx, &ena, extack);
> + if (!ena)
> + continue;
> +
> + if (nla_put_u32(skb, IFLA_RCLK_STATE_OUT_IDX, src_idx))
> + return -EMSGSIZE;
> + count++;
> + }
> +
> + if (nla_put_u32(skb, IFLA_RCLK_STATE_COUNT, count))
> + return -EMSGSIZE;
> +
> + nlmsg_end(skb, nlh);
> + return 0;
> +}
> +
> +static int rtnl_rclk_state_get(struct sk_buff *skb, struct nlmsghdr *nlh,
> + struct netlink_ext_ack *extack)
> +{
> + struct net *net = sock_net(skb->sk);
> + struct if_eec_state_msg *state;
> + struct net_device *dev;
> + struct sk_buff *nskb;
> + int err;
> +
> + state = nlmsg_data(nlh);
> + dev = __dev_get_by_index(net, state->ifindex);
> + if (!dev) {
> + NL_SET_ERR_MSG(extack, "unknown ifindex");
> + return -ENODEV;
> + }
> +
> + nskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> + if (!nskb)
> + return -ENOBUFS;
> +
> + err = rtnl_fill_rclk_state(nskb, dev, NETLINK_CB(skb).portid,
> + nlh->nlmsg_seq, NULL, nlh->nlmsg_flags,
> + extack);
> + if (err < 0)
> + kfree_skb(nskb);
> + else
> + err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid);
> +
> + return err;
> +}
> +
> +static int rtnl_rclk_set(struct sk_buff *skb, struct nlmsghdr *nlh,
> + struct netlink_ext_ack *extack)
> +{
> + struct net *net = sock_net(skb->sk);
> + struct if_set_rclk_msg *state;
> + struct net_device *dev;
> + bool ena;
> + int err;
> +
> + state = nlmsg_data(nlh);
> + dev = __dev_get_by_index(net, state->ifindex);
> + if (!dev) {
> + NL_SET_ERR_MSG(extack, "unknown ifindex");
> + return -ENODEV;
> + }
> +
> + if (!dev->netdev_ops->ndo_set_rclk_out)
> + return -EOPNOTSUPP;
> +
> + ena = !!(state->flags & SET_RCLK_FLAGS_ENA);
> + err = dev->netdev_ops->ndo_set_rclk_out(dev, state->out_idx, ena,
> + extack);
> +
> + return err;
> +}
> +
> /* Process one rtnetlink message. */
>
> static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
> @@ -5770,5 +5940,9 @@ void __init rtnetlink_init(void)
> rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump,
> 0);
>
> + rtnl_register(PF_UNSPEC, RTM_GETRCLKRANGE, rtnl_rclk_range_get, NULL, 0);
> + rtnl_register(PF_UNSPEC, RTM_GETRCLKSTATE, rtnl_rclk_state_get, NULL, 0);
> + rtnl_register(PF_UNSPEC, RTM_SETRCLKSTATE, rtnl_rclk_set, NULL, 0);
> +
> rtnl_register(PF_UNSPEC, RTM_GETEECSTATE, rtnl_eec_state_get, NULL, 0);
> }
> diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
> index 2c66e722ea9c..57c7c85edd4d 100644
> --- a/security/selinux/nlmsgtab.c
> +++ b/security/selinux/nlmsgtab.c
> @@ -91,6 +91,9 @@ static const struct nlmsg_perm nlmsg_route_perms[] =
> { RTM_NEWNEXTHOPBUCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
> { RTM_DELNEXTHOPBUCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
> { RTM_GETNEXTHOPBUCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ },
> + { RTM_GETRCLKRANGE, NETLINK_ROUTE_SOCKET__NLMSG_READ },
> + { RTM_GETRCLKSTATE, NETLINK_ROUTE_SOCKET__NLMSG_READ },
> + { RTM_SETRCLKSTATE, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
> { RTM_GETEECSTATE, NETLINK_ROUTE_SOCKET__NLMSG_READ },
> };
>
next prev parent reply other threads:[~2021-11-04 18:24 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-04 8:12 [Intel-wired-lan] [PATCH net-next 0/6] Add RTNL interface for SyncE Maciej Machnikowski
2021-11-04 8:12 ` [Intel-wired-lan] [PATCH net-next 1/6] ice: add support detecting features based on netlist Maciej Machnikowski
2021-11-04 8:12 ` [Intel-wired-lan] [PATCH net-next 2/6] rtnetlink: Add new RTM_GETEECSTATE message to get SyncE status Maciej Machnikowski
2021-11-04 8:12 ` [Intel-wired-lan] [PATCH net-next 3/6] ice: add support for reading SyncE DPLL state Maciej Machnikowski
2021-11-04 8:12 ` [Intel-wired-lan] [PATCH net-next 4/6] rtnetlink: Add support for SyncE recovered clock configuration Maciej Machnikowski
2021-11-04 18:24 ` Roopa Prabhu [this message]
2021-11-05 12:17 ` Machnikowski, Maciej
2021-11-07 14:21 ` Ido Schimmel
2021-11-08 9:03 ` Machnikowski, Maciej
2021-11-04 8:12 ` [Intel-wired-lan] [PATCH net-next 5/6] ice: add support for SyncE recovered clocks Maciej Machnikowski
2021-11-04 8:12 ` [Intel-wired-lan] [PATCH net-next 6/6] docs: net: Add description of SyncE interfaces Maciej Machnikowski
2021-11-04 18:08 ` Jakub Kicinski
2021-11-05 11:51 ` Machnikowski, Maciej
2021-11-05 21:30 ` Jakub Kicinski
2021-11-06 0:01 ` Machnikowski, Maciej
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2d379392-a381-e60a-7658-5ac695c30df1@nvidia.com \
--to=roopa@nvidia.com \
--cc=intel-wired-lan@osuosl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox