2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright (c) 2017, Joyent, Inc.
17 * Private utility to get and set LED information on NICs. This should really
18 * all be integrated into FM. Until we have figured out that plumbing, this
19 * allows us to have a little something that we can use to drive work.
32 #include <libdllink.h>
35 #include <sys/dld_ioc.h>
37 static const char *dlled_progname
;
38 static dladm_handle_t dlled_hdl
;
39 static char dlled_dlerrmsg
[DLADM_STRSIZE
];
41 typedef struct dlled_led_map
{
43 mac_led_mode_t dlm_bits
;
46 static dlled_led_map_t dlled_map
[] = {
47 { "default", MAC_LED_DEFAULT
},
48 { "off", MAC_LED_OFF
},
50 { "ident", MAC_LED_IDENT
}
53 #define DLLED_MAP_NENTRIES \
54 (sizeof (dlled_map) / sizeof (dlled_led_map_t))
57 dlled_usage(const char *fmt
, ...)
62 (void) fprintf(stderr
, "%s: ", dlled_progname
);
64 (void) vfprintf(stderr
, fmt
, ap
);
68 (void) fprintf(stderr
, "Usage: %s [-s mode] [link]\n"
70 "\t-s mode set LED to mode\n",
75 dlled_parse_mode(const char *orig
)
83 fprintf(stderr
, "failed to allocate memory to dup led "
84 "mode: %s\n", strerror(errno
));
88 part
= strtok(mode
, ",");
89 while (part
!= NULL
) {
92 for (i
= 0; i
< DLLED_MAP_NENTRIES
; i
++) {
93 if (strcmp(dlled_map
[i
].dlm_name
, part
) == 0) {
94 m
|= dlled_map
[i
].dlm_bits
;
99 if (i
== DLLED_MAP_NENTRIES
) {
100 fprintf(stderr
, "unknown LED mode: %s\n", part
);
104 part
= strtok(NULL
, ",");
109 fprintf(stderr
, "failed to parse %s: no valid modes "
110 "specified\n", orig
);
118 dlled_mode2str(mac_led_mode_t mode
, char *buf
, size_t len
)
121 boolean_t first
= B_TRUE
;
122 mac_led_mode_t orig
= mode
;
124 for (i
= 0; i
< DLLED_MAP_NENTRIES
; i
++) {
125 if ((mode
& dlled_map
[i
].dlm_bits
) != 0) {
129 (void) strlcat(buf
, ",", len
);
131 (void) strlcat(buf
, dlled_map
[i
].dlm_name
, len
);
132 mode
&= ~dlled_map
[i
].dlm_bits
;
137 (void) snprintf(buf
, len
, "unknown mode: 0x%x\n", orig
);
143 dlled_set(const char *link
, mac_led_mode_t mode
)
145 datalink_id_t linkid
;
146 dladm_status_t status
;
149 if ((status
= dladm_name2info(dlled_hdl
, link
, &linkid
, NULL
, NULL
,
150 NULL
)) != DLADM_STATUS_OK
) {
151 (void) fprintf(stderr
, "failed to get link "
152 "id for link %s: %s\n", link
,
153 dladm_status2str(status
, dlled_dlerrmsg
));
157 bzero(&dil
, sizeof (dil
));
158 dil
.dil_linkid
= linkid
;
159 dil
.dil_active
= mode
;
161 if (ioctl(dladm_dld_fd(dlled_hdl
), DLDIOC_SETLED
, &dil
) != 0) {
162 (void) fprintf(stderr
, "failed to set LED on "
163 "device %s: %s\n", link
, strerror(errno
));
171 dlled_get_led(dladm_handle_t hdl
, datalink_id_t linkid
, void *arg
)
173 dladm_status_t status
;
174 char name
[MAXLINKNAMELEN
];
175 char supported
[128], active
[128];
178 if ((status
= dladm_datalink_id2info(hdl
, linkid
, NULL
, NULL
, NULL
,
179 name
, sizeof (name
))) != DLADM_STATUS_OK
) {
180 (void) fprintf(stderr
, "failed to get datalink name for link "
181 "%d: %s", linkid
, dladm_status2str(status
,
183 return (DLADM_WALK_CONTINUE
);
188 bzero(&dil
, sizeof (dil
));
189 dil
.dil_linkid
= linkid
;
191 if (ioctl(dladm_dld_fd(hdl
), DLDIOC_GETLED
, &dil
) != 0) {
192 (void) fprintf(stderr
, "failed to get LED information for "
193 "device %s: %s\n", name
, strerror(errno
));
194 return (DLADM_WALK_CONTINUE
);
199 dlled_mode2str(dil
.dil_active
, active
, sizeof (active
));
200 dlled_mode2str(dil
.dil_supported
, supported
, sizeof (supported
));
202 printf("%-20s %-12s %s\n", name
, active
, supported
);
204 return (DLADM_WALK_CONTINUE
);
208 main(int argc
, char *argv
[])
211 boolean_t opt_s
= B_FALSE
;
212 mac_led_mode_t set_mode
= 0;
213 dladm_status_t status
;
215 dlled_progname
= basename(argv
[0]);
217 while ((c
= getopt(argc
, argv
, ":s:")) != -1) {
221 set_mode
= dlled_parse_mode(optarg
);
224 dlled_usage("option -%c requires an operand\n", optopt
);
228 dlled_usage("unknown option: -%c\n", optopt
);
236 if (opt_s
&& argc
> 1) {
237 dlled_usage("-s only operates on a single datalink\n");
241 if (opt_s
&& argc
<= 0) {
242 dlled_usage("-s requires a datalink\n");
246 if ((status
= dladm_open(&dlled_hdl
)) != DLADM_STATUS_OK
) {
247 (void) fprintf(stderr
, "failed to open /dev/dld: %s\n",
248 dladm_status2str(status
, dlled_dlerrmsg
));
253 return (dlled_set(argv
[0], set_mode
));
256 (void) printf("%-20s %-12s %s\n", "LINK", "ACTIVE", "SUPPORTED");
260 (void) dladm_walk_datalink_id(dlled_get_led
, dlled_hdl
, NULL
,
261 DATALINK_CLASS_PHYS
, DATALINK_ANY_MEDIATYPE
,
265 datalink_id_t linkid
;
267 for (i
= 0; i
< argc
; i
++) {
268 if ((status
= dladm_name2info(dlled_hdl
, argv
[i
],
269 &linkid
, NULL
, NULL
, NULL
)) != DLADM_STATUS_OK
) {
270 (void) fprintf(stderr
, "failed to get link "
271 "id for link %s: %s\n", link
,
272 dladm_status2str(status
, dlled_dlerrmsg
));
276 dlret
= dlled_get_led(dlled_hdl
, linkid
, NULL
);
277 if (dlret
!= DLADM_WALK_CONTINUE
) {