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.14.15
  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			      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
 66const struct ethnl_request_ops ethnl_debug_request_ops = {
 67	.request_cmd		= ETHTOOL_MSG_DEBUG_GET,
 68	.reply_cmd		= ETHTOOL_MSG_DEBUG_GET_REPLY,
 69	.hdr_attr		= ETHTOOL_A_DEBUG_HEADER,
 70	.req_info_size		= sizeof(struct debug_req_info),
 71	.reply_data_size	= sizeof(struct debug_reply_data),
 72
 73	.prepare_data		= debug_prepare_data,
 74	.reply_size		= debug_reply_size,
 75	.fill_reply		= debug_fill_reply,
 76};
 77
 78/* DEBUG_SET */
 79
 80const struct nla_policy ethnl_debug_set_policy[] = {
 81	[ETHTOOL_A_DEBUG_HEADER]	=
 82		NLA_POLICY_NESTED(ethnl_header_policy),
 83	[ETHTOOL_A_DEBUG_MSGMASK]	= { .type = NLA_NESTED },
 84};
 85
 86int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info)
 
 
 87{
 88	struct ethnl_req_info req_info = {};
 
 
 
 
 
 
 
 
 89	struct nlattr **tb = info->attrs;
 90	struct net_device *dev;
 91	bool mod = false;
 92	u32 msg_mask;
 93	int ret;
 94
 95	ret = ethnl_parse_header_dev_get(&req_info,
 96					 tb[ETHTOOL_A_DEBUG_HEADER],
 97					 genl_info_net(info), info->extack,
 98					 true);
 99	if (ret < 0)
100		return ret;
101	dev = req_info.dev;
102	ret = -EOPNOTSUPP;
103	if (!dev->ethtool_ops->get_msglevel || !dev->ethtool_ops->set_msglevel)
104		goto out_dev;
105
106	rtnl_lock();
107	ret = ethnl_ops_begin(dev);
108	if (ret < 0)
109		goto out_rtnl;
110
111	msg_mask = dev->ethtool_ops->get_msglevel(dev);
112	ret = ethnl_update_bitset32(&msg_mask, NETIF_MSG_CLASS_COUNT,
113				    tb[ETHTOOL_A_DEBUG_MSGMASK],
114				    netif_msg_class_names, info->extack, &mod);
115	if (ret < 0 || !mod)
116		goto out_ops;
117
118	dev->ethtool_ops->set_msglevel(dev, msg_mask);
119	ethtool_notify(dev, ETHTOOL_MSG_DEBUG_NTF, NULL);
 
120
121out_ops:
122	ethnl_ops_complete(dev);
123out_rtnl:
124	rtnl_unlock();
125out_dev:
126	dev_put(dev);
127	return ret;
128}