xref: /aosp_15_r20/external/ethtool/netlink/pse-pd.c (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1*1b481fc3SMaciej Żenczykowski /*
2*1b481fc3SMaciej Żenczykowski  * pse.c - netlink implementation of pse commands
3*1b481fc3SMaciej Żenczykowski  *
4*1b481fc3SMaciej Żenczykowski  * Implementation of "ethtool --show-pse <dev>" and
5*1b481fc3SMaciej Żenczykowski  * "ethtool --set-pse <dev> ..."
6*1b481fc3SMaciej Żenczykowski  */
7*1b481fc3SMaciej Żenczykowski 
8*1b481fc3SMaciej Żenczykowski #include <errno.h>
9*1b481fc3SMaciej Żenczykowski #include <ctype.h>
10*1b481fc3SMaciej Żenczykowski #include <inttypes.h>
11*1b481fc3SMaciej Żenczykowski #include <string.h>
12*1b481fc3SMaciej Żenczykowski #include <stdio.h>
13*1b481fc3SMaciej Żenczykowski 
14*1b481fc3SMaciej Żenczykowski #include "../internal.h"
15*1b481fc3SMaciej Żenczykowski #include "../common.h"
16*1b481fc3SMaciej Żenczykowski #include "netlink.h"
17*1b481fc3SMaciej Żenczykowski #include "parser.h"
18*1b481fc3SMaciej Żenczykowski 
19*1b481fc3SMaciej Żenczykowski /* PSE_GET */
20*1b481fc3SMaciej Żenczykowski 
podl_pse_admin_state_name(u32 val)21*1b481fc3SMaciej Żenczykowski static const char *podl_pse_admin_state_name(u32 val)
22*1b481fc3SMaciej Żenczykowski {
23*1b481fc3SMaciej Żenczykowski 	switch (val) {
24*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN:
25*1b481fc3SMaciej Żenczykowski 		return "unknown";
26*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED:
27*1b481fc3SMaciej Żenczykowski 		return "disabled";
28*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED:
29*1b481fc3SMaciej Żenczykowski 		return "enabled";
30*1b481fc3SMaciej Żenczykowski 	default:
31*1b481fc3SMaciej Żenczykowski 		return "unsupported";
32*1b481fc3SMaciej Żenczykowski 	}
33*1b481fc3SMaciej Żenczykowski }
34*1b481fc3SMaciej Żenczykowski 
podl_pse_pw_d_status_name(u32 val)35*1b481fc3SMaciej Żenczykowski static const char *podl_pse_pw_d_status_name(u32 val)
36*1b481fc3SMaciej Żenczykowski {
37*1b481fc3SMaciej Żenczykowski 	switch (val) {
38*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN:
39*1b481fc3SMaciej Żenczykowski 		return "unknown";
40*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED:
41*1b481fc3SMaciej Żenczykowski 		return "disabled";
42*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING:
43*1b481fc3SMaciej Żenczykowski 		return "searching";
44*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING:
45*1b481fc3SMaciej Żenczykowski 		return "delivering power";
46*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP:
47*1b481fc3SMaciej Żenczykowski 		return "sleep";
48*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE:
49*1b481fc3SMaciej Żenczykowski 		return "idle";
50*1b481fc3SMaciej Żenczykowski 	case ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR:
51*1b481fc3SMaciej Żenczykowski 		return "error";
52*1b481fc3SMaciej Żenczykowski 	default:
53*1b481fc3SMaciej Żenczykowski 		return "unsupported";
54*1b481fc3SMaciej Żenczykowski 	}
55*1b481fc3SMaciej Żenczykowski }
56*1b481fc3SMaciej Żenczykowski 
pse_reply_cb(const struct nlmsghdr * nlhdr,void * data)57*1b481fc3SMaciej Żenczykowski int pse_reply_cb(const struct nlmsghdr *nlhdr, void *data)
58*1b481fc3SMaciej Żenczykowski {
59*1b481fc3SMaciej Żenczykowski 	const struct nlattr *tb[ETHTOOL_A_PSE_MAX + 1] = {};
60*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = data;
61*1b481fc3SMaciej Żenczykowski 	DECLARE_ATTR_TB_INFO(tb);
62*1b481fc3SMaciej Żenczykowski 	bool silent;
63*1b481fc3SMaciej Żenczykowski 	int err_ret;
64*1b481fc3SMaciej Żenczykowski 	int ret;
65*1b481fc3SMaciej Żenczykowski 
66*1b481fc3SMaciej Żenczykowski 	silent = nlctx->is_dump || nlctx->is_monitor;
67*1b481fc3SMaciej Żenczykowski 	err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR;
68*1b481fc3SMaciej Żenczykowski 	ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
69*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
70*1b481fc3SMaciej Żenczykowski 		return err_ret;
71*1b481fc3SMaciej Żenczykowski 	nlctx->devname = get_dev_name(tb[ETHTOOL_A_PSE_HEADER]);
72*1b481fc3SMaciej Żenczykowski 	if (!dev_ok(nlctx))
73*1b481fc3SMaciej Żenczykowski 		return err_ret;
74*1b481fc3SMaciej Żenczykowski 
75*1b481fc3SMaciej Żenczykowski 	if (silent)
76*1b481fc3SMaciej Żenczykowski 		print_nl();
77*1b481fc3SMaciej Żenczykowski 
78*1b481fc3SMaciej Żenczykowski 	open_json_object(NULL);
79*1b481fc3SMaciej Żenczykowski 
80*1b481fc3SMaciej Żenczykowski 	print_string(PRINT_ANY, "ifname", "PSE attributes for %s:\n",
81*1b481fc3SMaciej Żenczykowski 		     nlctx->devname);
82*1b481fc3SMaciej Żenczykowski 
83*1b481fc3SMaciej Żenczykowski 	if (tb[ETHTOOL_A_PODL_PSE_ADMIN_STATE]) {
84*1b481fc3SMaciej Żenczykowski 		u32 val;
85*1b481fc3SMaciej Żenczykowski 
86*1b481fc3SMaciej Żenczykowski 		val = mnl_attr_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_STATE]);
87*1b481fc3SMaciej Żenczykowski 		print_string(PRINT_ANY, "podl-pse-admin-state",
88*1b481fc3SMaciej Żenczykowski 			     "PoDL PSE Admin State: %s\n",
89*1b481fc3SMaciej Żenczykowski 			     podl_pse_admin_state_name(val));
90*1b481fc3SMaciej Żenczykowski 	}
91*1b481fc3SMaciej Żenczykowski 
92*1b481fc3SMaciej Żenczykowski 	if (tb[ETHTOOL_A_PODL_PSE_PW_D_STATUS]) {
93*1b481fc3SMaciej Żenczykowski 		u32 val;
94*1b481fc3SMaciej Żenczykowski 
95*1b481fc3SMaciej Żenczykowski 		val = mnl_attr_get_u32(tb[ETHTOOL_A_PODL_PSE_PW_D_STATUS]);
96*1b481fc3SMaciej Żenczykowski 		print_string(PRINT_ANY, "podl-pse-power-detection-status",
97*1b481fc3SMaciej Żenczykowski 			     "PoDL PSE Power Detection Status: %s\n",
98*1b481fc3SMaciej Żenczykowski 			     podl_pse_pw_d_status_name(val));
99*1b481fc3SMaciej Żenczykowski 	}
100*1b481fc3SMaciej Żenczykowski 
101*1b481fc3SMaciej Żenczykowski 	close_json_object();
102*1b481fc3SMaciej Żenczykowski 
103*1b481fc3SMaciej Żenczykowski 	return MNL_CB_OK;
104*1b481fc3SMaciej Żenczykowski }
105*1b481fc3SMaciej Żenczykowski 
nl_gpse(struct cmd_context * ctx)106*1b481fc3SMaciej Żenczykowski int nl_gpse(struct cmd_context *ctx)
107*1b481fc3SMaciej Żenczykowski {
108*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = ctx->nlctx;
109*1b481fc3SMaciej Żenczykowski 	struct nl_socket *nlsk;
110*1b481fc3SMaciej Żenczykowski 	int ret;
111*1b481fc3SMaciej Żenczykowski 
112*1b481fc3SMaciej Żenczykowski 	if (netlink_cmd_check(ctx, ETHTOOL_MSG_PSE_GET, true))
113*1b481fc3SMaciej Żenczykowski 		return -EOPNOTSUPP;
114*1b481fc3SMaciej Żenczykowski 	if (ctx->argc > 0) {
115*1b481fc3SMaciej Żenczykowski 		fprintf(stderr, "ethtool: unexpected parameter '%s'\n",
116*1b481fc3SMaciej Żenczykowski 			*ctx->argp);
117*1b481fc3SMaciej Żenczykowski 		return 1;
118*1b481fc3SMaciej Żenczykowski 	}
119*1b481fc3SMaciej Żenczykowski 
120*1b481fc3SMaciej Żenczykowski 	nlsk = nlctx->ethnl_socket;
121*1b481fc3SMaciej Żenczykowski 	ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PSE_GET,
122*1b481fc3SMaciej Żenczykowski 				      ETHTOOL_A_PSE_HEADER, 0);
123*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
124*1b481fc3SMaciej Żenczykowski 		return ret;
125*1b481fc3SMaciej Żenczykowski 
126*1b481fc3SMaciej Żenczykowski 	new_json_obj(ctx->json);
127*1b481fc3SMaciej Żenczykowski 	ret = nlsock_send_get_request(nlsk, pse_reply_cb);
128*1b481fc3SMaciej Żenczykowski 	delete_json_obj();
129*1b481fc3SMaciej Żenczykowski 
130*1b481fc3SMaciej Żenczykowski 	return ret;
131*1b481fc3SMaciej Żenczykowski }
132*1b481fc3SMaciej Żenczykowski 
133*1b481fc3SMaciej Żenczykowski /* PSE_SET */
134*1b481fc3SMaciej Żenczykowski 
135*1b481fc3SMaciej Żenczykowski static const struct lookup_entry_u32 podl_pse_admin_control_values[] = {
136*1b481fc3SMaciej Żenczykowski 	{ .arg = "enable",	.val = ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED },
137*1b481fc3SMaciej Żenczykowski 	{ .arg = "disable",	.val = ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED },
138*1b481fc3SMaciej Żenczykowski 	{}
139*1b481fc3SMaciej Żenczykowski };
140*1b481fc3SMaciej Żenczykowski 
141*1b481fc3SMaciej Żenczykowski static const struct param_parser spse_params[] = {
142*1b481fc3SMaciej Żenczykowski 	{
143*1b481fc3SMaciej Żenczykowski 		.arg		= "podl-pse-admin-control",
144*1b481fc3SMaciej Żenczykowski 		.type		= ETHTOOL_A_PODL_PSE_ADMIN_CONTROL,
145*1b481fc3SMaciej Żenczykowski 		.handler	= nl_parse_lookup_u32,
146*1b481fc3SMaciej Żenczykowski 		.handler_data	= podl_pse_admin_control_values,
147*1b481fc3SMaciej Żenczykowski 		.min_argc	= 1,
148*1b481fc3SMaciej Żenczykowski 	},
149*1b481fc3SMaciej Żenczykowski 	{}
150*1b481fc3SMaciej Żenczykowski };
151*1b481fc3SMaciej Żenczykowski 
nl_spse(struct cmd_context * ctx)152*1b481fc3SMaciej Żenczykowski int nl_spse(struct cmd_context *ctx)
153*1b481fc3SMaciej Żenczykowski {
154*1b481fc3SMaciej Żenczykowski 	struct nl_context *nlctx = ctx->nlctx;
155*1b481fc3SMaciej Żenczykowski 	struct nl_msg_buff *msgbuff;
156*1b481fc3SMaciej Żenczykowski 	struct nl_socket *nlsk;
157*1b481fc3SMaciej Żenczykowski 	int ret;
158*1b481fc3SMaciej Żenczykowski 
159*1b481fc3SMaciej Żenczykowski 	if (netlink_cmd_check(ctx, ETHTOOL_MSG_PSE_SET, false))
160*1b481fc3SMaciej Żenczykowski 		return -EOPNOTSUPP;
161*1b481fc3SMaciej Żenczykowski 	if (!ctx->argc) {
162*1b481fc3SMaciej Żenczykowski 		fprintf(stderr, "ethtool (--set-pse): parameters missing\n");
163*1b481fc3SMaciej Żenczykowski 		return 1;
164*1b481fc3SMaciej Żenczykowski 	}
165*1b481fc3SMaciej Żenczykowski 
166*1b481fc3SMaciej Żenczykowski 	nlctx->cmd = "--set-pse";
167*1b481fc3SMaciej Żenczykowski 	nlctx->argp = ctx->argp;
168*1b481fc3SMaciej Żenczykowski 	nlctx->argc = ctx->argc;
169*1b481fc3SMaciej Żenczykowski 	nlctx->devname = ctx->devname;
170*1b481fc3SMaciej Żenczykowski 	nlsk = nlctx->ethnl_socket;
171*1b481fc3SMaciej Żenczykowski 	msgbuff = &nlsk->msgbuff;
172*1b481fc3SMaciej Żenczykowski 
173*1b481fc3SMaciej Żenczykowski 	ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_PSE_SET,
174*1b481fc3SMaciej Żenczykowski 		       NLM_F_REQUEST | NLM_F_ACK);
175*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
176*1b481fc3SMaciej Żenczykowski 		return 2;
177*1b481fc3SMaciej Żenczykowski 	if (ethnla_fill_header(msgbuff, ETHTOOL_A_PSE_HEADER,
178*1b481fc3SMaciej Żenczykowski 			       ctx->devname, 0))
179*1b481fc3SMaciej Żenczykowski 		return -EMSGSIZE;
180*1b481fc3SMaciej Żenczykowski 
181*1b481fc3SMaciej Żenczykowski 	ret = nl_parser(nlctx, spse_params, NULL, PARSER_GROUP_NONE, NULL);
182*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
183*1b481fc3SMaciej Żenczykowski 		return 1;
184*1b481fc3SMaciej Żenczykowski 
185*1b481fc3SMaciej Żenczykowski 	ret = nlsock_sendmsg(nlsk, NULL);
186*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
187*1b481fc3SMaciej Żenczykowski 		return 83;
188*1b481fc3SMaciej Żenczykowski 	ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx);
189*1b481fc3SMaciej Żenczykowski 	if (ret == 0)
190*1b481fc3SMaciej Żenczykowski 		return 0;
191*1b481fc3SMaciej Żenczykowski 	else
192*1b481fc3SMaciej Żenczykowski 		return nlctx->exit_code ?: 83;
193*1b481fc3SMaciej Żenczykowski }
194