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