xref: /aosp_15_r20/external/ethtool/netlink/channels.c (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1*1b481fc3SMaciej Żenczykowski /*
2*1b481fc3SMaciej Żenczykowski  * channels.c - netlink implementation of channel commands
3*1b481fc3SMaciej Żenczykowski  *
4*1b481fc3SMaciej Żenczykowski  * Implementation of "ethtool -l <dev>" and "ethtool -L <dev> ..."
5*1b481fc3SMaciej Żenczykowski  */
6*1b481fc3SMaciej Żenczykowski 
7*1b481fc3SMaciej Żenczykowski #include <errno.h>
8*1b481fc3SMaciej Żenczykowski #include <string.h>
9*1b481fc3SMaciej Żenczykowski #include <stdio.h>
10*1b481fc3SMaciej Żenczykowski 
11*1b481fc3SMaciej Żenczykowski #include "../internal.h"
12*1b481fc3SMaciej Żenczykowski #include "../common.h"
13*1b481fc3SMaciej Żenczykowski #include "netlink.h"
14*1b481fc3SMaciej Żenczykowski #include "parser.h"
15*1b481fc3SMaciej Żenczykowski 
16*1b481fc3SMaciej Żenczykowski /* CHANNELS_GET */
17*1b481fc3SMaciej Żenczykowski 
channels_reply_cb(const struct nlmsghdr * nlhdr,void * data)18*1b481fc3SMaciej Żenczykowski int channels_reply_cb(const struct nlmsghdr *nlhdr, void *data)
19*1b481fc3SMaciej Żenczykowski {
20*1b481fc3SMaciej Żenczykowski 	const struct nlattr *tb[ETHTOOL_A_CHANNELS_MAX + 1] = {};
21*1b481fc3SMaciej Żenczykowski 	DECLARE_ATTR_TB_INFO(tb);
22*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = data;
23*1b481fc3SMaciej Żenczykowski 	bool silent;
24*1b481fc3SMaciej Żenczykowski 	int err_ret;
25*1b481fc3SMaciej Żenczykowski 	int ret;
26*1b481fc3SMaciej Żenczykowski 
27*1b481fc3SMaciej Żenczykowski 	silent = nlctx->is_dump || nlctx->is_monitor;
28*1b481fc3SMaciej Żenczykowski 	err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR;
29*1b481fc3SMaciej Żenczykowski 	ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
30*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
31*1b481fc3SMaciej Żenczykowski 		return err_ret;
32*1b481fc3SMaciej Żenczykowski 	nlctx->devname = get_dev_name(tb[ETHTOOL_A_CHANNELS_HEADER]);
33*1b481fc3SMaciej Żenczykowski 	if (!dev_ok(nlctx))
34*1b481fc3SMaciej Żenczykowski 		return err_ret;
35*1b481fc3SMaciej Żenczykowski 
36*1b481fc3SMaciej Żenczykowski 	if (silent)
37*1b481fc3SMaciej Żenczykowski 		putchar('\n');
38*1b481fc3SMaciej Żenczykowski 	printf("Channel parameters for %s:\n", nlctx->devname);
39*1b481fc3SMaciej Żenczykowski 	printf("Pre-set maximums:\n");
40*1b481fc3SMaciej Żenczykowski 	show_u32("rx-max", "RX:\t\t", tb[ETHTOOL_A_CHANNELS_RX_MAX]);
41*1b481fc3SMaciej Żenczykowski 	show_u32("tx-max", "TX:\t\t", tb[ETHTOOL_A_CHANNELS_TX_MAX]);
42*1b481fc3SMaciej Żenczykowski 	show_u32("other-max", "Other:\t\t", tb[ETHTOOL_A_CHANNELS_OTHER_MAX]);
43*1b481fc3SMaciej Żenczykowski 	show_u32("combined-max", "Combined:\t",
44*1b481fc3SMaciej Żenczykowski 		 tb[ETHTOOL_A_CHANNELS_COMBINED_MAX]);
45*1b481fc3SMaciej Żenczykowski 	printf("Current hardware settings:\n");
46*1b481fc3SMaciej Żenczykowski 	show_u32("rx", "RX:\t\t", tb[ETHTOOL_A_CHANNELS_RX_COUNT]);
47*1b481fc3SMaciej Żenczykowski 	show_u32("tx", "TX:\t\t", tb[ETHTOOL_A_CHANNELS_TX_COUNT]);
48*1b481fc3SMaciej Żenczykowski 	show_u32("other", "Other:\t\t", tb[ETHTOOL_A_CHANNELS_OTHER_COUNT]);
49*1b481fc3SMaciej Żenczykowski 	show_u32("combined", "Combined:\t",
50*1b481fc3SMaciej Żenczykowski 		 tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]);
51*1b481fc3SMaciej Żenczykowski 
52*1b481fc3SMaciej Żenczykowski 	return MNL_CB_OK;
53*1b481fc3SMaciej Żenczykowski }
54*1b481fc3SMaciej Żenczykowski 
nl_gchannels(struct cmd_context * ctx)55*1b481fc3SMaciej Żenczykowski int nl_gchannels(struct cmd_context *ctx)
56*1b481fc3SMaciej Żenczykowski {
57*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = ctx->nlctx;
58*1b481fc3SMaciej Żenczykowski 	struct nl_socket *nlsk = nlctx->ethnl_socket;
59*1b481fc3SMaciej Żenczykowski 	int ret;
60*1b481fc3SMaciej Żenczykowski 
61*1b481fc3SMaciej Żenczykowski 	if (netlink_cmd_check(ctx, ETHTOOL_MSG_CHANNELS_GET, true))
62*1b481fc3SMaciej Żenczykowski 		return -EOPNOTSUPP;
63*1b481fc3SMaciej Żenczykowski 	if (ctx->argc > 0) {
64*1b481fc3SMaciej Żenczykowski 		fprintf(stderr, "ethtool: unexpected parameter '%s'\n",
65*1b481fc3SMaciej Żenczykowski 			*ctx->argp);
66*1b481fc3SMaciej Żenczykowski 		return 1;
67*1b481fc3SMaciej Żenczykowski 	}
68*1b481fc3SMaciej Żenczykowski 
69*1b481fc3SMaciej Żenczykowski 	ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_CHANNELS_GET,
70*1b481fc3SMaciej Żenczykowski 				      ETHTOOL_A_CHANNELS_HEADER, 0);
71*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
72*1b481fc3SMaciej Żenczykowski 		return ret;
73*1b481fc3SMaciej Żenczykowski 	return nlsock_send_get_request(nlsk, channels_reply_cb);
74*1b481fc3SMaciej Żenczykowski }
75*1b481fc3SMaciej Żenczykowski 
76*1b481fc3SMaciej Żenczykowski /* CHANNELS_SET */
77*1b481fc3SMaciej Żenczykowski 
78*1b481fc3SMaciej Żenczykowski static const struct param_parser schannels_params[] = {
79*1b481fc3SMaciej Żenczykowski 	{
80*1b481fc3SMaciej Żenczykowski 		.arg		= "rx",
81*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_CHANNELS_RX_COUNT,
82*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
83*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
84*1b481fc3SMaciej Żenczykowski 	},
85*1b481fc3SMaciej Żenczykowski 	{
86*1b481fc3SMaciej Żenczykowski 		.arg		= "tx",
87*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_CHANNELS_TX_COUNT,
88*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
89*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
90*1b481fc3SMaciej Żenczykowski 	},
91*1b481fc3SMaciej Żenczykowski 	{
92*1b481fc3SMaciej Żenczykowski 		.arg		= "other",
93*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_CHANNELS_OTHER_COUNT,
94*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
95*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
96*1b481fc3SMaciej Żenczykowski 	},
97*1b481fc3SMaciej Żenczykowski 	{
98*1b481fc3SMaciej Żenczykowski 		.arg		= "combined",
99*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_CHANNELS_COMBINED_COUNT,
100*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
101*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
102*1b481fc3SMaciej Żenczykowski 	},
103*1b481fc3SMaciej Żenczykowski 	{}
104*1b481fc3SMaciej Żenczykowski };
105*1b481fc3SMaciej Żenczykowski 
nl_schannels(struct cmd_context * ctx)106*1b481fc3SMaciej Żenczykowski int nl_schannels(struct cmd_context *ctx)
107*1b481fc3SMaciej Żenczykowski {
108*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = ctx->nlctx;
109*1b481fc3SMaciej Żenczykowski 	struct nl_msg_buff *msgbuff;
110*1b481fc3SMaciej Żenczykowski 	struct nl_socket *nlsk;
111*1b481fc3SMaciej Żenczykowski 	int ret;
112*1b481fc3SMaciej Żenczykowski 
113*1b481fc3SMaciej Żenczykowski 	if (netlink_cmd_check(ctx, ETHTOOL_MSG_CHANNELS_SET, false))
114*1b481fc3SMaciej Żenczykowski 		return -EOPNOTSUPP;
115*1b481fc3SMaciej Żenczykowski 
116*1b481fc3SMaciej Żenczykowski 	nlctx->cmd = "-L";
117*1b481fc3SMaciej Żenczykowski 	nlctx->argp = ctx->argp;
118*1b481fc3SMaciej Żenczykowski 	nlctx->argc = ctx->argc;
119*1b481fc3SMaciej Żenczykowski 	nlctx->devname = ctx->devname;
120*1b481fc3SMaciej Żenczykowski 	nlsk = nlctx->ethnl_socket;
121*1b481fc3SMaciej Żenczykowski 	msgbuff = &nlsk->msgbuff;
122*1b481fc3SMaciej Żenczykowski 
123*1b481fc3SMaciej Żenczykowski 	ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_CHANNELS_SET,
124*1b481fc3SMaciej Żenczykowski 		       NLM_F_REQUEST | NLM_F_ACK);
125*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
126*1b481fc3SMaciej Żenczykowski 		return 2;
127*1b481fc3SMaciej Żenczykowski 	if (ethnla_fill_header(msgbuff, ETHTOOL_A_CHANNELS_HEADER,
128*1b481fc3SMaciej Żenczykowski 			       ctx->devname, 0))
129*1b481fc3SMaciej Żenczykowski 		return -EMSGSIZE;
130*1b481fc3SMaciej Żenczykowski 
131*1b481fc3SMaciej Żenczykowski 	ret = nl_parser(nlctx, schannels_params, NULL, PARSER_GROUP_NONE, NULL);
132*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
133*1b481fc3SMaciej Żenczykowski 		return 1;
134*1b481fc3SMaciej Żenczykowski 
135*1b481fc3SMaciej Żenczykowski 	ret = nlsock_sendmsg(nlsk, NULL);
136*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
137*1b481fc3SMaciej Żenczykowski 		return 1;
138*1b481fc3SMaciej Żenczykowski 	ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx);
139*1b481fc3SMaciej Żenczykowski 	if (ret == 0)
140*1b481fc3SMaciej Żenczykowski 		return 0;
141*1b481fc3SMaciej Żenczykowski 	else
142*1b481fc3SMaciej Żenczykowski 		return nlctx->exit_code ?: 1;
143*1b481fc3SMaciej Żenczykowski }
144