4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * CDDL HEADER START
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan *
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * The contents of this file are subject to the terms of the
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Common Development and Distribution License (the "License").
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * You may not use this file except in compliance with the License.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan *
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * or http://www.opensolaris.org/os/licensing.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * See the License for the specific language governing permissions
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * and limitations under the License.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan *
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * When distributing Covered Code, include this CDDL HEADER in each
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * If applicable, add the following below this CDDL HEADER, with the
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * fields enclosed by brackets "[]" replaced with your own identifying
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * information: Portions Copyright [yyyy] [name of copyright owner]
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan *
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * CDDL HEADER END
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Use is subject to license terms.
3bc4925d580ab95c16f1ddd5eb387655cbd16e65Garrett D'Amore *
3bc4925d580ab95c16f1ddd5eb387655cbd16e65Garrett D'Amore * Copyright 2015 Garrett D'Amore <garrett@damore.org>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan#include <stdlib.h>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan#include <string.h>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan#include <strings.h>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan#include <sys/types.h>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan#include <libdladm_impl.h>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan#include <libdllink.h>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan#include <libdlstat.h>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan#include <libdlether.h>
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Ethernet administration library.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * kstat names for extracting attributes.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhantypedef struct ether_spdx_s {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan dladm_ether_spdx_t eth_spdx;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan char *eth_spdx_stat_name;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan} ether_spdx_t;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanstatic ether_spdx_t cap_spdx[] = {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "cap_1000fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "cap_1000hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{100, LINK_DUPLEX_FULL}, "cap_100fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{100, LINK_DUPLEX_HALF}, "cap_100hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{10, LINK_DUPLEX_FULL}, "cap_10fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{10, LINK_DUPLEX_HALF}, "cap_10hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan};
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanstatic ether_spdx_t adv_cap_spdx[] = {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "adv_cap_1000fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "adv_cap_1000hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{100, LINK_DUPLEX_FULL}, "adv_cap_100fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{100, LINK_DUPLEX_HALF}, "adv_cap_100hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{10, LINK_DUPLEX_FULL}, "adv_cap_10fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{10, LINK_DUPLEX_HALF}, "adv_cap_10hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan};
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanstatic ether_spdx_t lp_cap_spdx[] = {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "lp_cap_1000fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "lp_cap_1000hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{100, LINK_DUPLEX_FULL}, "lp_cap_100fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{100, LINK_DUPLEX_HALF}, "lp_cap_100hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{10, LINK_DUPLEX_FULL}, "lp_cap_10fdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{10, LINK_DUPLEX_HALF}, "lp_cap_10hdx"},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan};
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhantypedef struct attr_kstat_s {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan char *autoneg_stat;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan char *pause_stat;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan char *asmpause_stat;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan char *fault_stat;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan ether_spdx_t *spdx_stat;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan} attr_kstat_t;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanstatic attr_kstat_t attrstat[] = {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {"link_autoneg", /* current */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan "link_pause", "link_asmpause", NULL,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan NULL},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {"cap_autoneg", /* capable */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan "cap_pause", "cap_asmpause", "cap_rem_fault",
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan cap_spdx},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {"adv_cap_autoneg", /* advertised */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan "adv_cap_pause", "adv_cap_asmpause", "adv_rem_fault",
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan adv_cap_spdx},
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan {"lp_cap_autoneg", /* peer advertised */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan "lp_cap_pause", "lp_cap_asmpause", "lp_rem_fault",
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan lp_cap_spdx}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan};
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Get the speed-duplex stats specified in the ether_spdx_t table passed in
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * by querying the appropriate kstat for each entry in the table.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanstatic dladm_status_t
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeyi_dladm_get_spdx(dladm_handle_t handle, datalink_id_t linkid,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey dladm_ether_attr_t *eattr, ether_spdx_t *spdx_stat)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan{
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan int i, nspdx = 0;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan uint32_t speed;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan dladm_status_t status;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan void *ptr;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->le_spdx = NULL;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan for (i = 0; spdx_stat[i].eth_spdx_stat_name != NULL; i++) {
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan spdx_stat[i].eth_spdx_stat_name,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan KSTAT_DATA_UINT32, &speed)) != DLADM_STATUS_OK) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status == DLADM_STATUS_NOTFOUND) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan /*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Missing statistic.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Skip this one and try the rest.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan continue;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan } else {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan free(eattr->le_spdx);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->le_num_spdx = 0;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan return (status);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (speed == 0)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan continue;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan nspdx++;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan ptr = realloc(eattr->le_spdx,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan nspdx * sizeof (dladm_ether_spdx_t));
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (ptr != NULL) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->le_spdx = ptr;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan } else {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan free(eattr->le_spdx);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->le_num_spdx = 0;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan return (DLADM_STATUS_NOMEM);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->le_spdx[nspdx - 1] = spdx_stat[i].eth_spdx;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->le_num_spdx = nspdx;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan return (DLADM_STATUS_OK);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Returns "yes" or "no" based on the autonegotion capabilities
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * for the parameter type indicated by ptype. The permissible
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * values for ptype are CURRENT, CAPABLE, ADV, PEERADV.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanchar *
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhandladm_ether_autoneg2str(char *buf, size_t buflen, dladm_ether_info_t *eattr,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan int ptype)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan{
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan boolean_t autoneg = eattr->lei_attr[ptype].le_autoneg;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strlcpy(buf, (autoneg ? "yes" : "no"), buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan return (buf);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Returns {"bi", "tx", "none"} based on the flow-control capabilities
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * for the parameter type indicated by ptype. The permissible
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * values for ptype are CURRENT, CAPABLE, ADV, PEERADV.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanchar *
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhandladm_ether_pause2str(char *buf, size_t buflen, dladm_ether_info_t *eattr,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan int ptype)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan{
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan boolean_t pause = eattr->lei_attr[ptype].le_pause;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan boolean_t asmpause = eattr->lei_attr[ptype].le_asmpause;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (pause)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strlcpy(buf, "bi", buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan else if (asmpause)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strlcpy(buf, "tx", buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan else
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strlcpy(buf, "none", buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan return (buf);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * For a given param type, parse the list of speed-duplex pairs in
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * the dladm_ether_info_t and return a comma-separated string formatted
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * as <speed><speed-unit-char>-<duplex-chars> where <speed> is the value of
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * speed, in units specifid by the <speed-unit-char> which is one
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * of 'M' (Mbits/sec) or 'G' (Gigabits/sec). The permissible values of
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * <duplex-chars> are 'u' (indicating duplex is "unknown") or one/both of
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * 'f', 'h' (indicating full-duplex and half-duplex respectively)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanextern char *
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhandladm_ether_spdx2str(char *buf, size_t buflen, dladm_ether_info_t *eattr,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan int ptype)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan{
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan int i, j;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan boolean_t is_full, is_half;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan int speed;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan char speed_unit;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan char tmpbuf[DLADM_STRSIZE];
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan dladm_ether_spdx_t *spdx;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan uint32_t nspdx;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan spdx = eattr->lei_attr[ptype].le_spdx;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan nspdx = eattr->lei_attr[ptype].le_num_spdx;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan for (i = 0; i < nspdx; i++) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan speed = spdx[i].lesd_speed;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan /*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * if we have already covered this speed for
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * the <other>-duplex case before this, skip it
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan for (j = 0; j < i; j++) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (speed == spdx[j].lesd_speed)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan break;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (j < i)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan continue;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
3bc4925d580ab95c16f1ddd5eb387655cbd16e65Garrett D'Amore if ((speed % 1000) == 0) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan speed = speed/1000;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan speed_unit = 'G';
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan } else {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan speed_unit = 'M';
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) snprintf(tmpbuf, DLADM_STRSIZE, "%d%c",
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan speed, speed_unit);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (i > 0)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strncat(buf, ",", buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strncat(buf, tmpbuf, buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan is_full = is_half = B_FALSE;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan /*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Find all the supported duplex values for this speed.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan for (j = 0; j < nspdx; j++) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (spdx[j].lesd_speed != spdx[i].lesd_speed)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan continue;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (spdx[j].lesd_duplex == LINK_DUPLEX_FULL)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan is_full = B_TRUE;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (spdx[j].lesd_duplex == LINK_DUPLEX_HALF)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan is_half = B_TRUE;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (is_full && is_half)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strncat(buf, "-fh", buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan else if (is_full)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strncat(buf, "-f", buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan else if (is_half)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan (void) strncat(buf, "-h", buflen);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan return (buf);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan/*
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Extract Ethernet attributes of the link specified by linkid.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * Information for the CURRENT, CAPABLE, ADV and PEERADV parameter
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * types is extracted into the lei_attr[] entries in the dladm_ether_info_t.
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * On succesful return, the memory allocated in this function should be
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan * freed by calling dladm_ether_info_done().
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanextern dladm_status_t
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeydladm_ether_info(dladm_handle_t handle, datalink_id_t linkid,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey dladm_ether_info_t *eattr)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan{
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan uint32_t autoneg, pause, asmpause, fault;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan uint64_t sp64;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan dladm_status_t status;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan int i;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan link_duplex_t link_duplex;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan bzero(eattr, sizeof (*eattr));
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_linkname, sizeof (eattr->lei_linkname));
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan /* get current values of speed, duplex, state of link */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[CURRENT].le_num_spdx = 1;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[CURRENT].le_spdx = malloc(sizeof (dladm_ether_spdx_t));
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (eattr->lei_attr[CURRENT].le_spdx == NULL) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan status = DLADM_STATUS_NOMEM;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed",
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan KSTAT_DATA_UINT64, &sp64)) != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex",
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan KSTAT_DATA_UINT32, &link_duplex)) != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[CURRENT].le_spdx->lesd_speed = (int)(sp64/1000000ull);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[CURRENT].le_spdx->lesd_duplex = link_duplex;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer status = dladm_get_state(handle, linkid, &eattr->lei_state);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan /* get the auto, pause, asmpause, fault values */
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan for (i = CURRENT; i <= PEERADV; i++) {
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan attrstat[i].autoneg_stat, KSTAT_DATA_UINT32, &autoneg);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan attrstat[i].pause_stat, KSTAT_DATA_UINT32, &pause);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan attrstat[i].asmpause_stat, KSTAT_DATA_UINT32, &asmpause);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[i].le_autoneg = (autoneg != 0);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[i].le_pause = (pause != 0);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[i].le_asmpause = (asmpause != 0);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (i == CURRENT)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan continue;
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid,
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan attrstat[i].fault_stat, KSTAT_DATA_UINT32, &fault);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[i].le_fault = (pause != 0);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan /* get all the supported speed/duplex values */
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = i_dladm_get_spdx(handle, linkid, &eattr->lei_attr[i],
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan attrstat[i].spdx_stat);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan goto bail;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan }
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[CURRENT].le_fault =
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan eattr->lei_attr[ADV].le_fault || eattr->lei_attr[PEERADV].le_fault;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanbail:
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan if (status != DLADM_STATUS_OK)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan dladm_ether_info_done(eattr);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan return (status);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan}
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhanextern void
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhandladm_ether_info_done(dladm_ether_info_t *eattr)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan{
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan int i;
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan for (i = CURRENT; i <= PEERADV; i++)
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan free(eattr->lei_attr[i].le_spdx);
4784fcbddec533c366d5e92ce1ca3a4a2ce69495Sowmini Varadhan}