xref: /aosp_15_r20/external/ethtool/netlink/rings.c (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1*1b481fc3SMaciej Żenczykowski /*
2*1b481fc3SMaciej Żenczykowski  * rings.c - netlink implementation of ring commands
3*1b481fc3SMaciej Żenczykowski  *
4*1b481fc3SMaciej Żenczykowski  * Implementation of "ethtool -g <dev>" and "ethtool -G <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 /* RINGS_GET */
17*1b481fc3SMaciej Żenczykowski 
rings_reply_cb(const struct nlmsghdr * nlhdr,void * data)18*1b481fc3SMaciej Żenczykowski int rings_reply_cb(const struct nlmsghdr *nlhdr, void *data)
19*1b481fc3SMaciej Żenczykowski {
20*1b481fc3SMaciej Żenczykowski 	const struct nlattr *tb[ETHTOOL_A_RINGS_MAX + 1] = {};
21*1b481fc3SMaciej Żenczykowski 	DECLARE_ATTR_TB_INFO(tb);
22*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = data;
23*1b481fc3SMaciej Żenczykowski 	unsigned char tcp_hds;
24*1b481fc3SMaciej Żenczykowski 	char *tcp_hds_fmt;
25*1b481fc3SMaciej Żenczykowski 	char *tcp_hds_key;
26*1b481fc3SMaciej Żenczykowski 	char tcp_hds_buf[256];
27*1b481fc3SMaciej Żenczykowski 	bool silent;
28*1b481fc3SMaciej Żenczykowski 	int err_ret;
29*1b481fc3SMaciej Żenczykowski 	int ret;
30*1b481fc3SMaciej Żenczykowski 
31*1b481fc3SMaciej Żenczykowski 	silent = nlctx->is_dump || nlctx->is_monitor;
32*1b481fc3SMaciej Żenczykowski 	err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR;
33*1b481fc3SMaciej Żenczykowski 	ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
34*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
35*1b481fc3SMaciej Żenczykowski 		return err_ret;
36*1b481fc3SMaciej Żenczykowski 	nlctx->devname = get_dev_name(tb[ETHTOOL_A_RINGS_HEADER]);
37*1b481fc3SMaciej Żenczykowski 	if (!dev_ok(nlctx))
38*1b481fc3SMaciej Żenczykowski 		return err_ret;
39*1b481fc3SMaciej Żenczykowski 
40*1b481fc3SMaciej Żenczykowski 	open_json_object(NULL);
41*1b481fc3SMaciej Żenczykowski 
42*1b481fc3SMaciej Żenczykowski 	if (silent)
43*1b481fc3SMaciej Żenczykowski 		show_cr();
44*1b481fc3SMaciej Żenczykowski 	print_string(PRINT_ANY, "ifname", "Ring parameters for %s:\n",
45*1b481fc3SMaciej Żenczykowski 		     nlctx->devname);
46*1b481fc3SMaciej Żenczykowski 	print_string(PRINT_FP, NULL, "Pre-set maximums:\n", NULL);
47*1b481fc3SMaciej Żenczykowski 	show_u32("rx-max", "RX:\t\t\t", tb[ETHTOOL_A_RINGS_RX_MAX]);
48*1b481fc3SMaciej Żenczykowski 	show_u32("rx-mini-max", "RX Mini:\t\t", tb[ETHTOOL_A_RINGS_RX_MINI_MAX]);
49*1b481fc3SMaciej Żenczykowski 	show_u32("rx-jumbo-max", "RX Jumbo:\t\t",
50*1b481fc3SMaciej Żenczykowski 		 tb[ETHTOOL_A_RINGS_RX_JUMBO_MAX]);
51*1b481fc3SMaciej Żenczykowski 	show_u32("tx-max", "TX:\t\t\t", tb[ETHTOOL_A_RINGS_TX_MAX]);
52*1b481fc3SMaciej Żenczykowski 	show_u32("tx-push-buff-max-len", "TX push buff len:\t",
53*1b481fc3SMaciej Żenczykowski 		 tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX]);
54*1b481fc3SMaciej Żenczykowski 	print_string(PRINT_FP, NULL, "Current hardware settings:\n", NULL);
55*1b481fc3SMaciej Żenczykowski 	show_u32("rx", "RX:\t\t\t", tb[ETHTOOL_A_RINGS_RX]);
56*1b481fc3SMaciej Żenczykowski 	show_u32("rx-mini", "RX Mini:\t\t", tb[ETHTOOL_A_RINGS_RX_MINI]);
57*1b481fc3SMaciej Żenczykowski 	show_u32("rx-jumbo", "RX Jumbo:\t\t", tb[ETHTOOL_A_RINGS_RX_JUMBO]);
58*1b481fc3SMaciej Żenczykowski 	show_u32("tx", "TX:\t\t\t", tb[ETHTOOL_A_RINGS_TX]);
59*1b481fc3SMaciej Żenczykowski 	show_u32("rx-buf-len", "RX Buf Len:\t\t", tb[ETHTOOL_A_RINGS_RX_BUF_LEN]);
60*1b481fc3SMaciej Żenczykowski 	show_u32("cqe-size", "CQE Size:\t\t", tb[ETHTOOL_A_RINGS_CQE_SIZE]);
61*1b481fc3SMaciej Żenczykowski 	show_bool("tx-push", "TX Push:\t\t%s\n", tb[ETHTOOL_A_RINGS_TX_PUSH]);
62*1b481fc3SMaciej Żenczykowski 	show_bool("rx-push", "RX Push:\t\t%s\n", tb[ETHTOOL_A_RINGS_RX_PUSH]);
63*1b481fc3SMaciej Żenczykowski 	show_u32("tx-push-buf-len", "TX push buff len:\t",
64*1b481fc3SMaciej Żenczykowski 		 tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN]);
65*1b481fc3SMaciej Żenczykowski 
66*1b481fc3SMaciej Żenczykowski 	tcp_hds_fmt = "TCP data split:\t\t%s\n";
67*1b481fc3SMaciej Żenczykowski 	tcp_hds_key = "tcp-data-split";
68*1b481fc3SMaciej Żenczykowski 	tcp_hds = tb[ETHTOOL_A_RINGS_TCP_DATA_SPLIT] ?
69*1b481fc3SMaciej Żenczykowski 		mnl_attr_get_u8(tb[ETHTOOL_A_RINGS_TCP_DATA_SPLIT]) : 0;
70*1b481fc3SMaciej Żenczykowski 	switch (tcp_hds) {
71*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_TCP_DATA_SPLIT_UNKNOWN:
72*1b481fc3SMaciej Żenczykowski 		print_string(PRINT_FP, tcp_hds_key, tcp_hds_fmt, "n/a");
73*1b481fc3SMaciej Żenczykowski 		break;
74*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_TCP_DATA_SPLIT_DISABLED:
75*1b481fc3SMaciej Żenczykowski 		print_string(PRINT_ANY, tcp_hds_key, tcp_hds_fmt, "off");
76*1b481fc3SMaciej Żenczykowski 		break;
77*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_TCP_DATA_SPLIT_ENABLED:
78*1b481fc3SMaciej Żenczykowski 		print_string(PRINT_ANY, tcp_hds_key, tcp_hds_fmt, "on");
79*1b481fc3SMaciej Żenczykowski 		break;
80*1b481fc3SMaciej Żenczykowski 	default:
81*1b481fc3SMaciej Żenczykowski 		snprintf(tcp_hds_buf, sizeof(tcp_hds_buf),
82*1b481fc3SMaciej Żenczykowski 			 "unknown(%d)\n", tcp_hds);
83*1b481fc3SMaciej Żenczykowski 		print_string(PRINT_ANY, tcp_hds_key, tcp_hds_fmt, tcp_hds_buf);
84*1b481fc3SMaciej Żenczykowski 		break;
85*1b481fc3SMaciej Żenczykowski 	}
86*1b481fc3SMaciej Żenczykowski 
87*1b481fc3SMaciej Żenczykowski 	close_json_object();
88*1b481fc3SMaciej Żenczykowski 
89*1b481fc3SMaciej Żenczykowski 	return MNL_CB_OK;
90*1b481fc3SMaciej Żenczykowski }
91*1b481fc3SMaciej Żenczykowski 
nl_gring(struct cmd_context * ctx)92*1b481fc3SMaciej Żenczykowski int nl_gring(struct cmd_context *ctx)
93*1b481fc3SMaciej Żenczykowski {
94*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = ctx->nlctx;
95*1b481fc3SMaciej Żenczykowski 	struct nl_socket *nlsk = nlctx->ethnl_socket;
96*1b481fc3SMaciej Żenczykowski 	int ret;
97*1b481fc3SMaciej Żenczykowski 
98*1b481fc3SMaciej Żenczykowski 	if (netlink_cmd_check(ctx, ETHTOOL_MSG_RINGS_GET, true))
99*1b481fc3SMaciej Żenczykowski 		return -EOPNOTSUPP;
100*1b481fc3SMaciej Żenczykowski 	if (ctx->argc > 0) {
101*1b481fc3SMaciej Żenczykowski 		fprintf(stderr, "ethtool: unexpected parameter '%s'\n",
102*1b481fc3SMaciej Żenczykowski 			*ctx->argp);
103*1b481fc3SMaciej Żenczykowski 		return 1;
104*1b481fc3SMaciej Żenczykowski 	}
105*1b481fc3SMaciej Żenczykowski 
106*1b481fc3SMaciej Żenczykowski 	ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_RINGS_GET,
107*1b481fc3SMaciej Żenczykowski 				      ETHTOOL_A_RINGS_HEADER, 0);
108*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
109*1b481fc3SMaciej Żenczykowski 		return ret;
110*1b481fc3SMaciej Żenczykowski 
111*1b481fc3SMaciej Żenczykowski 	new_json_obj(ctx->json);
112*1b481fc3SMaciej Żenczykowski 	ret = nlsock_send_get_request(nlsk, rings_reply_cb);
113*1b481fc3SMaciej Żenczykowski 	delete_json_obj();
114*1b481fc3SMaciej Żenczykowski 	return ret;
115*1b481fc3SMaciej Żenczykowski }
116*1b481fc3SMaciej Żenczykowski 
117*1b481fc3SMaciej Żenczykowski /* RINGS_SET */
118*1b481fc3SMaciej Żenczykowski 
119*1b481fc3SMaciej Żenczykowski static const struct param_parser sring_params[] = {
120*1b481fc3SMaciej Żenczykowski 	{
121*1b481fc3SMaciej Żenczykowski 		.arg		= "rx",
122*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_RINGS_RX,
123*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
124*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
125*1b481fc3SMaciej Żenczykowski 	},
126*1b481fc3SMaciej Żenczykowski 	{
127*1b481fc3SMaciej Żenczykowski 		.arg		= "rx-mini",
128*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_RINGS_RX_MINI,
129*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
130*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
131*1b481fc3SMaciej Żenczykowski 	},
132*1b481fc3SMaciej Żenczykowski 	{
133*1b481fc3SMaciej Żenczykowski 		.arg		= "rx-jumbo",
134*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_RINGS_RX_JUMBO,
135*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
136*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
137*1b481fc3SMaciej Żenczykowski 	},
138*1b481fc3SMaciej Żenczykowski 	{
139*1b481fc3SMaciej Żenczykowski 		.arg		= "tx",
140*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_RINGS_TX,
141*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
142*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
143*1b481fc3SMaciej Żenczykowski 	},
144*1b481fc3SMaciej Żenczykowski 	{
145*1b481fc3SMaciej Żenczykowski 		.arg		= "tx-push-buf-len",
146*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
147*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_direct_u32,
148*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
149*1b481fc3SMaciej Żenczykowski 	},
150*1b481fc3SMaciej Żenczykowski 	{
151*1b481fc3SMaciej Żenczykowski 		.arg            = "rx-buf-len",
152*1b481fc3SMaciej Żenczykowski 		.type           = ETHTOOL_A_RINGS_RX_BUF_LEN,
153*1b481fc3SMaciej Żenczykowski 		.handler        = nl_parse_direct_u32,
154*1b481fc3SMaciej Żenczykowski 		.min_argc       = 1,
155*1b481fc3SMaciej Żenczykowski 	},
156*1b481fc3SMaciej Żenczykowski 	{
157*1b481fc3SMaciej Żenczykowski 		.arg            = "cqe-size",
158*1b481fc3SMaciej Żenczykowski 		.type           = ETHTOOL_A_RINGS_CQE_SIZE,
159*1b481fc3SMaciej Żenczykowski 		.handler        = nl_parse_direct_u32,
160*1b481fc3SMaciej Żenczykowski 		.min_argc       = 1,
161*1b481fc3SMaciej Żenczykowski 	},
162*1b481fc3SMaciej Żenczykowski 	{
163*1b481fc3SMaciej Żenczykowski 		.arg            = "tx-push",
164*1b481fc3SMaciej Żenczykowski 		.type           = ETHTOOL_A_RINGS_TX_PUSH,
165*1b481fc3SMaciej Żenczykowski 		.handler        = nl_parse_u8bool,
166*1b481fc3SMaciej Żenczykowski 		.min_argc       = 1,
167*1b481fc3SMaciej Żenczykowski 	},
168*1b481fc3SMaciej Żenczykowski 	{
169*1b481fc3SMaciej Żenczykowski 		.arg            = "rx-push",
170*1b481fc3SMaciej Żenczykowski 		.type           = ETHTOOL_A_RINGS_RX_PUSH,
171*1b481fc3SMaciej Żenczykowski 		.handler        = nl_parse_u8bool,
172*1b481fc3SMaciej Żenczykowski 		.min_argc       = 1,
173*1b481fc3SMaciej Żenczykowski 	},
174*1b481fc3SMaciej Żenczykowski 	{}
175*1b481fc3SMaciej Żenczykowski };
176*1b481fc3SMaciej Żenczykowski 
nl_sring(struct cmd_context * ctx)177*1b481fc3SMaciej Żenczykowski int nl_sring(struct cmd_context *ctx)
178*1b481fc3SMaciej Żenczykowski {
179*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = ctx->nlctx;
180*1b481fc3SMaciej Żenczykowski 	struct nl_msg_buff *msgbuff;
181*1b481fc3SMaciej Żenczykowski 	struct nl_socket *nlsk;
182*1b481fc3SMaciej Żenczykowski 	int ret;
183*1b481fc3SMaciej Żenczykowski 
184*1b481fc3SMaciej Żenczykowski 	if (netlink_cmd_check(ctx, ETHTOOL_MSG_RINGS_SET, false))
185*1b481fc3SMaciej Żenczykowski 		return -EOPNOTSUPP;
186*1b481fc3SMaciej Żenczykowski 
187*1b481fc3SMaciej Żenczykowski 	nlctx->cmd = "-G";
188*1b481fc3SMaciej Żenczykowski 	nlctx->argp = ctx->argp;
189*1b481fc3SMaciej Żenczykowski 	nlctx->argc = ctx->argc;
190*1b481fc3SMaciej Żenczykowski 	nlctx->devname = ctx->devname;
191*1b481fc3SMaciej Żenczykowski 	nlsk = nlctx->ethnl_socket;
192*1b481fc3SMaciej Żenczykowski 	msgbuff = &nlsk->msgbuff;
193*1b481fc3SMaciej Żenczykowski 
194*1b481fc3SMaciej Żenczykowski 	ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_RINGS_SET,
195*1b481fc3SMaciej Żenczykowski 		       NLM_F_REQUEST | NLM_F_ACK);
196*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
197*1b481fc3SMaciej Żenczykowski 		return 2;
198*1b481fc3SMaciej Żenczykowski 	if (ethnla_fill_header(msgbuff, ETHTOOL_A_RINGS_HEADER,
199*1b481fc3SMaciej Żenczykowski 			       ctx->devname, 0))
200*1b481fc3SMaciej Żenczykowski 		return -EMSGSIZE;
201*1b481fc3SMaciej Żenczykowski 
202*1b481fc3SMaciej Żenczykowski 	ret = nl_parser(nlctx, sring_params, NULL, PARSER_GROUP_NONE, NULL);
203*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
204*1b481fc3SMaciej Żenczykowski 		return 1;
205*1b481fc3SMaciej Żenczykowski 
206*1b481fc3SMaciej Żenczykowski 	ret = nlsock_sendmsg(nlsk, NULL);
207*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
208*1b481fc3SMaciej Żenczykowski 		return 81;
209*1b481fc3SMaciej Żenczykowski 	ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx);
210*1b481fc3SMaciej Żenczykowski 	if (ret == 0)
211*1b481fc3SMaciej Żenczykowski 		return 0;
212*1b481fc3SMaciej Żenczykowski 	else
213*1b481fc3SMaciej Żenczykowski 		return nlctx->exit_code ?: 81;
214*1b481fc3SMaciej Żenczykowski }
215