14784fcbdSSowmini Varadhan /*
24784fcbdSSowmini Varadhan * CDDL HEADER START
34784fcbdSSowmini Varadhan *
44784fcbdSSowmini Varadhan * The contents of this file are subject to the terms of the
54784fcbdSSowmini Varadhan * Common Development and Distribution License (the "License").
64784fcbdSSowmini Varadhan * You may not use this file except in compliance with the License.
74784fcbdSSowmini Varadhan *
84784fcbdSSowmini Varadhan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94784fcbdSSowmini Varadhan * or http://www.opensolaris.org/os/licensing.
104784fcbdSSowmini Varadhan * See the License for the specific language governing permissions
114784fcbdSSowmini Varadhan * and limitations under the License.
124784fcbdSSowmini Varadhan *
134784fcbdSSowmini Varadhan * When distributing Covered Code, include this CDDL HEADER in each
144784fcbdSSowmini Varadhan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154784fcbdSSowmini Varadhan * If applicable, add the following below this CDDL HEADER, with the
164784fcbdSSowmini Varadhan * fields enclosed by brackets "[]" replaced with your own identifying
174784fcbdSSowmini Varadhan * information: Portions Copyright [yyyy] [name of copyright owner]
184784fcbdSSowmini Varadhan *
194784fcbdSSowmini Varadhan * CDDL HEADER END
204784fcbdSSowmini Varadhan */
214784fcbdSSowmini Varadhan /*
220dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
234784fcbdSSowmini Varadhan * Use is subject to license terms.
243bc4925dSGarrett D'Amore *
253bc4925dSGarrett D'Amore * Copyright 2015 Garrett D'Amore <garrett@damore.org>
264784fcbdSSowmini Varadhan */
274784fcbdSSowmini Varadhan
284784fcbdSSowmini Varadhan #include <stdlib.h>
294784fcbdSSowmini Varadhan #include <string.h>
304784fcbdSSowmini Varadhan #include <strings.h>
314784fcbdSSowmini Varadhan #include <sys/types.h>
324784fcbdSSowmini Varadhan #include <libdladm_impl.h>
334784fcbdSSowmini Varadhan #include <libdllink.h>
344784fcbdSSowmini Varadhan #include <libdlstat.h>
354784fcbdSSowmini Varadhan #include <libdlether.h>
364784fcbdSSowmini Varadhan
374784fcbdSSowmini Varadhan /*
384784fcbdSSowmini Varadhan * Ethernet administration library.
394784fcbdSSowmini Varadhan */
404784fcbdSSowmini Varadhan
414784fcbdSSowmini Varadhan /*
424784fcbdSSowmini Varadhan * kstat names for extracting attributes.
434784fcbdSSowmini Varadhan */
444784fcbdSSowmini Varadhan typedef struct ether_spdx_s {
454784fcbdSSowmini Varadhan dladm_ether_spdx_t eth_spdx;
464784fcbdSSowmini Varadhan char *eth_spdx_stat_name;
474784fcbdSSowmini Varadhan } ether_spdx_t;
484784fcbdSSowmini Varadhan
494784fcbdSSowmini Varadhan static ether_spdx_t cap_spdx[] = {
50*2aaafd60SRobert Mustacchi {{400000, LINK_DUPLEX_FULL}, "cap_400gfdx"},
51*2aaafd60SRobert Mustacchi {{200000, LINK_DUPLEX_FULL}, "cap_200gfdx"},
523d75a287SRobert Mustacchi {{100000, LINK_DUPLEX_FULL}, "cap_100gfdx"},
533d75a287SRobert Mustacchi {{50000, LINK_DUPLEX_FULL}, "cap_50gfdx"},
543d75a287SRobert Mustacchi {{40000, LINK_DUPLEX_FULL}, "cap_40gfdx"},
553d75a287SRobert Mustacchi {{25000, LINK_DUPLEX_FULL}, "cap_25gfdx"},
563d75a287SRobert Mustacchi {{10000, LINK_DUPLEX_FULL}, "cap_10gfdx"},
573d75a287SRobert Mustacchi {{5000, LINK_DUPLEX_FULL}, "cap_5000fdx"},
583d75a287SRobert Mustacchi {{2500, LINK_DUPLEX_FULL}, "cap_2500fdx"},
594784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "cap_1000fdx"},
604784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "cap_1000hdx"},
614784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_FULL}, "cap_100fdx"},
624784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_HALF}, "cap_100hdx"},
634784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_FULL}, "cap_10fdx"},
644784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_HALF}, "cap_10hdx"},
654784fcbdSSowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL}
664784fcbdSSowmini Varadhan };
674784fcbdSSowmini Varadhan
684784fcbdSSowmini Varadhan static ether_spdx_t adv_cap_spdx[] = {
69*2aaafd60SRobert Mustacchi {{400000, LINK_DUPLEX_FULL}, "adv_cap_400gfdx"},
70*2aaafd60SRobert Mustacchi {{200000, LINK_DUPLEX_FULL}, "adv_cap_200gfdx"},
713d75a287SRobert Mustacchi {{100000, LINK_DUPLEX_FULL}, "adv_cap_100gfdx"},
723d75a287SRobert Mustacchi {{50000, LINK_DUPLEX_FULL}, "adv_cap_50gfdx"},
733d75a287SRobert Mustacchi {{40000, LINK_DUPLEX_FULL}, "adv_cap_40gfdx"},
743d75a287SRobert Mustacchi {{25000, LINK_DUPLEX_FULL}, "adv_cap_25gfdx"},
753d75a287SRobert Mustacchi {{10000, LINK_DUPLEX_FULL}, "adv_cap_10gfdx"},
763d75a287SRobert Mustacchi {{5000, LINK_DUPLEX_FULL}, "adv_cap_5000fdx"},
773d75a287SRobert Mustacchi {{2500, LINK_DUPLEX_FULL}, "adv_cap_2500fdx"},
784784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "adv_cap_1000fdx"},
794784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "adv_cap_1000hdx"},
804784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_FULL}, "adv_cap_100fdx"},
814784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_HALF}, "adv_cap_100hdx"},
824784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_FULL}, "adv_cap_10fdx"},
834784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_HALF}, "adv_cap_10hdx"},
844784fcbdSSowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL}
854784fcbdSSowmini Varadhan };
864784fcbdSSowmini Varadhan
874784fcbdSSowmini Varadhan static ether_spdx_t lp_cap_spdx[] = {
88*2aaafd60SRobert Mustacchi {{400000, LINK_DUPLEX_FULL}, "lp_cap_400gfdx"},
89*2aaafd60SRobert Mustacchi {{200000, LINK_DUPLEX_FULL}, "lp_cap_200gfdx"},
903d75a287SRobert Mustacchi {{100000, LINK_DUPLEX_FULL}, "lp_cap_100gfdx"},
913d75a287SRobert Mustacchi {{50000, LINK_DUPLEX_FULL}, "lp_cap_50gfdx"},
923d75a287SRobert Mustacchi {{40000, LINK_DUPLEX_FULL}, "lp_cap_40gfdx"},
933d75a287SRobert Mustacchi {{25000, LINK_DUPLEX_FULL}, "lp_cap_25gfdx"},
943d75a287SRobert Mustacchi {{10000, LINK_DUPLEX_FULL}, "lp_cap_10gfdx"},
953d75a287SRobert Mustacchi {{5000, LINK_DUPLEX_FULL}, "lp_cap_5000fdx"},
963d75a287SRobert Mustacchi {{2500, LINK_DUPLEX_FULL}, "lp_cap_2500fdx"},
974784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "lp_cap_1000fdx"},
984784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "lp_cap_1000hdx"},
994784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_FULL}, "lp_cap_100fdx"},
1004784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_HALF}, "lp_cap_100hdx"},
1014784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_FULL}, "lp_cap_10fdx"},
1024784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_HALF}, "lp_cap_10hdx"},
1034784fcbdSSowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL}
1044784fcbdSSowmini Varadhan };
1054784fcbdSSowmini Varadhan
1064784fcbdSSowmini Varadhan typedef struct attr_kstat_s {
1074784fcbdSSowmini Varadhan char *autoneg_stat;
1084784fcbdSSowmini Varadhan char *pause_stat;
1094784fcbdSSowmini Varadhan char *asmpause_stat;
1104784fcbdSSowmini Varadhan char *fault_stat;
1114784fcbdSSowmini Varadhan ether_spdx_t *spdx_stat;
1124784fcbdSSowmini Varadhan } attr_kstat_t;
1134784fcbdSSowmini Varadhan
1144784fcbdSSowmini Varadhan static attr_kstat_t attrstat[] = {
1154784fcbdSSowmini Varadhan {"link_autoneg", /* current */
1164784fcbdSSowmini Varadhan "link_pause", "link_asmpause", NULL,
1174784fcbdSSowmini Varadhan NULL},
1184784fcbdSSowmini Varadhan
1194784fcbdSSowmini Varadhan {"cap_autoneg", /* capable */
1204784fcbdSSowmini Varadhan "cap_pause", "cap_asmpause", "cap_rem_fault",
1214784fcbdSSowmini Varadhan cap_spdx},
1224784fcbdSSowmini Varadhan
1234784fcbdSSowmini Varadhan {"adv_cap_autoneg", /* advertised */
1244784fcbdSSowmini Varadhan "adv_cap_pause", "adv_cap_asmpause", "adv_rem_fault",
1254784fcbdSSowmini Varadhan adv_cap_spdx},
1264784fcbdSSowmini Varadhan
1274784fcbdSSowmini Varadhan {"lp_cap_autoneg", /* peer advertised */
1284784fcbdSSowmini Varadhan "lp_cap_pause", "lp_cap_asmpause", "lp_rem_fault",
1294784fcbdSSowmini Varadhan lp_cap_spdx}
1304784fcbdSSowmini Varadhan };
1314784fcbdSSowmini Varadhan
1324784fcbdSSowmini Varadhan /*
1334784fcbdSSowmini Varadhan * Get the speed-duplex stats specified in the ether_spdx_t table passed in
1344784fcbdSSowmini Varadhan * by querying the appropriate kstat for each entry in the table.
1354784fcbdSSowmini Varadhan */
1364784fcbdSSowmini Varadhan static dladm_status_t
i_dladm_get_spdx(dladm_handle_t handle,datalink_id_t linkid,dladm_ether_attr_t * eattr,ether_spdx_t * spdx_stat)1374ac67f02SAnurag S. Maskey i_dladm_get_spdx(dladm_handle_t handle, datalink_id_t linkid,
1384ac67f02SAnurag S. Maskey dladm_ether_attr_t *eattr, ether_spdx_t *spdx_stat)
1394784fcbdSSowmini Varadhan {
1404784fcbdSSowmini Varadhan int i, nspdx = 0;
1414784fcbdSSowmini Varadhan uint32_t speed;
1424784fcbdSSowmini Varadhan dladm_status_t status;
1434784fcbdSSowmini Varadhan void *ptr;
1444784fcbdSSowmini Varadhan
1454784fcbdSSowmini Varadhan eattr->le_spdx = NULL;
1464784fcbdSSowmini Varadhan for (i = 0; spdx_stat[i].eth_spdx_stat_name != NULL; i++) {
1474ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid,
1484784fcbdSSowmini Varadhan spdx_stat[i].eth_spdx_stat_name,
1494784fcbdSSowmini Varadhan KSTAT_DATA_UINT32, &speed)) != DLADM_STATUS_OK) {
1504784fcbdSSowmini Varadhan
1514784fcbdSSowmini Varadhan if (status == DLADM_STATUS_NOTFOUND) {
1524784fcbdSSowmini Varadhan /*
1534784fcbdSSowmini Varadhan * Missing statistic.
1544784fcbdSSowmini Varadhan * Skip this one and try the rest.
1554784fcbdSSowmini Varadhan */
1564784fcbdSSowmini Varadhan continue;
1574784fcbdSSowmini Varadhan } else {
1584784fcbdSSowmini Varadhan free(eattr->le_spdx);
1594784fcbdSSowmini Varadhan eattr->le_num_spdx = 0;
1604784fcbdSSowmini Varadhan return (status);
1614784fcbdSSowmini Varadhan }
1624784fcbdSSowmini Varadhan }
1634784fcbdSSowmini Varadhan if (speed == 0)
1644784fcbdSSowmini Varadhan continue;
1654784fcbdSSowmini Varadhan nspdx++;
1664784fcbdSSowmini Varadhan ptr = realloc(eattr->le_spdx,
1674784fcbdSSowmini Varadhan nspdx * sizeof (dladm_ether_spdx_t));
1684784fcbdSSowmini Varadhan if (ptr != NULL) {
1694784fcbdSSowmini Varadhan eattr->le_spdx = ptr;
1704784fcbdSSowmini Varadhan } else {
1714784fcbdSSowmini Varadhan free(eattr->le_spdx);
1724784fcbdSSowmini Varadhan eattr->le_num_spdx = 0;
1734784fcbdSSowmini Varadhan return (DLADM_STATUS_NOMEM);
1744784fcbdSSowmini Varadhan }
1754784fcbdSSowmini Varadhan eattr->le_spdx[nspdx - 1] = spdx_stat[i].eth_spdx;
1764784fcbdSSowmini Varadhan }
1774784fcbdSSowmini Varadhan eattr->le_num_spdx = nspdx;
1784784fcbdSSowmini Varadhan return (DLADM_STATUS_OK);
1794784fcbdSSowmini Varadhan }
1804784fcbdSSowmini Varadhan
1814784fcbdSSowmini Varadhan /*
1824784fcbdSSowmini Varadhan * Returns "yes" or "no" based on the autonegotion capabilities
1834784fcbdSSowmini Varadhan * for the parameter type indicated by ptype. The permissible
1844784fcbdSSowmini Varadhan * values for ptype are CURRENT, CAPABLE, ADV, PEERADV.
1854784fcbdSSowmini Varadhan */
1864784fcbdSSowmini Varadhan char *
dladm_ether_autoneg2str(char * buf,size_t buflen,dladm_ether_info_t * eattr,int ptype)1874784fcbdSSowmini Varadhan dladm_ether_autoneg2str(char *buf, size_t buflen, dladm_ether_info_t *eattr,
1884784fcbdSSowmini Varadhan int ptype)
1894784fcbdSSowmini Varadhan {
1904784fcbdSSowmini Varadhan boolean_t autoneg = eattr->lei_attr[ptype].le_autoneg;
1914784fcbdSSowmini Varadhan
1924784fcbdSSowmini Varadhan (void) strlcpy(buf, (autoneg ? "yes" : "no"), buflen);
1934784fcbdSSowmini Varadhan return (buf);
1944784fcbdSSowmini Varadhan }
1954784fcbdSSowmini Varadhan
1964784fcbdSSowmini Varadhan /*
1974784fcbdSSowmini Varadhan * Returns {"bi", "tx", "none"} based on the flow-control capabilities
1984784fcbdSSowmini Varadhan * for the parameter type indicated by ptype. The permissible
1994784fcbdSSowmini Varadhan * values for ptype are CURRENT, CAPABLE, ADV, PEERADV.
2004784fcbdSSowmini Varadhan */
2014784fcbdSSowmini Varadhan char *
dladm_ether_pause2str(char * buf,size_t buflen,dladm_ether_info_t * eattr,int ptype)2024784fcbdSSowmini Varadhan dladm_ether_pause2str(char *buf, size_t buflen, dladm_ether_info_t *eattr,
2034784fcbdSSowmini Varadhan int ptype)
2044784fcbdSSowmini Varadhan {
2054784fcbdSSowmini Varadhan boolean_t pause = eattr->lei_attr[ptype].le_pause;
2064784fcbdSSowmini Varadhan boolean_t asmpause = eattr->lei_attr[ptype].le_asmpause;
2074784fcbdSSowmini Varadhan
2084784fcbdSSowmini Varadhan if (pause)
2094784fcbdSSowmini Varadhan (void) strlcpy(buf, "bi", buflen);
2104784fcbdSSowmini Varadhan else if (asmpause)
2114784fcbdSSowmini Varadhan (void) strlcpy(buf, "tx", buflen);
2124784fcbdSSowmini Varadhan else
2134784fcbdSSowmini Varadhan (void) strlcpy(buf, "none", buflen);
2144784fcbdSSowmini Varadhan return (buf);
2154784fcbdSSowmini Varadhan }
2164784fcbdSSowmini Varadhan
2174784fcbdSSowmini Varadhan /*
2184784fcbdSSowmini Varadhan * For a given param type, parse the list of speed-duplex pairs in
2194784fcbdSSowmini Varadhan * the dladm_ether_info_t and return a comma-separated string formatted
2204784fcbdSSowmini Varadhan * as <speed><speed-unit-char>-<duplex-chars> where <speed> is the value of
2214784fcbdSSowmini Varadhan * speed, in units specifid by the <speed-unit-char> which is one
2224784fcbdSSowmini Varadhan * of 'M' (Mbits/sec) or 'G' (Gigabits/sec). The permissible values of
2234784fcbdSSowmini Varadhan * <duplex-chars> are 'u' (indicating duplex is "unknown") or one/both of
2244784fcbdSSowmini Varadhan * 'f', 'h' (indicating full-duplex and half-duplex respectively)
2254784fcbdSSowmini Varadhan */
2264784fcbdSSowmini Varadhan extern char *
dladm_ether_spdx2str(char * buf,size_t buflen,dladm_ether_info_t * eattr,int ptype)2274784fcbdSSowmini Varadhan dladm_ether_spdx2str(char *buf, size_t buflen, dladm_ether_info_t *eattr,
2284784fcbdSSowmini Varadhan int ptype)
2294784fcbdSSowmini Varadhan {
2304202e8bfSToomas Soome uint_t i, j;
2314784fcbdSSowmini Varadhan boolean_t is_full, is_half;
2324784fcbdSSowmini Varadhan int speed;
2334784fcbdSSowmini Varadhan char speed_unit;
2344784fcbdSSowmini Varadhan char tmpbuf[DLADM_STRSIZE];
2354784fcbdSSowmini Varadhan dladm_ether_spdx_t *spdx;
2364784fcbdSSowmini Varadhan uint32_t nspdx;
2374784fcbdSSowmini Varadhan
2384784fcbdSSowmini Varadhan spdx = eattr->lei_attr[ptype].le_spdx;
2394784fcbdSSowmini Varadhan nspdx = eattr->lei_attr[ptype].le_num_spdx;
2404784fcbdSSowmini Varadhan for (i = 0; i < nspdx; i++) {
2414784fcbdSSowmini Varadhan
2424784fcbdSSowmini Varadhan speed = spdx[i].lesd_speed;
2434784fcbdSSowmini Varadhan
2444784fcbdSSowmini Varadhan /*
2454784fcbdSSowmini Varadhan * if we have already covered this speed for
2464784fcbdSSowmini Varadhan * the <other>-duplex case before this, skip it
2474784fcbdSSowmini Varadhan */
2484784fcbdSSowmini Varadhan for (j = 0; j < i; j++) {
2494784fcbdSSowmini Varadhan if (speed == spdx[j].lesd_speed)
2504784fcbdSSowmini Varadhan break;
2514784fcbdSSowmini Varadhan }
2524784fcbdSSowmini Varadhan if (j < i)
2534784fcbdSSowmini Varadhan continue;
2544784fcbdSSowmini Varadhan
2553bc4925dSGarrett D'Amore if ((speed % 1000) == 0) {
2564784fcbdSSowmini Varadhan speed = speed/1000;
2574784fcbdSSowmini Varadhan speed_unit = 'G';
2584784fcbdSSowmini Varadhan } else {
2594784fcbdSSowmini Varadhan speed_unit = 'M';
2604784fcbdSSowmini Varadhan }
2614784fcbdSSowmini Varadhan (void) snprintf(tmpbuf, DLADM_STRSIZE, "%d%c",
2624784fcbdSSowmini Varadhan speed, speed_unit);
2634784fcbdSSowmini Varadhan if (i > 0)
2644784fcbdSSowmini Varadhan (void) strncat(buf, ",", buflen);
2654784fcbdSSowmini Varadhan (void) strncat(buf, tmpbuf, buflen);
2664784fcbdSSowmini Varadhan
2674784fcbdSSowmini Varadhan is_full = is_half = B_FALSE;
2684784fcbdSSowmini Varadhan /*
2694784fcbdSSowmini Varadhan * Find all the supported duplex values for this speed.
2704784fcbdSSowmini Varadhan */
2714784fcbdSSowmini Varadhan for (j = 0; j < nspdx; j++) {
2724784fcbdSSowmini Varadhan if (spdx[j].lesd_speed != spdx[i].lesd_speed)
2734784fcbdSSowmini Varadhan continue;
2744784fcbdSSowmini Varadhan if (spdx[j].lesd_duplex == LINK_DUPLEX_FULL)
2754784fcbdSSowmini Varadhan is_full = B_TRUE;
2764784fcbdSSowmini Varadhan if (spdx[j].lesd_duplex == LINK_DUPLEX_HALF)
2774784fcbdSSowmini Varadhan is_half = B_TRUE;
2784784fcbdSSowmini Varadhan }
2794784fcbdSSowmini Varadhan if (is_full && is_half)
2804784fcbdSSowmini Varadhan (void) strncat(buf, "-fh", buflen);
2814784fcbdSSowmini Varadhan else if (is_full)
2824784fcbdSSowmini Varadhan (void) strncat(buf, "-f", buflen);
2834784fcbdSSowmini Varadhan else if (is_half)
2844784fcbdSSowmini Varadhan (void) strncat(buf, "-h", buflen);
2854784fcbdSSowmini Varadhan }
2864784fcbdSSowmini Varadhan return (buf);
2874784fcbdSSowmini Varadhan }
2884784fcbdSSowmini Varadhan
2894784fcbdSSowmini Varadhan /*
2904784fcbdSSowmini Varadhan * Extract Ethernet attributes of the link specified by linkid.
2914784fcbdSSowmini Varadhan * Information for the CURRENT, CAPABLE, ADV and PEERADV parameter
2924784fcbdSSowmini Varadhan * types is extracted into the lei_attr[] entries in the dladm_ether_info_t.
2934784fcbdSSowmini Varadhan * On succesful return, the memory allocated in this function should be
2944784fcbdSSowmini Varadhan * freed by calling dladm_ether_info_done().
2954784fcbdSSowmini Varadhan */
2964784fcbdSSowmini Varadhan extern dladm_status_t
dladm_ether_info(dladm_handle_t handle,datalink_id_t linkid,dladm_ether_info_t * eattr)2974ac67f02SAnurag S. Maskey dladm_ether_info(dladm_handle_t handle, datalink_id_t linkid,
2984ac67f02SAnurag S. Maskey dladm_ether_info_t *eattr)
2994784fcbdSSowmini Varadhan {
3004784fcbdSSowmini Varadhan uint32_t autoneg, pause, asmpause, fault;
3014784fcbdSSowmini Varadhan uint64_t sp64;
3024784fcbdSSowmini Varadhan dladm_status_t status;
3034784fcbdSSowmini Varadhan int i;
3044784fcbdSSowmini Varadhan link_duplex_t link_duplex;
3054784fcbdSSowmini Varadhan
3064784fcbdSSowmini Varadhan bzero(eattr, sizeof (*eattr));
3074ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL,
3084784fcbdSSowmini Varadhan eattr->lei_linkname, sizeof (eattr->lei_linkname));
3094784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK)
3104784fcbdSSowmini Varadhan goto bail;
3114784fcbdSSowmini Varadhan
3124784fcbdSSowmini Varadhan /* get current values of speed, duplex, state of link */
3134784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_num_spdx = 1;
3144784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_spdx = malloc(sizeof (dladm_ether_spdx_t));
3154784fcbdSSowmini Varadhan if (eattr->lei_attr[CURRENT].le_spdx == NULL) {
3164784fcbdSSowmini Varadhan status = DLADM_STATUS_NOMEM;
3174784fcbdSSowmini Varadhan goto bail;
3184784fcbdSSowmini Varadhan }
3194784fcbdSSowmini Varadhan
3204ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed",
3214784fcbdSSowmini Varadhan KSTAT_DATA_UINT64, &sp64)) != DLADM_STATUS_OK)
3224784fcbdSSowmini Varadhan goto bail;
3234784fcbdSSowmini Varadhan
3244ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex",
3254784fcbdSSowmini Varadhan KSTAT_DATA_UINT32, &link_duplex)) != DLADM_STATUS_OK)
3264784fcbdSSowmini Varadhan goto bail;
3274784fcbdSSowmini Varadhan
3284784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_spdx->lesd_speed = (int)(sp64/1000000ull);
3294784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_spdx->lesd_duplex = link_duplex;
3304784fcbdSSowmini Varadhan
3310dc2366fSVenugopal Iyer status = dladm_get_state(handle, linkid, &eattr->lei_state);
3324784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK)
3334784fcbdSSowmini Varadhan goto bail;
3344784fcbdSSowmini Varadhan
3354784fcbdSSowmini Varadhan /* get the auto, pause, asmpause, fault values */
3364784fcbdSSowmini Varadhan for (i = CURRENT; i <= PEERADV; i++) {
3374784fcbdSSowmini Varadhan
3384ac67f02SAnurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid,
3394784fcbdSSowmini Varadhan attrstat[i].autoneg_stat, KSTAT_DATA_UINT32, &autoneg);
3404784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK)
3414784fcbdSSowmini Varadhan goto bail;
3424784fcbdSSowmini Varadhan
3434ac67f02SAnurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid,
3444784fcbdSSowmini Varadhan attrstat[i].pause_stat, KSTAT_DATA_UINT32, &pause);
3454784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK)
3464784fcbdSSowmini Varadhan goto bail;
3474784fcbdSSowmini Varadhan
3484ac67f02SAnurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid,
3494784fcbdSSowmini Varadhan attrstat[i].asmpause_stat, KSTAT_DATA_UINT32, &asmpause);
3504784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK)
3514784fcbdSSowmini Varadhan goto bail;
3524784fcbdSSowmini Varadhan
3534784fcbdSSowmini Varadhan eattr->lei_attr[i].le_autoneg = (autoneg != 0);
3544784fcbdSSowmini Varadhan eattr->lei_attr[i].le_pause = (pause != 0);
3554784fcbdSSowmini Varadhan eattr->lei_attr[i].le_asmpause = (asmpause != 0);
3564784fcbdSSowmini Varadhan
3574784fcbdSSowmini Varadhan if (i == CURRENT)
3584784fcbdSSowmini Varadhan continue;
3594ac67f02SAnurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid,
3604784fcbdSSowmini Varadhan attrstat[i].fault_stat, KSTAT_DATA_UINT32, &fault);
3614784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK)
3624784fcbdSSowmini Varadhan goto bail;
3634784fcbdSSowmini Varadhan eattr->lei_attr[i].le_fault = (pause != 0);
3644784fcbdSSowmini Varadhan
3654784fcbdSSowmini Varadhan /* get all the supported speed/duplex values */
3664ac67f02SAnurag S. Maskey status = i_dladm_get_spdx(handle, linkid, &eattr->lei_attr[i],
3674784fcbdSSowmini Varadhan attrstat[i].spdx_stat);
3684784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK)
3694784fcbdSSowmini Varadhan goto bail;
3704784fcbdSSowmini Varadhan }
3714784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_fault =
3724784fcbdSSowmini Varadhan eattr->lei_attr[ADV].le_fault || eattr->lei_attr[PEERADV].le_fault;
3734784fcbdSSowmini Varadhan bail:
3744784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK)
3754784fcbdSSowmini Varadhan dladm_ether_info_done(eattr);
3764784fcbdSSowmini Varadhan return (status);
3774784fcbdSSowmini Varadhan }
3784784fcbdSSowmini Varadhan
3794784fcbdSSowmini Varadhan extern void
dladm_ether_info_done(dladm_ether_info_t * eattr)3804784fcbdSSowmini Varadhan dladm_ether_info_done(dladm_ether_info_t *eattr)
3814784fcbdSSowmini Varadhan {
3824784fcbdSSowmini Varadhan int i;
3834784fcbdSSowmini Varadhan
3847fa359c0SRobert Mustacchi for (i = CURRENT; i <= PEERADV; i++) {
3854784fcbdSSowmini Varadhan free(eattr->lei_attr[i].le_spdx);
3867fa359c0SRobert Mustacchi eattr->lei_attr[i].le_spdx = NULL;
3877fa359c0SRobert Mustacchi }
3884784fcbdSSowmini Varadhan }
389