12a8164dfSZhong Wang /* 22a8164dfSZhong Wang * CDDL HEADER START 32a8164dfSZhong Wang * 42a8164dfSZhong Wang * The contents of this file are subject to the terms of the 52a8164dfSZhong Wang * Common Development and Distribution License (the "License"). 62a8164dfSZhong Wang * You may not use this file except in compliance with the License. 72a8164dfSZhong Wang * 82a8164dfSZhong Wang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92a8164dfSZhong Wang * or http://www.opensolaris.org/os/licensing. 102a8164dfSZhong Wang * See the License for the specific language governing permissions 112a8164dfSZhong Wang * and limitations under the License. 122a8164dfSZhong Wang * 132a8164dfSZhong Wang * When distributing Covered Code, include this CDDL HEADER in each 142a8164dfSZhong Wang * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152a8164dfSZhong Wang * If applicable, add the following below this CDDL HEADER, with the 162a8164dfSZhong Wang * fields enclosed by brackets "[]" replaced with your own identifying 172a8164dfSZhong Wang * information: Portions Copyright [yyyy] [name of copyright owner] 182a8164dfSZhong Wang * 192a8164dfSZhong Wang * CDDL HEADER END 202a8164dfSZhong Wang */ 212a8164dfSZhong Wang /* 222a8164dfSZhong Wang * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 232a8164dfSZhong Wang * Use is subject to license terms. 242a8164dfSZhong Wang */ 252a8164dfSZhong Wang 262a8164dfSZhong Wang #include <stdlib.h> 272a8164dfSZhong Wang #include <stdio.h> 282a8164dfSZhong Wang #include <wchar.h> 292a8164dfSZhong Wang #include <strings.h> 302a8164dfSZhong Wang #include <sys/types.h> 312a8164dfSZhong Wang #include <sys/stat.h> 322a8164dfSZhong Wang #include <fcntl.h> 332a8164dfSZhong Wang #include <unistd.h> 342a8164dfSZhong Wang #include <libintl.h> 352a8164dfSZhong Wang #include <errno.h> 362a8164dfSZhong Wang #include <string.h> 372a8164dfSZhong Wang #include <assert.h> 382a8164dfSZhong Wang #include <syslog.h> 392a8164dfSZhong Wang #include <libfcoe.h> 40*d4401b99SKelly Hu #include <libdllink.h> 412a8164dfSZhong Wang #include <fcoeio.h> 422a8164dfSZhong Wang 432a8164dfSZhong Wang #define FCOE_DEV_PATH "/devices/fcoe:admin" 442a8164dfSZhong Wang 452a8164dfSZhong Wang #define OPEN_FCOE 0 462a8164dfSZhong Wang #define OPEN_EXCL_FCOE O_EXCL 472a8164dfSZhong Wang 482a8164dfSZhong Wang /* 492a8164dfSZhong Wang * Open for fcoe module 502a8164dfSZhong Wang * 512a8164dfSZhong Wang * flag - open flag (OPEN_FCOE, OPEN_EXCL_FCOE) 522a8164dfSZhong Wang * fd - pointer to integer. On success, contains the fcoe file descriptor 532a8164dfSZhong Wang */ 542a8164dfSZhong Wang static int 552a8164dfSZhong Wang openFcoe(int flag, int *fd) 562a8164dfSZhong Wang { 572a8164dfSZhong Wang int ret = FCOE_STATUS_ERROR; 582a8164dfSZhong Wang 592a8164dfSZhong Wang if ((*fd = open(FCOE_DEV_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 602a8164dfSZhong Wang ret = FCOE_STATUS_OK; 612a8164dfSZhong Wang } else { 622a8164dfSZhong Wang if (errno == EPERM || errno == EACCES) { 632a8164dfSZhong Wang ret = FCOE_STATUS_ERROR_PERM; 642a8164dfSZhong Wang } else { 652a8164dfSZhong Wang ret = FCOE_STATUS_ERROR_OPEN_DEV; 662a8164dfSZhong Wang } 672a8164dfSZhong Wang syslog(LOG_DEBUG, "openFcoe:open failure:%s:errno(%d)", 682a8164dfSZhong Wang FCOE_DEV_PATH, errno); 692a8164dfSZhong Wang } 702a8164dfSZhong Wang 712a8164dfSZhong Wang return (ret); 722a8164dfSZhong Wang } 732a8164dfSZhong Wang 742a8164dfSZhong Wang static int 752a8164dfSZhong Wang isWWNZero(FCOE_PORT_WWN portwwn) 762a8164dfSZhong Wang { 772a8164dfSZhong Wang int i; 782a8164dfSZhong Wang int size = sizeof (FCOE_PORT_WWN); 792a8164dfSZhong Wang 802a8164dfSZhong Wang for (i = 0; i < size; i++) { 812a8164dfSZhong Wang if (portwwn.wwn[i] != 0) { 822a8164dfSZhong Wang return (0); 832a8164dfSZhong Wang } 842a8164dfSZhong Wang } 852a8164dfSZhong Wang return (1); 862a8164dfSZhong Wang } 872a8164dfSZhong Wang 882a8164dfSZhong Wang FCOE_STATUS 892a8164dfSZhong Wang FCOE_CreatePort( 902a8164dfSZhong Wang const FCOE_UINT8 *macLinkName, 912a8164dfSZhong Wang FCOE_UINT8 portType, 922a8164dfSZhong Wang FCOE_PORT_WWN pwwn, 932a8164dfSZhong Wang FCOE_PORT_WWN nwwn, 942a8164dfSZhong Wang FCOE_UINT8 promiscuous) 952a8164dfSZhong Wang { 962a8164dfSZhong Wang FCOE_STATUS status = FCOE_STATUS_OK; 972a8164dfSZhong Wang int fcoe_fd; 982a8164dfSZhong Wang fcoeio_t fcoeio; 992a8164dfSZhong Wang fcoeio_create_port_param_t param; 100*d4401b99SKelly Hu dladm_handle_t handle; 101*d4401b99SKelly Hu datalink_id_t linkid; 102*d4401b99SKelly Hu datalink_class_t class; 1032a8164dfSZhong Wang 1042a8164dfSZhong Wang bzero(¶m, sizeof (fcoeio_create_port_param_t)); 1052a8164dfSZhong Wang 1062a8164dfSZhong Wang if (macLinkName == NULL) { 1072a8164dfSZhong Wang return (FCOE_STATUS_ERROR_INVAL_ARG); 1082a8164dfSZhong Wang } 1092a8164dfSZhong Wang 110*d4401b99SKelly Hu if (strlen((char *)macLinkName) > MAXLINKNAMELEN-1) { 111*d4401b99SKelly Hu return (FCOE_STATUS_ERROR_MAC_LEN); 112*d4401b99SKelly Hu } 113*d4401b99SKelly Hu 114*d4401b99SKelly Hu if (dladm_open(&handle) != DLADM_STATUS_OK) { 115*d4401b99SKelly Hu return (FCOE_STATUS_ERROR); 116*d4401b99SKelly Hu } 117*d4401b99SKelly Hu 118*d4401b99SKelly Hu if (dladm_name2info(handle, (const char *)macLinkName, 119*d4401b99SKelly Hu &linkid, NULL, &class, NULL) != DLADM_STATUS_OK) { 120*d4401b99SKelly Hu dladm_close(handle); 121*d4401b99SKelly Hu return (FCOE_STATUS_ERROR_GET_LINKINFO); 122*d4401b99SKelly Hu } 123*d4401b99SKelly Hu dladm_close(handle); 124*d4401b99SKelly Hu 125*d4401b99SKelly Hu if (class != DATALINK_CLASS_PHYS) { 126*d4401b99SKelly Hu return (FCOE_STATUS_ERROR_CLASS_UNSUPPORT); 127*d4401b99SKelly Hu } 128*d4401b99SKelly Hu 1292a8164dfSZhong Wang if (portType != FCOE_PORTTYPE_INITIATOR && 1302a8164dfSZhong Wang portType != FCOE_PORTTYPE_TARGET) { 1312a8164dfSZhong Wang return (FCOE_STATUS_ERROR_INVAL_ARG); 1322a8164dfSZhong Wang } 1332a8164dfSZhong Wang 1342a8164dfSZhong Wang if (!isWWNZero(pwwn)) { 1352a8164dfSZhong Wang param.fcp_pwwn_provided = 1; 1362a8164dfSZhong Wang bcopy(pwwn.wwn, param.fcp_pwwn, 8); 1372a8164dfSZhong Wang } 1382a8164dfSZhong Wang 1392a8164dfSZhong Wang if (!isWWNZero(nwwn)) { 1402a8164dfSZhong Wang param.fcp_nwwn_provided = 1; 1412a8164dfSZhong Wang bcopy(nwwn.wwn, param.fcp_nwwn, 8); 1422a8164dfSZhong Wang } 1432a8164dfSZhong Wang 1442a8164dfSZhong Wang if (param.fcp_pwwn_provided == 1 && 1452a8164dfSZhong Wang param.fcp_nwwn_provided == 1 && 1462a8164dfSZhong Wang bcmp(&pwwn, &nwwn, 8) == 0) { 1472a8164dfSZhong Wang return (FCOE_STATUS_ERROR_WWN_SAME); 1482a8164dfSZhong Wang } 1492a8164dfSZhong Wang 1502a8164dfSZhong Wang param.fcp_force_promisc = promiscuous; 151*d4401b99SKelly Hu param.fcp_mac_linkid = linkid; 1522a8164dfSZhong Wang param.fcp_port_type = (fcoe_cli_type_t)portType; 1532a8164dfSZhong Wang 1542a8164dfSZhong Wang if ((status = openFcoe(OPEN_FCOE, &fcoe_fd)) != FCOE_STATUS_OK) { 1552a8164dfSZhong Wang return (status); 1562a8164dfSZhong Wang } 1572a8164dfSZhong Wang 1582a8164dfSZhong Wang (void) memset(&fcoeio, 0, sizeof (fcoeio)); 1592a8164dfSZhong Wang fcoeio.fcoeio_cmd = FCOEIO_CREATE_FCOE_PORT; 1602a8164dfSZhong Wang 1612a8164dfSZhong Wang fcoeio.fcoeio_ilen = sizeof (param); 1622a8164dfSZhong Wang fcoeio.fcoeio_xfer = FCOEIO_XFER_WRITE; 1632a8164dfSZhong Wang fcoeio.fcoeio_ibuf = (uintptr_t)¶m; 1642a8164dfSZhong Wang 1652a8164dfSZhong Wang if (ioctl(fcoe_fd, FCOEIO_CMD, &fcoeio) != 0) { 1662a8164dfSZhong Wang switch (fcoeio.fcoeio_status) { 1672a8164dfSZhong Wang case FCOEIOE_INVAL_ARG: 1682a8164dfSZhong Wang status = FCOE_STATUS_ERROR_INVAL_ARG; 1692a8164dfSZhong Wang break; 1702a8164dfSZhong Wang 1712a8164dfSZhong Wang case FCOEIOE_BUSY: 1722a8164dfSZhong Wang status = FCOE_STATUS_ERROR_BUSY; 1732a8164dfSZhong Wang break; 1742a8164dfSZhong Wang 1752a8164dfSZhong Wang case FCOEIOE_ALREADY: 1762a8164dfSZhong Wang status = FCOE_STATUS_ERROR_ALREADY; 1772a8164dfSZhong Wang break; 1782a8164dfSZhong Wang 1792a8164dfSZhong Wang case FCOEIOE_PWWN_CONFLICTED: 1802a8164dfSZhong Wang status = FCOE_STATUS_ERROR_PWWN_CONFLICTED; 1812a8164dfSZhong Wang break; 1822a8164dfSZhong Wang 1832a8164dfSZhong Wang case FCOEIOE_NWWN_CONFLICTED: 1842a8164dfSZhong Wang status = FCOE_STATUS_ERROR_NWWN_CONFLICTED; 1852a8164dfSZhong Wang break; 1862a8164dfSZhong Wang 1872a8164dfSZhong Wang case FCOEIOE_CREATE_MAC: 1882a8164dfSZhong Wang status = FCOE_STATUS_ERROR_CREATE_MAC; 1892a8164dfSZhong Wang break; 1902a8164dfSZhong Wang 1912a8164dfSZhong Wang case FCOEIOE_OPEN_MAC: 1922a8164dfSZhong Wang status = FCOE_STATUS_ERROR_OPEN_MAC; 1932a8164dfSZhong Wang break; 1942a8164dfSZhong Wang 1952a8164dfSZhong Wang case FCOEIOE_CREATE_PORT: 1962a8164dfSZhong Wang status = FCOE_STATUS_ERROR_CREATE_PORT; 1972a8164dfSZhong Wang break; 1982a8164dfSZhong Wang 1992a8164dfSZhong Wang case FCOEIOE_NEED_JUMBO_FRAME: 2002a8164dfSZhong Wang status = FCOE_STATUS_ERROR_NEED_JUMBO_FRAME; 2012a8164dfSZhong Wang break; 2022a8164dfSZhong Wang 2032a8164dfSZhong Wang default: 2042a8164dfSZhong Wang status = FCOE_STATUS_ERROR; 2052a8164dfSZhong Wang } 2062a8164dfSZhong Wang } else { 2072a8164dfSZhong Wang status = FCOE_STATUS_OK; 2082a8164dfSZhong Wang } 2092a8164dfSZhong Wang (void) close(fcoe_fd); 2102a8164dfSZhong Wang return (status); 2112a8164dfSZhong Wang } 2122a8164dfSZhong Wang 2132a8164dfSZhong Wang FCOE_STATUS 2142a8164dfSZhong Wang FCOE_DeletePort(const FCOE_UINT8 *macLinkName) 2152a8164dfSZhong Wang { 2162a8164dfSZhong Wang FCOE_STATUS status = FCOE_STATUS_OK; 2172a8164dfSZhong Wang int fcoe_fd; 2182a8164dfSZhong Wang fcoeio_t fcoeio; 219*d4401b99SKelly Hu dladm_handle_t handle; 220*d4401b99SKelly Hu datalink_id_t linkid; 221*d4401b99SKelly Hu fcoeio_delete_port_param_t fc_del_port; 2222a8164dfSZhong Wang 2232a8164dfSZhong Wang if (macLinkName == NULL) { 2242a8164dfSZhong Wang return (FCOE_STATUS_ERROR_INVAL_ARG); 2252a8164dfSZhong Wang } 2262a8164dfSZhong Wang 227*d4401b99SKelly Hu if (strlen((char *)macLinkName) > MAXLINKNAMELEN-1) { 2282a8164dfSZhong Wang return (FCOE_STATUS_ERROR_MAC_LEN); 2292a8164dfSZhong Wang } 230*d4401b99SKelly Hu if (dladm_open(&handle) != DLADM_STATUS_OK) { 231*d4401b99SKelly Hu return (FCOE_STATUS_ERROR); 232*d4401b99SKelly Hu } 233*d4401b99SKelly Hu 234*d4401b99SKelly Hu if (dladm_name2info(handle, (const char *)macLinkName, 235*d4401b99SKelly Hu &linkid, NULL, NULL, NULL) != DLADM_STATUS_OK) { 236*d4401b99SKelly Hu dladm_close(handle); 237*d4401b99SKelly Hu return (FCOE_STATUS_ERROR_GET_LINKINFO); 238*d4401b99SKelly Hu } 239*d4401b99SKelly Hu dladm_close(handle); 2402a8164dfSZhong Wang 2412a8164dfSZhong Wang if ((status = openFcoe(OPEN_FCOE, &fcoe_fd)) != FCOE_STATUS_OK) { 2422a8164dfSZhong Wang return (status); 2432a8164dfSZhong Wang } 2442a8164dfSZhong Wang 245*d4401b99SKelly Hu fc_del_port.fdp_mac_linkid = linkid; 246*d4401b99SKelly Hu 2472a8164dfSZhong Wang (void) memset(&fcoeio, 0, sizeof (fcoeio)); 2482a8164dfSZhong Wang fcoeio.fcoeio_cmd = FCOEIO_DELETE_FCOE_PORT; 2492a8164dfSZhong Wang 250*d4401b99SKelly Hu /* only 4 bytes here, need to change */ 251*d4401b99SKelly Hu fcoeio.fcoeio_ilen = sizeof (fcoeio_delete_port_param_t); 2522a8164dfSZhong Wang fcoeio.fcoeio_xfer = FCOEIO_XFER_WRITE; 253*d4401b99SKelly Hu fcoeio.fcoeio_ibuf = (uintptr_t)&fc_del_port; 2542a8164dfSZhong Wang 2552a8164dfSZhong Wang if (ioctl(fcoe_fd, FCOEIO_CMD, &fcoeio) != 0) { 2562a8164dfSZhong Wang switch (fcoeio.fcoeio_status) { 2572a8164dfSZhong Wang case FCOEIOE_INVAL_ARG: 2582a8164dfSZhong Wang status = FCOE_STATUS_ERROR_INVAL_ARG; 2592a8164dfSZhong Wang break; 2602a8164dfSZhong Wang 2612a8164dfSZhong Wang case FCOEIOE_BUSY: 2622a8164dfSZhong Wang status = FCOE_STATUS_ERROR_BUSY; 2632a8164dfSZhong Wang break; 2642a8164dfSZhong Wang 2652a8164dfSZhong Wang case FCOEIOE_ALREADY: 2662a8164dfSZhong Wang status = FCOE_STATUS_ERROR_ALREADY; 2672a8164dfSZhong Wang break; 2682a8164dfSZhong Wang 2692a8164dfSZhong Wang case FCOEIOE_MAC_NOT_FOUND: 2702a8164dfSZhong Wang status = FCOE_STATUS_ERROR_MAC_NOT_FOUND; 2712a8164dfSZhong Wang break; 2722a8164dfSZhong Wang 2732a8164dfSZhong Wang case FCOEIOE_OFFLINE_FAILURE: 2742a8164dfSZhong Wang status = FCOE_STATUS_ERROR_OFFLINE_DEV; 2752a8164dfSZhong Wang break; 2762a8164dfSZhong Wang 2772a8164dfSZhong Wang default: 2782a8164dfSZhong Wang status = FCOE_STATUS_ERROR; 2792a8164dfSZhong Wang } 2802a8164dfSZhong Wang } else { 2812a8164dfSZhong Wang status = FCOE_STATUS_OK; 2822a8164dfSZhong Wang } 2832a8164dfSZhong Wang (void) close(fcoe_fd); 2842a8164dfSZhong Wang return (status); 2852a8164dfSZhong Wang } 2862a8164dfSZhong Wang 2872a8164dfSZhong Wang FCOE_STATUS 2882a8164dfSZhong Wang FCOE_GetPortList( 2892a8164dfSZhong Wang FCOE_UINT32 *port_num, 2902a8164dfSZhong Wang FCOE_PORT_ATTRIBUTE **portlist) 2912a8164dfSZhong Wang { 2922a8164dfSZhong Wang FCOE_STATUS status = FCOE_STATUS_OK; 2932a8164dfSZhong Wang int fcoe_fd; 2942a8164dfSZhong Wang fcoeio_t fcoeio; 2952a8164dfSZhong Wang fcoe_port_list_t *inportlist = NULL; 2962a8164dfSZhong Wang FCOE_PORT_ATTRIBUTE *outportlist = NULL; 2972a8164dfSZhong Wang int i; 2982a8164dfSZhong Wang int size = 64; /* default first attempt */ 2992a8164dfSZhong Wang int retry = 0; 3002a8164dfSZhong Wang int bufsize; 301*d4401b99SKelly Hu dladm_handle_t handle; 302*d4401b99SKelly Hu char mac_name[MAXLINKNAMELEN]; 3032a8164dfSZhong Wang 3042a8164dfSZhong Wang if (port_num == NULL || portlist == NULL) { 3052a8164dfSZhong Wang return (FCOE_STATUS_ERROR_INVAL_ARG); 3062a8164dfSZhong Wang } 3072a8164dfSZhong Wang *port_num = 0; 3082a8164dfSZhong Wang 3092a8164dfSZhong Wang if ((status = openFcoe(OPEN_FCOE, &fcoe_fd)) != FCOE_STATUS_OK) { 3102a8164dfSZhong Wang return (status); 3112a8164dfSZhong Wang } 3122a8164dfSZhong Wang 3132a8164dfSZhong Wang /* Get fcoe port list */ 3142a8164dfSZhong Wang (void) memset(&fcoeio, 0, sizeof (fcoeio)); 3152a8164dfSZhong Wang retry = 0; 3162a8164dfSZhong Wang 3172a8164dfSZhong Wang do { 3182a8164dfSZhong Wang bufsize = sizeof (fcoe_port_instance_t) * (size - 1) + 3192a8164dfSZhong Wang sizeof (fcoe_port_list_t); 3202a8164dfSZhong Wang inportlist = (fcoe_port_list_t *)malloc(bufsize); 3212a8164dfSZhong Wang fcoeio.fcoeio_cmd = FCOEIO_GET_FCOE_PORT_LIST; 3222a8164dfSZhong Wang fcoeio.fcoeio_olen = bufsize; 3232a8164dfSZhong Wang fcoeio.fcoeio_xfer = FCOEIO_XFER_READ; 3242a8164dfSZhong Wang fcoeio.fcoeio_obuf = (uintptr_t)inportlist; 3252a8164dfSZhong Wang 3262a8164dfSZhong Wang if (ioctl(fcoe_fd, FCOEIO_CMD, &fcoeio) != 0) { 3272a8164dfSZhong Wang if (fcoeio.fcoeio_status == FCOEIOE_MORE_DATA) { 3282a8164dfSZhong Wang size = inportlist->numPorts; 3292a8164dfSZhong Wang } 3302a8164dfSZhong Wang free(inportlist); 3312a8164dfSZhong Wang switch (fcoeio.fcoeio_status) { 3322a8164dfSZhong Wang case FCOEIOE_INVAL_ARG: 3332a8164dfSZhong Wang status = FCOE_STATUS_ERROR_INVAL_ARG; 3342a8164dfSZhong Wang (void) close(fcoe_fd); 3352a8164dfSZhong Wang return (status); 3362a8164dfSZhong Wang 3372a8164dfSZhong Wang case FCOEIOE_BUSY: 3382a8164dfSZhong Wang status = FCOE_STATUS_ERROR_BUSY; 3392a8164dfSZhong Wang retry++; 3402a8164dfSZhong Wang break; 3412a8164dfSZhong Wang 3422a8164dfSZhong Wang case FCOEIOE_MORE_DATA: 3432a8164dfSZhong Wang status = FCOE_STATUS_ERROR_MORE_DATA; 3442a8164dfSZhong Wang retry++; 3452a8164dfSZhong Wang default: 3462a8164dfSZhong Wang status = FCOE_STATUS_ERROR; 3472a8164dfSZhong Wang } 3482a8164dfSZhong Wang } else { 3492a8164dfSZhong Wang status = FCOE_STATUS_OK; 3502a8164dfSZhong Wang break; 3512a8164dfSZhong Wang } 3522a8164dfSZhong Wang } while (retry <= 3 && status != FCOE_STATUS_OK); 3532a8164dfSZhong Wang 354*d4401b99SKelly Hu if (status == FCOE_STATUS_OK && inportlist->numPorts > 0) { 355*d4401b99SKelly Hu if (dladm_open(&handle) != DLADM_STATUS_OK) { 356*d4401b99SKelly Hu handle = NULL; 357*d4401b99SKelly Hu } 358*d4401b99SKelly Hu 3592a8164dfSZhong Wang outportlist = (PFCOE_PORT_ATTRIBUTE) 3602a8164dfSZhong Wang malloc(sizeof (FCOE_PORT_ATTRIBUTE) * inportlist->numPorts); 3612a8164dfSZhong Wang 3622a8164dfSZhong Wang for (i = 0; i < inportlist->numPorts; i++) { 3632a8164dfSZhong Wang fcoe_port_instance_t *pi = &inportlist->ports[i]; 3642a8164dfSZhong Wang FCOE_PORT_ATTRIBUTE *po = &outportlist[i]; 3652a8164dfSZhong Wang bcopy(pi->fpi_pwwn, &po->port_wwn, 8); 366*d4401b99SKelly Hu 367*d4401b99SKelly Hu if (handle == NULL || 368*d4401b99SKelly Hu dladm_datalink_id2info(handle, pi->fpi_mac_linkid, 369*d4401b99SKelly Hu NULL, NULL, NULL, mac_name, sizeof (mac_name)) 370*d4401b99SKelly Hu != DLADM_STATUS_OK) { 371*d4401b99SKelly Hu (void) strcpy((char *)po->mac_link_name, 372*d4401b99SKelly Hu "<unknown>"); 373*d4401b99SKelly Hu } else { 374*d4401b99SKelly Hu (void) strcpy((char *)po->mac_link_name, 375*d4401b99SKelly Hu mac_name); 376*d4401b99SKelly Hu } 3772a8164dfSZhong Wang bcopy(pi->fpi_mac_factory_addr, 3782a8164dfSZhong Wang po->mac_factory_addr, 6); 3792a8164dfSZhong Wang bcopy(pi->fpi_mac_current_addr, 3802a8164dfSZhong Wang po->mac_current_addr, 6); 3812a8164dfSZhong Wang po->port_type = (FCOE_UINT8)pi->fpi_port_type; 3822a8164dfSZhong Wang po->mtu_size = pi->fpi_mtu_size; 3832a8164dfSZhong Wang po->mac_promisc = pi->fpi_mac_promisc; 3842a8164dfSZhong Wang } 385*d4401b99SKelly Hu 386*d4401b99SKelly Hu if (handle != NULL) { 387*d4401b99SKelly Hu dladm_close(handle); 388*d4401b99SKelly Hu } 3892a8164dfSZhong Wang *port_num = inportlist->numPorts; 3902a8164dfSZhong Wang *portlist = outportlist; 3912a8164dfSZhong Wang free(inportlist); 3922a8164dfSZhong Wang } else { 3932a8164dfSZhong Wang *port_num = 0; 3942a8164dfSZhong Wang *portlist = NULL; 3952a8164dfSZhong Wang } 3962a8164dfSZhong Wang (void) close(fcoe_fd); 3972a8164dfSZhong Wang return (status); 3982a8164dfSZhong Wang } 399