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. 24*b62c04c0SGarrett D'Amore * 25*b62c04c0SGarrett 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[] = { 504784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "cap_1000fdx"}, 514784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "cap_1000hdx"}, 524784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_FULL}, "cap_100fdx"}, 534784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_HALF}, "cap_100hdx"}, 544784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_FULL}, "cap_10fdx"}, 554784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_HALF}, "cap_10hdx"}, 564784fcbdSSowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL} 574784fcbdSSowmini Varadhan }; 584784fcbdSSowmini Varadhan 594784fcbdSSowmini Varadhan static ether_spdx_t adv_cap_spdx[] = { 604784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "adv_cap_1000fdx"}, 614784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "adv_cap_1000hdx"}, 624784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_FULL}, "adv_cap_100fdx"}, 634784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_HALF}, "adv_cap_100hdx"}, 644784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_FULL}, "adv_cap_10fdx"}, 654784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_HALF}, "adv_cap_10hdx"}, 664784fcbdSSowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL} 674784fcbdSSowmini Varadhan }; 684784fcbdSSowmini Varadhan 694784fcbdSSowmini Varadhan static ether_spdx_t lp_cap_spdx[] = { 704784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_FULL}, "lp_cap_1000fdx"}, 714784fcbdSSowmini Varadhan {{1000, LINK_DUPLEX_HALF}, "lp_cap_1000hdx"}, 724784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_FULL}, "lp_cap_100fdx"}, 734784fcbdSSowmini Varadhan {{100, LINK_DUPLEX_HALF}, "lp_cap_100hdx"}, 744784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_FULL}, "lp_cap_10fdx"}, 754784fcbdSSowmini Varadhan {{10, LINK_DUPLEX_HALF}, "lp_cap_10hdx"}, 764784fcbdSSowmini Varadhan {{0, LINK_DUPLEX_UNKNOWN}, NULL} 774784fcbdSSowmini Varadhan }; 784784fcbdSSowmini Varadhan 794784fcbdSSowmini Varadhan typedef struct attr_kstat_s { 804784fcbdSSowmini Varadhan char *autoneg_stat; 814784fcbdSSowmini Varadhan char *pause_stat; 824784fcbdSSowmini Varadhan char *asmpause_stat; 834784fcbdSSowmini Varadhan char *fault_stat; 844784fcbdSSowmini Varadhan ether_spdx_t *spdx_stat; 854784fcbdSSowmini Varadhan } attr_kstat_t; 864784fcbdSSowmini Varadhan 874784fcbdSSowmini Varadhan static attr_kstat_t attrstat[] = { 884784fcbdSSowmini Varadhan {"link_autoneg", /* current */ 894784fcbdSSowmini Varadhan "link_pause", "link_asmpause", NULL, 904784fcbdSSowmini Varadhan NULL}, 914784fcbdSSowmini Varadhan 924784fcbdSSowmini Varadhan {"cap_autoneg", /* capable */ 934784fcbdSSowmini Varadhan "cap_pause", "cap_asmpause", "cap_rem_fault", 944784fcbdSSowmini Varadhan cap_spdx}, 954784fcbdSSowmini Varadhan 964784fcbdSSowmini Varadhan {"adv_cap_autoneg", /* advertised */ 974784fcbdSSowmini Varadhan "adv_cap_pause", "adv_cap_asmpause", "adv_rem_fault", 984784fcbdSSowmini Varadhan adv_cap_spdx}, 994784fcbdSSowmini Varadhan 1004784fcbdSSowmini Varadhan {"lp_cap_autoneg", /* peer advertised */ 1014784fcbdSSowmini Varadhan "lp_cap_pause", "lp_cap_asmpause", "lp_rem_fault", 1024784fcbdSSowmini Varadhan lp_cap_spdx} 1034784fcbdSSowmini Varadhan }; 1044784fcbdSSowmini Varadhan 1054784fcbdSSowmini Varadhan /* 1064784fcbdSSowmini Varadhan * Get the speed-duplex stats specified in the ether_spdx_t table passed in 1074784fcbdSSowmini Varadhan * by querying the appropriate kstat for each entry in the table. 1084784fcbdSSowmini Varadhan */ 1094784fcbdSSowmini Varadhan static dladm_status_t 1104ac67f02SAnurag S. Maskey i_dladm_get_spdx(dladm_handle_t handle, datalink_id_t linkid, 1114ac67f02SAnurag S. Maskey dladm_ether_attr_t *eattr, ether_spdx_t *spdx_stat) 1124784fcbdSSowmini Varadhan { 1134784fcbdSSowmini Varadhan int i, nspdx = 0; 1144784fcbdSSowmini Varadhan uint32_t speed; 1154784fcbdSSowmini Varadhan dladm_status_t status; 1164784fcbdSSowmini Varadhan void *ptr; 1174784fcbdSSowmini Varadhan 1184784fcbdSSowmini Varadhan eattr->le_spdx = NULL; 1194784fcbdSSowmini Varadhan for (i = 0; spdx_stat[i].eth_spdx_stat_name != NULL; i++) { 1204ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, 1214784fcbdSSowmini Varadhan spdx_stat[i].eth_spdx_stat_name, 1224784fcbdSSowmini Varadhan KSTAT_DATA_UINT32, &speed)) != DLADM_STATUS_OK) { 1234784fcbdSSowmini Varadhan 1244784fcbdSSowmini Varadhan if (status == DLADM_STATUS_NOTFOUND) { 1254784fcbdSSowmini Varadhan /* 1264784fcbdSSowmini Varadhan * Missing statistic. 1274784fcbdSSowmini Varadhan * Skip this one and try the rest. 1284784fcbdSSowmini Varadhan */ 1294784fcbdSSowmini Varadhan continue; 1304784fcbdSSowmini Varadhan } else { 1314784fcbdSSowmini Varadhan free(eattr->le_spdx); 1324784fcbdSSowmini Varadhan eattr->le_num_spdx = 0; 1334784fcbdSSowmini Varadhan return (status); 1344784fcbdSSowmini Varadhan } 1354784fcbdSSowmini Varadhan } 1364784fcbdSSowmini Varadhan if (speed == 0) 1374784fcbdSSowmini Varadhan continue; 1384784fcbdSSowmini Varadhan nspdx++; 1394784fcbdSSowmini Varadhan ptr = realloc(eattr->le_spdx, 1404784fcbdSSowmini Varadhan nspdx * sizeof (dladm_ether_spdx_t)); 1414784fcbdSSowmini Varadhan if (ptr != NULL) { 1424784fcbdSSowmini Varadhan eattr->le_spdx = ptr; 1434784fcbdSSowmini Varadhan } else { 1444784fcbdSSowmini Varadhan free(eattr->le_spdx); 1454784fcbdSSowmini Varadhan eattr->le_num_spdx = 0; 1464784fcbdSSowmini Varadhan return (DLADM_STATUS_NOMEM); 1474784fcbdSSowmini Varadhan } 1484784fcbdSSowmini Varadhan eattr->le_spdx[nspdx - 1] = spdx_stat[i].eth_spdx; 1494784fcbdSSowmini Varadhan } 1504784fcbdSSowmini Varadhan eattr->le_num_spdx = nspdx; 1514784fcbdSSowmini Varadhan return (DLADM_STATUS_OK); 1524784fcbdSSowmini Varadhan } 1534784fcbdSSowmini Varadhan 1544784fcbdSSowmini Varadhan /* 1554784fcbdSSowmini Varadhan * Returns "yes" or "no" based on the autonegotion capabilities 1564784fcbdSSowmini Varadhan * for the parameter type indicated by ptype. The permissible 1574784fcbdSSowmini Varadhan * values for ptype are CURRENT, CAPABLE, ADV, PEERADV. 1584784fcbdSSowmini Varadhan */ 1594784fcbdSSowmini Varadhan char * 1604784fcbdSSowmini Varadhan dladm_ether_autoneg2str(char *buf, size_t buflen, dladm_ether_info_t *eattr, 1614784fcbdSSowmini Varadhan int ptype) 1624784fcbdSSowmini Varadhan { 1634784fcbdSSowmini Varadhan boolean_t autoneg = eattr->lei_attr[ptype].le_autoneg; 1644784fcbdSSowmini Varadhan 1654784fcbdSSowmini Varadhan (void) strlcpy(buf, (autoneg ? "yes" : "no"), buflen); 1664784fcbdSSowmini Varadhan return (buf); 1674784fcbdSSowmini Varadhan } 1684784fcbdSSowmini Varadhan 1694784fcbdSSowmini Varadhan /* 1704784fcbdSSowmini Varadhan * Returns {"bi", "tx", "none"} based on the flow-control capabilities 1714784fcbdSSowmini Varadhan * for the parameter type indicated by ptype. The permissible 1724784fcbdSSowmini Varadhan * values for ptype are CURRENT, CAPABLE, ADV, PEERADV. 1734784fcbdSSowmini Varadhan */ 1744784fcbdSSowmini Varadhan char * 1754784fcbdSSowmini Varadhan dladm_ether_pause2str(char *buf, size_t buflen, dladm_ether_info_t *eattr, 1764784fcbdSSowmini Varadhan int ptype) 1774784fcbdSSowmini Varadhan { 1784784fcbdSSowmini Varadhan boolean_t pause = eattr->lei_attr[ptype].le_pause; 1794784fcbdSSowmini Varadhan boolean_t asmpause = eattr->lei_attr[ptype].le_asmpause; 1804784fcbdSSowmini Varadhan 1814784fcbdSSowmini Varadhan if (pause) 1824784fcbdSSowmini Varadhan (void) strlcpy(buf, "bi", buflen); 1834784fcbdSSowmini Varadhan else if (asmpause) 1844784fcbdSSowmini Varadhan (void) strlcpy(buf, "tx", buflen); 1854784fcbdSSowmini Varadhan else 1864784fcbdSSowmini Varadhan (void) strlcpy(buf, "none", buflen); 1874784fcbdSSowmini Varadhan return (buf); 1884784fcbdSSowmini Varadhan } 1894784fcbdSSowmini Varadhan 1904784fcbdSSowmini Varadhan /* 1914784fcbdSSowmini Varadhan * For a given param type, parse the list of speed-duplex pairs in 1924784fcbdSSowmini Varadhan * the dladm_ether_info_t and return a comma-separated string formatted 1934784fcbdSSowmini Varadhan * as <speed><speed-unit-char>-<duplex-chars> where <speed> is the value of 1944784fcbdSSowmini Varadhan * speed, in units specifid by the <speed-unit-char> which is one 1954784fcbdSSowmini Varadhan * of 'M' (Mbits/sec) or 'G' (Gigabits/sec). The permissible values of 1964784fcbdSSowmini Varadhan * <duplex-chars> are 'u' (indicating duplex is "unknown") or one/both of 1974784fcbdSSowmini Varadhan * 'f', 'h' (indicating full-duplex and half-duplex respectively) 1984784fcbdSSowmini Varadhan */ 1994784fcbdSSowmini Varadhan extern char * 2004784fcbdSSowmini Varadhan dladm_ether_spdx2str(char *buf, size_t buflen, dladm_ether_info_t *eattr, 2014784fcbdSSowmini Varadhan int ptype) 2024784fcbdSSowmini Varadhan { 2034784fcbdSSowmini Varadhan int i, j; 2044784fcbdSSowmini Varadhan boolean_t is_full, is_half; 2054784fcbdSSowmini Varadhan int speed; 2064784fcbdSSowmini Varadhan char speed_unit; 2074784fcbdSSowmini Varadhan char tmpbuf[DLADM_STRSIZE]; 2084784fcbdSSowmini Varadhan dladm_ether_spdx_t *spdx; 2094784fcbdSSowmini Varadhan uint32_t nspdx; 2104784fcbdSSowmini Varadhan 2114784fcbdSSowmini Varadhan spdx = eattr->lei_attr[ptype].le_spdx; 2124784fcbdSSowmini Varadhan nspdx = eattr->lei_attr[ptype].le_num_spdx; 2134784fcbdSSowmini Varadhan for (i = 0; i < nspdx; i++) { 2144784fcbdSSowmini Varadhan 2154784fcbdSSowmini Varadhan speed = spdx[i].lesd_speed; 2164784fcbdSSowmini Varadhan 2174784fcbdSSowmini Varadhan /* 2184784fcbdSSowmini Varadhan * if we have already covered this speed for 2194784fcbdSSowmini Varadhan * the <other>-duplex case before this, skip it 2204784fcbdSSowmini Varadhan */ 2214784fcbdSSowmini Varadhan for (j = 0; j < i; j++) { 2224784fcbdSSowmini Varadhan if (speed == spdx[j].lesd_speed) 2234784fcbdSSowmini Varadhan break; 2244784fcbdSSowmini Varadhan } 2254784fcbdSSowmini Varadhan if (j < i) 2264784fcbdSSowmini Varadhan continue; 2274784fcbdSSowmini Varadhan 228*b62c04c0SGarrett D'Amore if ((speed % 1000) == 0) { 2294784fcbdSSowmini Varadhan speed = speed/1000; 2304784fcbdSSowmini Varadhan speed_unit = 'G'; 2314784fcbdSSowmini Varadhan } else { 2324784fcbdSSowmini Varadhan speed_unit = 'M'; 2334784fcbdSSowmini Varadhan } 2344784fcbdSSowmini Varadhan (void) snprintf(tmpbuf, DLADM_STRSIZE, "%d%c", 2354784fcbdSSowmini Varadhan speed, speed_unit); 2364784fcbdSSowmini Varadhan if (i > 0) 2374784fcbdSSowmini Varadhan (void) strncat(buf, ",", buflen); 2384784fcbdSSowmini Varadhan (void) strncat(buf, tmpbuf, buflen); 2394784fcbdSSowmini Varadhan 2404784fcbdSSowmini Varadhan is_full = is_half = B_FALSE; 2414784fcbdSSowmini Varadhan /* 2424784fcbdSSowmini Varadhan * Find all the supported duplex values for this speed. 2434784fcbdSSowmini Varadhan */ 2444784fcbdSSowmini Varadhan for (j = 0; j < nspdx; j++) { 2454784fcbdSSowmini Varadhan if (spdx[j].lesd_speed != spdx[i].lesd_speed) 2464784fcbdSSowmini Varadhan continue; 2474784fcbdSSowmini Varadhan if (spdx[j].lesd_duplex == LINK_DUPLEX_FULL) 2484784fcbdSSowmini Varadhan is_full = B_TRUE; 2494784fcbdSSowmini Varadhan if (spdx[j].lesd_duplex == LINK_DUPLEX_HALF) 2504784fcbdSSowmini Varadhan is_half = B_TRUE; 2514784fcbdSSowmini Varadhan } 2524784fcbdSSowmini Varadhan if (is_full && is_half) 2534784fcbdSSowmini Varadhan (void) strncat(buf, "-fh", buflen); 2544784fcbdSSowmini Varadhan else if (is_full) 2554784fcbdSSowmini Varadhan (void) strncat(buf, "-f", buflen); 2564784fcbdSSowmini Varadhan else if (is_half) 2574784fcbdSSowmini Varadhan (void) strncat(buf, "-h", buflen); 2584784fcbdSSowmini Varadhan } 2594784fcbdSSowmini Varadhan return (buf); 2604784fcbdSSowmini Varadhan } 2614784fcbdSSowmini Varadhan 2624784fcbdSSowmini Varadhan /* 2634784fcbdSSowmini Varadhan * Extract Ethernet attributes of the link specified by linkid. 2644784fcbdSSowmini Varadhan * Information for the CURRENT, CAPABLE, ADV and PEERADV parameter 2654784fcbdSSowmini Varadhan * types is extracted into the lei_attr[] entries in the dladm_ether_info_t. 2664784fcbdSSowmini Varadhan * On succesful return, the memory allocated in this function should be 2674784fcbdSSowmini Varadhan * freed by calling dladm_ether_info_done(). 2684784fcbdSSowmini Varadhan */ 2694784fcbdSSowmini Varadhan extern dladm_status_t 2704ac67f02SAnurag S. Maskey dladm_ether_info(dladm_handle_t handle, datalink_id_t linkid, 2714ac67f02SAnurag S. Maskey dladm_ether_info_t *eattr) 2724784fcbdSSowmini Varadhan { 2734784fcbdSSowmini Varadhan uint32_t autoneg, pause, asmpause, fault; 2744784fcbdSSowmini Varadhan uint64_t sp64; 2754784fcbdSSowmini Varadhan dladm_status_t status; 2764784fcbdSSowmini Varadhan int i; 2774784fcbdSSowmini Varadhan link_duplex_t link_duplex; 2784784fcbdSSowmini Varadhan 2794784fcbdSSowmini Varadhan bzero(eattr, sizeof (*eattr)); 2804ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL, 2814784fcbdSSowmini Varadhan eattr->lei_linkname, sizeof (eattr->lei_linkname)); 2824784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 2834784fcbdSSowmini Varadhan goto bail; 2844784fcbdSSowmini Varadhan 2854784fcbdSSowmini Varadhan /* get current values of speed, duplex, state of link */ 2864784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_num_spdx = 1; 2874784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_spdx = malloc(sizeof (dladm_ether_spdx_t)); 2884784fcbdSSowmini Varadhan if (eattr->lei_attr[CURRENT].le_spdx == NULL) { 2894784fcbdSSowmini Varadhan status = DLADM_STATUS_NOMEM; 2904784fcbdSSowmini Varadhan goto bail; 2914784fcbdSSowmini Varadhan } 2924784fcbdSSowmini Varadhan 2934ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "ifspeed", 2944784fcbdSSowmini Varadhan KSTAT_DATA_UINT64, &sp64)) != DLADM_STATUS_OK) 2954784fcbdSSowmini Varadhan goto bail; 2964784fcbdSSowmini Varadhan 2974ac67f02SAnurag S. Maskey if ((status = dladm_get_single_mac_stat(handle, linkid, "link_duplex", 2984784fcbdSSowmini Varadhan KSTAT_DATA_UINT32, &link_duplex)) != DLADM_STATUS_OK) 2994784fcbdSSowmini Varadhan goto bail; 3004784fcbdSSowmini Varadhan 3014784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_spdx->lesd_speed = (int)(sp64/1000000ull); 3024784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_spdx->lesd_duplex = link_duplex; 3034784fcbdSSowmini Varadhan 3040dc2366fSVenugopal Iyer status = dladm_get_state(handle, linkid, &eattr->lei_state); 3054784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 3064784fcbdSSowmini Varadhan goto bail; 3074784fcbdSSowmini Varadhan 3084784fcbdSSowmini Varadhan /* get the auto, pause, asmpause, fault values */ 3094784fcbdSSowmini Varadhan for (i = CURRENT; i <= PEERADV; i++) { 3104784fcbdSSowmini Varadhan 3114ac67f02SAnurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid, 3124784fcbdSSowmini Varadhan attrstat[i].autoneg_stat, KSTAT_DATA_UINT32, &autoneg); 3134784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 3144784fcbdSSowmini Varadhan goto bail; 3154784fcbdSSowmini Varadhan 3164ac67f02SAnurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid, 3174784fcbdSSowmini Varadhan attrstat[i].pause_stat, KSTAT_DATA_UINT32, &pause); 3184784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 3194784fcbdSSowmini Varadhan goto bail; 3204784fcbdSSowmini Varadhan 3214ac67f02SAnurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid, 3224784fcbdSSowmini Varadhan attrstat[i].asmpause_stat, KSTAT_DATA_UINT32, &asmpause); 3234784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 3244784fcbdSSowmini Varadhan goto bail; 3254784fcbdSSowmini Varadhan 3264784fcbdSSowmini Varadhan eattr->lei_attr[i].le_autoneg = (autoneg != 0); 3274784fcbdSSowmini Varadhan eattr->lei_attr[i].le_pause = (pause != 0); 3284784fcbdSSowmini Varadhan eattr->lei_attr[i].le_asmpause = (asmpause != 0); 3294784fcbdSSowmini Varadhan 3304784fcbdSSowmini Varadhan if (i == CURRENT) 3314784fcbdSSowmini Varadhan continue; 3324ac67f02SAnurag S. Maskey status = dladm_get_single_mac_stat(handle, linkid, 3334784fcbdSSowmini Varadhan attrstat[i].fault_stat, KSTAT_DATA_UINT32, &fault); 3344784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 3354784fcbdSSowmini Varadhan goto bail; 3364784fcbdSSowmini Varadhan eattr->lei_attr[i].le_fault = (pause != 0); 3374784fcbdSSowmini Varadhan 3384784fcbdSSowmini Varadhan /* get all the supported speed/duplex values */ 3394ac67f02SAnurag S. Maskey status = i_dladm_get_spdx(handle, linkid, &eattr->lei_attr[i], 3404784fcbdSSowmini Varadhan attrstat[i].spdx_stat); 3414784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 3424784fcbdSSowmini Varadhan goto bail; 3434784fcbdSSowmini Varadhan } 3444784fcbdSSowmini Varadhan eattr->lei_attr[CURRENT].le_fault = 3454784fcbdSSowmini Varadhan eattr->lei_attr[ADV].le_fault || eattr->lei_attr[PEERADV].le_fault; 3464784fcbdSSowmini Varadhan bail: 3474784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 3484784fcbdSSowmini Varadhan dladm_ether_info_done(eattr); 3494784fcbdSSowmini Varadhan return (status); 3504784fcbdSSowmini Varadhan } 3514784fcbdSSowmini Varadhan 3524784fcbdSSowmini Varadhan extern void 3534784fcbdSSowmini Varadhan dladm_ether_info_done(dladm_ether_info_t *eattr) 3544784fcbdSSowmini Varadhan { 3554784fcbdSSowmini Varadhan int i; 3564784fcbdSSowmini Varadhan 3574784fcbdSSowmini Varadhan for (i = CURRENT; i <= PEERADV; i++) 3584784fcbdSSowmini Varadhan free(eattr->lei_attr[i].le_spdx); 3594784fcbdSSowmini Varadhan } 360