Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2
  3#include "netlink.h"
  4#include "common.h"
  5#include "bitset.h"
  6
  7struct debug_req_info {
  8	struct ethnl_req_info		base;
  9};
 10
 11struct debug_reply_data {
 12	struct ethnl_reply_data		base;
 13	u32				msg_mask;
 14};
 15
 16#define DEBUG_REPDATA(__reply_base) \
 17	container_of(__reply_base, struct debug_reply_data, base)
 18
 19const struct nla_policy ethnl_debug_get_policy[] = {
 20	[ETHTOOL_A_DEBUG_HEADER]	=
 21		NLA_POLICY_NESTED(ethnl_header_policy),
 
 
 22};
 23
 24static int debug_prepare_data(const struct ethnl_req_info *req_base,
 25			      struct ethnl_reply_data *reply_base,
 26			      const struct genl_info *info)
 27{
 28	struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
 29	struct net_device *dev = reply_base->dev;
 30	int ret;
 31
 32	if (!dev->ethtool_ops->get_msglevel)
 33		return -EOPNOTSUPP;
 34
 35	ret = ethnl_ops_begin(dev);
 36	if (ret < 0)
 37		return ret;
 38	data->msg_mask = dev->ethtool_ops->get_msglevel(dev);
 39	ethnl_ops_complete(dev);
 40
 41	return 0;
 42}
 43
 44static int debug_reply_size(const struct ethnl_req_info *req_base,
 45			    const struct ethnl_reply_data *reply_base)
 46{
 47	const struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
 48	bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
 49
 50	return ethnl_bitset32_size(&data->msg_mask, NULL, NETIF_MSG_CLASS_COUNT,
 51				   netif_msg_class_names, compact);
 52}
 53
 54static int debug_fill_reply(struct sk_buff *skb,
 55			    const struct ethnl_req_info *req_base,
 56			    const struct ethnl_reply_data *reply_base)
 57{
 58	const struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
 59	bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
 60
 61	return ethnl_put_bitset32(skb, ETHTOOL_A_DEBUG_MSGMASK, &data->msg_mask,
 62				  NULL, NETIF_MSG_CLASS_COUNT,
 63				  netif_msg_class_names, compact);
 64}
 65
 66/* DEBUG_SET */
 
 
 
 
 
 
 
 67
 68const struct nla_policy ethnl_debug_set_policy[] = {
 69	[ETHTOOL_A_DEBUG_HEADER]	=
 70		NLA_POLICY_NESTED(ethnl_header_policy),
 71	[ETHTOOL_A_DEBUG_MSGMASK]	= { .type = NLA_NESTED },
 72};
 73
 74static int
 75ethnl_set_debug_validate(struct ethnl_req_info *req_info,
 76			 struct genl_info *info)
 77{
 78	const struct ethtool_ops *ops = req_info->dev->ethtool_ops;
 79
 80	return ops->get_msglevel && ops->set_msglevel ? 1 : -EOPNOTSUPP;
 81}
 
 
 
 
 82
 83static int
 84ethnl_set_debug(struct ethnl_req_info *req_info, struct genl_info *info)
 85{
 86	struct net_device *dev = req_info->dev;
 87	struct nlattr **tb = info->attrs;
 
 88	bool mod = false;
 89	u32 msg_mask;
 90	int ret;
 91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 92	msg_mask = dev->ethtool_ops->get_msglevel(dev);
 93	ret = ethnl_update_bitset32(&msg_mask, NETIF_MSG_CLASS_COUNT,
 94				    tb[ETHTOOL_A_DEBUG_MSGMASK],
 95				    netif_msg_class_names, info->extack, &mod);
 96	if (ret < 0 || !mod)
 97		return ret;
 98
 99	dev->ethtool_ops->set_msglevel(dev, msg_mask);
100	return 1;
101}
102
103const struct ethnl_request_ops ethnl_debug_request_ops = {
104	.request_cmd		= ETHTOOL_MSG_DEBUG_GET,
105	.reply_cmd		= ETHTOOL_MSG_DEBUG_GET_REPLY,
106	.hdr_attr		= ETHTOOL_A_DEBUG_HEADER,
107	.req_info_size		= sizeof(struct debug_req_info),
108	.reply_data_size	= sizeof(struct debug_reply_data),
109
110	.prepare_data		= debug_prepare_data,
111	.reply_size		= debug_reply_size,
112	.fill_reply		= debug_fill_reply,
113
114	.set_validate		= ethnl_set_debug_validate,
115	.set			= ethnl_set_debug,
116	.set_ntf_cmd		= ETHTOOL_MSG_DEBUG_NTF,
117};
 
 
 
 
v5.9
  1// SPDX-License-Identifier: GPL-2.0-only
  2
  3#include "netlink.h"
  4#include "common.h"
  5#include "bitset.h"
  6
  7struct debug_req_info {
  8	struct ethnl_req_info		base;
  9};
 10
 11struct debug_reply_data {
 12	struct ethnl_reply_data		base;
 13	u32				msg_mask;
 14};
 15
 16#define DEBUG_REPDATA(__reply_base) \
 17	container_of(__reply_base, struct debug_reply_data, base)
 18
 19static const struct nla_policy
 20debug_get_policy[ETHTOOL_A_DEBUG_MAX + 1] = {
 21	[ETHTOOL_A_DEBUG_UNSPEC]	= { .type = NLA_REJECT },
 22	[ETHTOOL_A_DEBUG_HEADER]	= { .type = NLA_NESTED },
 23	[ETHTOOL_A_DEBUG_MSGMASK]	= { .type = NLA_REJECT },
 24};
 25
 26static int debug_prepare_data(const struct ethnl_req_info *req_base,
 27			      struct ethnl_reply_data *reply_base,
 28			      struct genl_info *info)
 29{
 30	struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
 31	struct net_device *dev = reply_base->dev;
 32	int ret;
 33
 34	if (!dev->ethtool_ops->get_msglevel)
 35		return -EOPNOTSUPP;
 36
 37	ret = ethnl_ops_begin(dev);
 38	if (ret < 0)
 39		return ret;
 40	data->msg_mask = dev->ethtool_ops->get_msglevel(dev);
 41	ethnl_ops_complete(dev);
 42
 43	return 0;
 44}
 45
 46static int debug_reply_size(const struct ethnl_req_info *req_base,
 47			    const struct ethnl_reply_data *reply_base)
 48{
 49	const struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
 50	bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
 51
 52	return ethnl_bitset32_size(&data->msg_mask, NULL, NETIF_MSG_CLASS_COUNT,
 53				   netif_msg_class_names, compact);
 54}
 55
 56static int debug_fill_reply(struct sk_buff *skb,
 57			    const struct ethnl_req_info *req_base,
 58			    const struct ethnl_reply_data *reply_base)
 59{
 60	const struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
 61	bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
 62
 63	return ethnl_put_bitset32(skb, ETHTOOL_A_DEBUG_MSGMASK, &data->msg_mask,
 64				  NULL, NETIF_MSG_CLASS_COUNT,
 65				  netif_msg_class_names, compact);
 66}
 67
 68const struct ethnl_request_ops ethnl_debug_request_ops = {
 69	.request_cmd		= ETHTOOL_MSG_DEBUG_GET,
 70	.reply_cmd		= ETHTOOL_MSG_DEBUG_GET_REPLY,
 71	.hdr_attr		= ETHTOOL_A_DEBUG_HEADER,
 72	.max_attr		= ETHTOOL_A_DEBUG_MAX,
 73	.req_info_size		= sizeof(struct debug_req_info),
 74	.reply_data_size	= sizeof(struct debug_reply_data),
 75	.request_policy		= debug_get_policy,
 76
 77	.prepare_data		= debug_prepare_data,
 78	.reply_size		= debug_reply_size,
 79	.fill_reply		= debug_fill_reply,
 
 80};
 81
 82/* DEBUG_SET */
 
 
 
 
 83
 84static const struct nla_policy
 85debug_set_policy[ETHTOOL_A_DEBUG_MAX + 1] = {
 86	[ETHTOOL_A_DEBUG_UNSPEC]	= { .type = NLA_REJECT },
 87	[ETHTOOL_A_DEBUG_HEADER]	= { .type = NLA_NESTED },
 88	[ETHTOOL_A_DEBUG_MSGMASK]	= { .type = NLA_NESTED },
 89};
 90
 91int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info)
 
 92{
 93	struct nlattr *tb[ETHTOOL_A_DEBUG_MAX + 1];
 94	struct ethnl_req_info req_info = {};
 95	struct net_device *dev;
 96	bool mod = false;
 97	u32 msg_mask;
 98	int ret;
 99
100	ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb,
101			  ETHTOOL_A_DEBUG_MAX, debug_set_policy,
102			  info->extack);
103	if (ret < 0)
104		return ret;
105	ret = ethnl_parse_header_dev_get(&req_info,
106					 tb[ETHTOOL_A_DEBUG_HEADER],
107					 genl_info_net(info), info->extack,
108					 true);
109	if (ret < 0)
110		return ret;
111	dev = req_info.dev;
112	ret = -EOPNOTSUPP;
113	if (!dev->ethtool_ops->get_msglevel || !dev->ethtool_ops->set_msglevel)
114		goto out_dev;
115
116	rtnl_lock();
117	ret = ethnl_ops_begin(dev);
118	if (ret < 0)
119		goto out_rtnl;
120
121	msg_mask = dev->ethtool_ops->get_msglevel(dev);
122	ret = ethnl_update_bitset32(&msg_mask, NETIF_MSG_CLASS_COUNT,
123				    tb[ETHTOOL_A_DEBUG_MSGMASK],
124				    netif_msg_class_names, info->extack, &mod);
125	if (ret < 0 || !mod)
126		goto out_ops;
127
128	dev->ethtool_ops->set_msglevel(dev, msg_mask);
129	ethtool_notify(dev, ETHTOOL_MSG_DEBUG_NTF, NULL);
 
 
 
 
 
 
 
 
 
 
 
 
130
131out_ops:
132	ethnl_ops_complete(dev);
133out_rtnl:
134	rtnl_unlock();
135out_dev:
136	dev_put(dev);
137	return ret;
138}