19087SZhong.Wang@Sun.COM /* 29087SZhong.Wang@Sun.COM * CDDL HEADER START 39087SZhong.Wang@Sun.COM * 49087SZhong.Wang@Sun.COM * The contents of this file are subject to the terms of the 59087SZhong.Wang@Sun.COM * Common Development and Distribution License (the "License"). 69087SZhong.Wang@Sun.COM * You may not use this file except in compliance with the License. 79087SZhong.Wang@Sun.COM * 89087SZhong.Wang@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 99087SZhong.Wang@Sun.COM * or http://www.opensolaris.org/os/licensing. 109087SZhong.Wang@Sun.COM * See the License for the specific language governing permissions 119087SZhong.Wang@Sun.COM * and limitations under the License. 129087SZhong.Wang@Sun.COM * 139087SZhong.Wang@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 149087SZhong.Wang@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 159087SZhong.Wang@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 169087SZhong.Wang@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 179087SZhong.Wang@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 189087SZhong.Wang@Sun.COM * 199087SZhong.Wang@Sun.COM * CDDL HEADER END 209087SZhong.Wang@Sun.COM */ 219087SZhong.Wang@Sun.COM /* 229087SZhong.Wang@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 239087SZhong.Wang@Sun.COM * Use is subject to license terms. 249087SZhong.Wang@Sun.COM */ 259087SZhong.Wang@Sun.COM 269087SZhong.Wang@Sun.COM #include <stdlib.h> 279087SZhong.Wang@Sun.COM #include <stdio.h> 289087SZhong.Wang@Sun.COM #include <wchar.h> 299087SZhong.Wang@Sun.COM #include <strings.h> 309087SZhong.Wang@Sun.COM #include <sys/types.h> 319087SZhong.Wang@Sun.COM #include <sys/stat.h> 329087SZhong.Wang@Sun.COM #include <fcntl.h> 339087SZhong.Wang@Sun.COM #include <unistd.h> 349087SZhong.Wang@Sun.COM #include <libintl.h> 359087SZhong.Wang@Sun.COM #include <errno.h> 369087SZhong.Wang@Sun.COM #include <string.h> 379087SZhong.Wang@Sun.COM #include <assert.h> 389087SZhong.Wang@Sun.COM #include <syslog.h> 399087SZhong.Wang@Sun.COM #include <libfcoe.h> 40*9307Skelly.hu@Sun.COM #include <libdllink.h> 419087SZhong.Wang@Sun.COM #include <fcoeio.h> 429087SZhong.Wang@Sun.COM 439087SZhong.Wang@Sun.COM #define FCOE_DEV_PATH "/devices/fcoe:admin" 449087SZhong.Wang@Sun.COM 459087SZhong.Wang@Sun.COM #define OPEN_FCOE 0 469087SZhong.Wang@Sun.COM #define OPEN_EXCL_FCOE O_EXCL 479087SZhong.Wang@Sun.COM 489087SZhong.Wang@Sun.COM /* 499087SZhong.Wang@Sun.COM * Open for fcoe module 509087SZhong.Wang@Sun.COM * 519087SZhong.Wang@Sun.COM * flag - open flag (OPEN_FCOE, OPEN_EXCL_FCOE) 529087SZhong.Wang@Sun.COM * fd - pointer to integer. On success, contains the fcoe file descriptor 539087SZhong.Wang@Sun.COM */ 549087SZhong.Wang@Sun.COM static int 559087SZhong.Wang@Sun.COM openFcoe(int flag, int *fd) 569087SZhong.Wang@Sun.COM { 579087SZhong.Wang@Sun.COM int ret = FCOE_STATUS_ERROR; 589087SZhong.Wang@Sun.COM 599087SZhong.Wang@Sun.COM if ((*fd = open(FCOE_DEV_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 609087SZhong.Wang@Sun.COM ret = FCOE_STATUS_OK; 619087SZhong.Wang@Sun.COM } else { 629087SZhong.Wang@Sun.COM if (errno == EPERM || errno == EACCES) { 639087SZhong.Wang@Sun.COM ret = FCOE_STATUS_ERROR_PERM; 649087SZhong.Wang@Sun.COM } else { 659087SZhong.Wang@Sun.COM ret = FCOE_STATUS_ERROR_OPEN_DEV; 669087SZhong.Wang@Sun.COM } 679087SZhong.Wang@Sun.COM syslog(LOG_DEBUG, "openFcoe:open failure:%s:errno(%d)", 689087SZhong.Wang@Sun.COM FCOE_DEV_PATH, errno); 699087SZhong.Wang@Sun.COM } 709087SZhong.Wang@Sun.COM 719087SZhong.Wang@Sun.COM return (ret); 729087SZhong.Wang@Sun.COM } 739087SZhong.Wang@Sun.COM 749087SZhong.Wang@Sun.COM static int 759087SZhong.Wang@Sun.COM isWWNZero(FCOE_PORT_WWN portwwn) 769087SZhong.Wang@Sun.COM { 779087SZhong.Wang@Sun.COM int i; 789087SZhong.Wang@Sun.COM int size = sizeof (FCOE_PORT_WWN); 799087SZhong.Wang@Sun.COM 809087SZhong.Wang@Sun.COM for (i = 0; i < size; i++) { 819087SZhong.Wang@Sun.COM if (portwwn.wwn[i] != 0) { 829087SZhong.Wang@Sun.COM return (0); 839087SZhong.Wang@Sun.COM } 849087SZhong.Wang@Sun.COM } 859087SZhong.Wang@Sun.COM return (1); 869087SZhong.Wang@Sun.COM } 879087SZhong.Wang@Sun.COM 889087SZhong.Wang@Sun.COM FCOE_STATUS 899087SZhong.Wang@Sun.COM FCOE_CreatePort( 909087SZhong.Wang@Sun.COM const FCOE_UINT8 *macLinkName, 919087SZhong.Wang@Sun.COM FCOE_UINT8 portType, 929087SZhong.Wang@Sun.COM FCOE_PORT_WWN pwwn, 939087SZhong.Wang@Sun.COM FCOE_PORT_WWN nwwn, 949087SZhong.Wang@Sun.COM FCOE_UINT8 promiscuous) 959087SZhong.Wang@Sun.COM { 96*9307Skelly.hu@Sun.COM FCOE_STATUS status = FCOE_STATUS_OK; 97*9307Skelly.hu@Sun.COM int fcoe_fd; 98*9307Skelly.hu@Sun.COM fcoeio_t fcoeio; 999087SZhong.Wang@Sun.COM fcoeio_create_port_param_t param; 100*9307Skelly.hu@Sun.COM dladm_handle_t handle; 101*9307Skelly.hu@Sun.COM datalink_id_t linkid; 102*9307Skelly.hu@Sun.COM datalink_class_t class; 1039087SZhong.Wang@Sun.COM 1049087SZhong.Wang@Sun.COM bzero(¶m, sizeof (fcoeio_create_port_param_t)); 1059087SZhong.Wang@Sun.COM 1069087SZhong.Wang@Sun.COM if (macLinkName == NULL) { 1079087SZhong.Wang@Sun.COM return (FCOE_STATUS_ERROR_INVAL_ARG); 1089087SZhong.Wang@Sun.COM } 1099087SZhong.Wang@Sun.COM 110*9307Skelly.hu@Sun.COM if (strlen((char *)macLinkName) > MAXLINKNAMELEN-1) { 111*9307Skelly.hu@Sun.COM return (FCOE_STATUS_ERROR_MAC_LEN); 112*9307Skelly.hu@Sun.COM } 113*9307Skelly.hu@Sun.COM 114*9307Skelly.hu@Sun.COM if (dladm_open(&handle) != DLADM_STATUS_OK) { 115*9307Skelly.hu@Sun.COM return (FCOE_STATUS_ERROR); 116*9307Skelly.hu@Sun.COM } 117*9307Skelly.hu@Sun.COM 118*9307Skelly.hu@Sun.COM if (dladm_name2info(handle, (const char *)macLinkName, 119*9307Skelly.hu@Sun.COM &linkid, NULL, &class, NULL) != DLADM_STATUS_OK) { 120*9307Skelly.hu@Sun.COM dladm_close(handle); 121*9307Skelly.hu@Sun.COM return (FCOE_STATUS_ERROR_GET_LINKINFO); 122*9307Skelly.hu@Sun.COM } 123*9307Skelly.hu@Sun.COM dladm_close(handle); 124*9307Skelly.hu@Sun.COM 125*9307Skelly.hu@Sun.COM if (class != DATALINK_CLASS_PHYS) { 126*9307Skelly.hu@Sun.COM return (FCOE_STATUS_ERROR_CLASS_UNSUPPORT); 127*9307Skelly.hu@Sun.COM } 128*9307Skelly.hu@Sun.COM 1299087SZhong.Wang@Sun.COM if (portType != FCOE_PORTTYPE_INITIATOR && 1309087SZhong.Wang@Sun.COM portType != FCOE_PORTTYPE_TARGET) { 1319087SZhong.Wang@Sun.COM return (FCOE_STATUS_ERROR_INVAL_ARG); 1329087SZhong.Wang@Sun.COM } 1339087SZhong.Wang@Sun.COM 1349087SZhong.Wang@Sun.COM if (!isWWNZero(pwwn)) { 1359087SZhong.Wang@Sun.COM param.fcp_pwwn_provided = 1; 1369087SZhong.Wang@Sun.COM bcopy(pwwn.wwn, param.fcp_pwwn, 8); 1379087SZhong.Wang@Sun.COM } 1389087SZhong.Wang@Sun.COM 1399087SZhong.Wang@Sun.COM if (!isWWNZero(nwwn)) { 1409087SZhong.Wang@Sun.COM param.fcp_nwwn_provided = 1; 1419087SZhong.Wang@Sun.COM bcopy(nwwn.wwn, param.fcp_nwwn, 8); 1429087SZhong.Wang@Sun.COM } 1439087SZhong.Wang@Sun.COM 1449087SZhong.Wang@Sun.COM if (param.fcp_pwwn_provided == 1 && 1459087SZhong.Wang@Sun.COM param.fcp_nwwn_provided == 1 && 1469087SZhong.Wang@Sun.COM bcmp(&pwwn, &nwwn, 8) == 0) { 1479087SZhong.Wang@Sun.COM return (FCOE_STATUS_ERROR_WWN_SAME); 1489087SZhong.Wang@Sun.COM } 1499087SZhong.Wang@Sun.COM 1509087SZhong.Wang@Sun.COM param.fcp_force_promisc = promiscuous; 151*9307Skelly.hu@Sun.COM param.fcp_mac_linkid = linkid; 1529087SZhong.Wang@Sun.COM param.fcp_port_type = (fcoe_cli_type_t)portType; 1539087SZhong.Wang@Sun.COM 1549087SZhong.Wang@Sun.COM if ((status = openFcoe(OPEN_FCOE, &fcoe_fd)) != FCOE_STATUS_OK) { 1559087SZhong.Wang@Sun.COM return (status); 1569087SZhong.Wang@Sun.COM } 1579087SZhong.Wang@Sun.COM 1589087SZhong.Wang@Sun.COM (void) memset(&fcoeio, 0, sizeof (fcoeio)); 1599087SZhong.Wang@Sun.COM fcoeio.fcoeio_cmd = FCOEIO_CREATE_FCOE_PORT; 1609087SZhong.Wang@Sun.COM 1619087SZhong.Wang@Sun.COM fcoeio.fcoeio_ilen = sizeof (param); 1629087SZhong.Wang@Sun.COM fcoeio.fcoeio_xfer = FCOEIO_XFER_WRITE; 1639087SZhong.Wang@Sun.COM fcoeio.fcoeio_ibuf = (uintptr_t)¶m; 1649087SZhong.Wang@Sun.COM 1659087SZhong.Wang@Sun.COM if (ioctl(fcoe_fd, FCOEIO_CMD, &fcoeio) != 0) { 1669087SZhong.Wang@Sun.COM switch (fcoeio.fcoeio_status) { 1679087SZhong.Wang@Sun.COM case FCOEIOE_INVAL_ARG: 1689087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_INVAL_ARG; 1699087SZhong.Wang@Sun.COM break; 1709087SZhong.Wang@Sun.COM 1719087SZhong.Wang@Sun.COM case FCOEIOE_BUSY: 1729087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_BUSY; 1739087SZhong.Wang@Sun.COM break; 1749087SZhong.Wang@Sun.COM 1759087SZhong.Wang@Sun.COM case FCOEIOE_ALREADY: 1769087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_ALREADY; 1779087SZhong.Wang@Sun.COM break; 1789087SZhong.Wang@Sun.COM 1799087SZhong.Wang@Sun.COM case FCOEIOE_PWWN_CONFLICTED: 1809087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_PWWN_CONFLICTED; 1819087SZhong.Wang@Sun.COM break; 1829087SZhong.Wang@Sun.COM 1839087SZhong.Wang@Sun.COM case FCOEIOE_NWWN_CONFLICTED: 1849087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_NWWN_CONFLICTED; 1859087SZhong.Wang@Sun.COM break; 1869087SZhong.Wang@Sun.COM 1879087SZhong.Wang@Sun.COM case FCOEIOE_CREATE_MAC: 1889087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_CREATE_MAC; 1899087SZhong.Wang@Sun.COM break; 1909087SZhong.Wang@Sun.COM 1919087SZhong.Wang@Sun.COM case FCOEIOE_OPEN_MAC: 1929087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_OPEN_MAC; 1939087SZhong.Wang@Sun.COM break; 1949087SZhong.Wang@Sun.COM 1959087SZhong.Wang@Sun.COM case FCOEIOE_CREATE_PORT: 1969087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_CREATE_PORT; 1979087SZhong.Wang@Sun.COM break; 1989087SZhong.Wang@Sun.COM 1999087SZhong.Wang@Sun.COM case FCOEIOE_NEED_JUMBO_FRAME: 2009087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_NEED_JUMBO_FRAME; 2019087SZhong.Wang@Sun.COM break; 2029087SZhong.Wang@Sun.COM 2039087SZhong.Wang@Sun.COM default: 2049087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR; 2059087SZhong.Wang@Sun.COM } 2069087SZhong.Wang@Sun.COM } else { 2079087SZhong.Wang@Sun.COM status = FCOE_STATUS_OK; 2089087SZhong.Wang@Sun.COM } 2099087SZhong.Wang@Sun.COM (void) close(fcoe_fd); 2109087SZhong.Wang@Sun.COM return (status); 2119087SZhong.Wang@Sun.COM } 2129087SZhong.Wang@Sun.COM 2139087SZhong.Wang@Sun.COM FCOE_STATUS 2149087SZhong.Wang@Sun.COM FCOE_DeletePort(const FCOE_UINT8 *macLinkName) 2159087SZhong.Wang@Sun.COM { 2169087SZhong.Wang@Sun.COM FCOE_STATUS status = FCOE_STATUS_OK; 2179087SZhong.Wang@Sun.COM int fcoe_fd; 2189087SZhong.Wang@Sun.COM fcoeio_t fcoeio; 219*9307Skelly.hu@Sun.COM dladm_handle_t handle; 220*9307Skelly.hu@Sun.COM datalink_id_t linkid; 221*9307Skelly.hu@Sun.COM fcoeio_delete_port_param_t fc_del_port; 2229087SZhong.Wang@Sun.COM 2239087SZhong.Wang@Sun.COM if (macLinkName == NULL) { 2249087SZhong.Wang@Sun.COM return (FCOE_STATUS_ERROR_INVAL_ARG); 2259087SZhong.Wang@Sun.COM } 2269087SZhong.Wang@Sun.COM 227*9307Skelly.hu@Sun.COM if (strlen((char *)macLinkName) > MAXLINKNAMELEN-1) { 2289087SZhong.Wang@Sun.COM return (FCOE_STATUS_ERROR_MAC_LEN); 2299087SZhong.Wang@Sun.COM } 230*9307Skelly.hu@Sun.COM if (dladm_open(&handle) != DLADM_STATUS_OK) { 231*9307Skelly.hu@Sun.COM return (FCOE_STATUS_ERROR); 232*9307Skelly.hu@Sun.COM } 233*9307Skelly.hu@Sun.COM 234*9307Skelly.hu@Sun.COM if (dladm_name2info(handle, (const char *)macLinkName, 235*9307Skelly.hu@Sun.COM &linkid, NULL, NULL, NULL) != DLADM_STATUS_OK) { 236*9307Skelly.hu@Sun.COM dladm_close(handle); 237*9307Skelly.hu@Sun.COM return (FCOE_STATUS_ERROR_GET_LINKINFO); 238*9307Skelly.hu@Sun.COM } 239*9307Skelly.hu@Sun.COM dladm_close(handle); 2409087SZhong.Wang@Sun.COM 2419087SZhong.Wang@Sun.COM if ((status = openFcoe(OPEN_FCOE, &fcoe_fd)) != FCOE_STATUS_OK) { 2429087SZhong.Wang@Sun.COM return (status); 2439087SZhong.Wang@Sun.COM } 2449087SZhong.Wang@Sun.COM 245*9307Skelly.hu@Sun.COM fc_del_port.fdp_mac_linkid = linkid; 246*9307Skelly.hu@Sun.COM 2479087SZhong.Wang@Sun.COM (void) memset(&fcoeio, 0, sizeof (fcoeio)); 2489087SZhong.Wang@Sun.COM fcoeio.fcoeio_cmd = FCOEIO_DELETE_FCOE_PORT; 2499087SZhong.Wang@Sun.COM 250*9307Skelly.hu@Sun.COM /* only 4 bytes here, need to change */ 251*9307Skelly.hu@Sun.COM fcoeio.fcoeio_ilen = sizeof (fcoeio_delete_port_param_t); 2529087SZhong.Wang@Sun.COM fcoeio.fcoeio_xfer = FCOEIO_XFER_WRITE; 253*9307Skelly.hu@Sun.COM fcoeio.fcoeio_ibuf = (uintptr_t)&fc_del_port; 2549087SZhong.Wang@Sun.COM 2559087SZhong.Wang@Sun.COM if (ioctl(fcoe_fd, FCOEIO_CMD, &fcoeio) != 0) { 2569087SZhong.Wang@Sun.COM switch (fcoeio.fcoeio_status) { 2579087SZhong.Wang@Sun.COM case FCOEIOE_INVAL_ARG: 2589087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_INVAL_ARG; 2599087SZhong.Wang@Sun.COM break; 2609087SZhong.Wang@Sun.COM 2619087SZhong.Wang@Sun.COM case FCOEIOE_BUSY: 2629087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_BUSY; 2639087SZhong.Wang@Sun.COM break; 2649087SZhong.Wang@Sun.COM 2659087SZhong.Wang@Sun.COM case FCOEIOE_ALREADY: 2669087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_ALREADY; 2679087SZhong.Wang@Sun.COM break; 2689087SZhong.Wang@Sun.COM 2699087SZhong.Wang@Sun.COM case FCOEIOE_MAC_NOT_FOUND: 2709087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_MAC_NOT_FOUND; 2719087SZhong.Wang@Sun.COM break; 2729087SZhong.Wang@Sun.COM 2739087SZhong.Wang@Sun.COM case FCOEIOE_OFFLINE_FAILURE: 2749087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_OFFLINE_DEV; 2759087SZhong.Wang@Sun.COM break; 2769087SZhong.Wang@Sun.COM 2779087SZhong.Wang@Sun.COM default: 2789087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR; 2799087SZhong.Wang@Sun.COM } 2809087SZhong.Wang@Sun.COM } else { 2819087SZhong.Wang@Sun.COM status = FCOE_STATUS_OK; 2829087SZhong.Wang@Sun.COM } 2839087SZhong.Wang@Sun.COM (void) close(fcoe_fd); 2849087SZhong.Wang@Sun.COM return (status); 2859087SZhong.Wang@Sun.COM } 2869087SZhong.Wang@Sun.COM 2879087SZhong.Wang@Sun.COM FCOE_STATUS 2889087SZhong.Wang@Sun.COM FCOE_GetPortList( 2899087SZhong.Wang@Sun.COM FCOE_UINT32 *port_num, 2909087SZhong.Wang@Sun.COM FCOE_PORT_ATTRIBUTE **portlist) 2919087SZhong.Wang@Sun.COM { 2929087SZhong.Wang@Sun.COM FCOE_STATUS status = FCOE_STATUS_OK; 293*9307Skelly.hu@Sun.COM int fcoe_fd; 2949087SZhong.Wang@Sun.COM fcoeio_t fcoeio; 295*9307Skelly.hu@Sun.COM fcoe_port_list_t *inportlist = NULL; 2969087SZhong.Wang@Sun.COM FCOE_PORT_ATTRIBUTE *outportlist = NULL; 297*9307Skelly.hu@Sun.COM int i; 298*9307Skelly.hu@Sun.COM int size = 64; /* default first attempt */ 299*9307Skelly.hu@Sun.COM int retry = 0; 300*9307Skelly.hu@Sun.COM int bufsize; 301*9307Skelly.hu@Sun.COM dladm_handle_t handle; 302*9307Skelly.hu@Sun.COM char mac_name[MAXLINKNAMELEN]; 3039087SZhong.Wang@Sun.COM 3049087SZhong.Wang@Sun.COM if (port_num == NULL || portlist == NULL) { 3059087SZhong.Wang@Sun.COM return (FCOE_STATUS_ERROR_INVAL_ARG); 3069087SZhong.Wang@Sun.COM } 3079087SZhong.Wang@Sun.COM *port_num = 0; 3089087SZhong.Wang@Sun.COM 3099087SZhong.Wang@Sun.COM if ((status = openFcoe(OPEN_FCOE, &fcoe_fd)) != FCOE_STATUS_OK) { 3109087SZhong.Wang@Sun.COM return (status); 3119087SZhong.Wang@Sun.COM } 3129087SZhong.Wang@Sun.COM 3139087SZhong.Wang@Sun.COM /* Get fcoe port list */ 3149087SZhong.Wang@Sun.COM (void) memset(&fcoeio, 0, sizeof (fcoeio)); 3159087SZhong.Wang@Sun.COM retry = 0; 3169087SZhong.Wang@Sun.COM 3179087SZhong.Wang@Sun.COM do { 3189087SZhong.Wang@Sun.COM bufsize = sizeof (fcoe_port_instance_t) * (size - 1) + 3199087SZhong.Wang@Sun.COM sizeof (fcoe_port_list_t); 3209087SZhong.Wang@Sun.COM inportlist = (fcoe_port_list_t *)malloc(bufsize); 3219087SZhong.Wang@Sun.COM fcoeio.fcoeio_cmd = FCOEIO_GET_FCOE_PORT_LIST; 3229087SZhong.Wang@Sun.COM fcoeio.fcoeio_olen = bufsize; 3239087SZhong.Wang@Sun.COM fcoeio.fcoeio_xfer = FCOEIO_XFER_READ; 3249087SZhong.Wang@Sun.COM fcoeio.fcoeio_obuf = (uintptr_t)inportlist; 3259087SZhong.Wang@Sun.COM 3269087SZhong.Wang@Sun.COM if (ioctl(fcoe_fd, FCOEIO_CMD, &fcoeio) != 0) { 3279087SZhong.Wang@Sun.COM if (fcoeio.fcoeio_status == FCOEIOE_MORE_DATA) { 3289087SZhong.Wang@Sun.COM size = inportlist->numPorts; 3299087SZhong.Wang@Sun.COM } 3309087SZhong.Wang@Sun.COM free(inportlist); 3319087SZhong.Wang@Sun.COM switch (fcoeio.fcoeio_status) { 3329087SZhong.Wang@Sun.COM case FCOEIOE_INVAL_ARG: 3339087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_INVAL_ARG; 3349087SZhong.Wang@Sun.COM (void) close(fcoe_fd); 3359087SZhong.Wang@Sun.COM return (status); 3369087SZhong.Wang@Sun.COM 3379087SZhong.Wang@Sun.COM case FCOEIOE_BUSY: 3389087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_BUSY; 3399087SZhong.Wang@Sun.COM retry++; 3409087SZhong.Wang@Sun.COM break; 3419087SZhong.Wang@Sun.COM 3429087SZhong.Wang@Sun.COM case FCOEIOE_MORE_DATA: 3439087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR_MORE_DATA; 3449087SZhong.Wang@Sun.COM retry++; 3459087SZhong.Wang@Sun.COM default: 3469087SZhong.Wang@Sun.COM status = FCOE_STATUS_ERROR; 3479087SZhong.Wang@Sun.COM } 3489087SZhong.Wang@Sun.COM } else { 3499087SZhong.Wang@Sun.COM status = FCOE_STATUS_OK; 3509087SZhong.Wang@Sun.COM break; 3519087SZhong.Wang@Sun.COM } 3529087SZhong.Wang@Sun.COM } while (retry <= 3 && status != FCOE_STATUS_OK); 3539087SZhong.Wang@Sun.COM 354*9307Skelly.hu@Sun.COM if (status == FCOE_STATUS_OK && inportlist->numPorts > 0) { 355*9307Skelly.hu@Sun.COM if (dladm_open(&handle) != DLADM_STATUS_OK) { 356*9307Skelly.hu@Sun.COM handle = NULL; 357*9307Skelly.hu@Sun.COM } 358*9307Skelly.hu@Sun.COM 3599087SZhong.Wang@Sun.COM outportlist = (PFCOE_PORT_ATTRIBUTE) 3609087SZhong.Wang@Sun.COM malloc(sizeof (FCOE_PORT_ATTRIBUTE) * inportlist->numPorts); 3619087SZhong.Wang@Sun.COM 3629087SZhong.Wang@Sun.COM for (i = 0; i < inportlist->numPorts; i++) { 3639087SZhong.Wang@Sun.COM fcoe_port_instance_t *pi = &inportlist->ports[i]; 3649087SZhong.Wang@Sun.COM FCOE_PORT_ATTRIBUTE *po = &outportlist[i]; 3659087SZhong.Wang@Sun.COM bcopy(pi->fpi_pwwn, &po->port_wwn, 8); 366*9307Skelly.hu@Sun.COM 367*9307Skelly.hu@Sun.COM if (handle == NULL || 368*9307Skelly.hu@Sun.COM dladm_datalink_id2info(handle, pi->fpi_mac_linkid, 369*9307Skelly.hu@Sun.COM NULL, NULL, NULL, mac_name, sizeof (mac_name)) 370*9307Skelly.hu@Sun.COM != DLADM_STATUS_OK) { 371*9307Skelly.hu@Sun.COM (void) strcpy((char *)po->mac_link_name, 372*9307Skelly.hu@Sun.COM "<unknown>"); 373*9307Skelly.hu@Sun.COM } else { 374*9307Skelly.hu@Sun.COM (void) strcpy((char *)po->mac_link_name, 375*9307Skelly.hu@Sun.COM mac_name); 376*9307Skelly.hu@Sun.COM } 3779087SZhong.Wang@Sun.COM bcopy(pi->fpi_mac_factory_addr, 3789087SZhong.Wang@Sun.COM po->mac_factory_addr, 6); 3799087SZhong.Wang@Sun.COM bcopy(pi->fpi_mac_current_addr, 3809087SZhong.Wang@Sun.COM po->mac_current_addr, 6); 3819087SZhong.Wang@Sun.COM po->port_type = (FCOE_UINT8)pi->fpi_port_type; 3829087SZhong.Wang@Sun.COM po->mtu_size = pi->fpi_mtu_size; 3839087SZhong.Wang@Sun.COM po->mac_promisc = pi->fpi_mac_promisc; 3849087SZhong.Wang@Sun.COM } 385*9307Skelly.hu@Sun.COM 386*9307Skelly.hu@Sun.COM if (handle != NULL) { 387*9307Skelly.hu@Sun.COM dladm_close(handle); 388*9307Skelly.hu@Sun.COM } 3899087SZhong.Wang@Sun.COM *port_num = inportlist->numPorts; 3909087SZhong.Wang@Sun.COM *portlist = outportlist; 3919087SZhong.Wang@Sun.COM free(inportlist); 3929087SZhong.Wang@Sun.COM } else { 3939087SZhong.Wang@Sun.COM *port_num = 0; 3949087SZhong.Wang@Sun.COM *portlist = NULL; 3959087SZhong.Wang@Sun.COM } 3969087SZhong.Wang@Sun.COM (void) close(fcoe_fd); 3979087SZhong.Wang@Sun.COM return (status); 3989087SZhong.Wang@Sun.COM } 399