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 <sys/stat.h> 279087SZhong.Wang@Sun.COM #include <sys/types.h> 289087SZhong.Wang@Sun.COM #include <netinet/in.h> 299087SZhong.Wang@Sun.COM #include <sys/inttypes.h> 309087SZhong.Wang@Sun.COM #include <sys/strsun.h> 319087SZhong.Wang@Sun.COM #include <sys/mac_client.h> 329087SZhong.Wang@Sun.COM 339087SZhong.Wang@Sun.COM /* 349087SZhong.Wang@Sun.COM * FCoE header files 359087SZhong.Wang@Sun.COM */ 369087SZhong.Wang@Sun.COM #include <sys/fcoe/fcoeio.h> 379087SZhong.Wang@Sun.COM #include <sys/fcoe/fcoe_common.h> 389087SZhong.Wang@Sun.COM 399087SZhong.Wang@Sun.COM /* 409087SZhong.Wang@Sun.COM * Driver's own header files 419087SZhong.Wang@Sun.COM */ 429087SZhong.Wang@Sun.COM #include <fcoe.h> 439087SZhong.Wang@Sun.COM #include <fcoe_eth.h> 449087SZhong.Wang@Sun.COM #include <fcoe_fc.h> 459087SZhong.Wang@Sun.COM 469087SZhong.Wang@Sun.COM static void fcoe_rx(void *arg, mac_resource_handle_t mrh, 479087SZhong.Wang@Sun.COM mblk_t *mp, boolean_t loopback); 489087SZhong.Wang@Sun.COM static void fcoe_mac_notify(void *arg, mac_notify_type_t type); 499087SZhong.Wang@Sun.COM 509087SZhong.Wang@Sun.COM /* 519087SZhong.Wang@Sun.COM * Global variable definitions 529087SZhong.Wang@Sun.COM */ 539087SZhong.Wang@Sun.COM 549087SZhong.Wang@Sun.COM /* 559087SZhong.Wang@Sun.COM * Internal tunable, used to enable p2p mode 569087SZhong.Wang@Sun.COM */ 579087SZhong.Wang@Sun.COM volatile uint32_t fcoe_enable_p2pmode = 0; 589087SZhong.Wang@Sun.COM 599087SZhong.Wang@Sun.COM int 609087SZhong.Wang@Sun.COM fcoe_open_mac(fcoe_mac_t *mac, int force_promisc, fcoeio_stat_t *err_detail) 619087SZhong.Wang@Sun.COM { 629087SZhong.Wang@Sun.COM int ret; 639087SZhong.Wang@Sun.COM int fcoe_ret; 649087SZhong.Wang@Sun.COM char cli_name[MAXNAMELEN]; 659087SZhong.Wang@Sun.COM mac_diag_t diag; 669087SZhong.Wang@Sun.COM uint16_t fm_open_flag = 0; 679087SZhong.Wang@Sun.COM 689087SZhong.Wang@Sun.COM *err_detail = 0; 699087SZhong.Wang@Sun.COM 709087SZhong.Wang@Sun.COM /* 719087SZhong.Wang@Sun.COM * Open MAC interface 729087SZhong.Wang@Sun.COM */ 73*9307Skelly.hu@Sun.COM ret = mac_open_by_linkid(mac->fm_linkid, &mac->fm_handle); 749087SZhong.Wang@Sun.COM if (ret != 0) { 75*9307Skelly.hu@Sun.COM FCOE_LOG("fcoe", "mac_open_by_linkname %d failed %x", 76*9307Skelly.hu@Sun.COM mac->fm_linkid, ret); 779087SZhong.Wang@Sun.COM return (FCOE_FAILURE); 789087SZhong.Wang@Sun.COM } 799087SZhong.Wang@Sun.COM 80*9307Skelly.hu@Sun.COM (void) sprintf(cli_name, "%s-%d", "fcoe", mac->fm_linkid); 819087SZhong.Wang@Sun.COM 829087SZhong.Wang@Sun.COM ret = mac_client_open(mac->fm_handle, 839087SZhong.Wang@Sun.COM &mac->fm_cli_handle, cli_name, fm_open_flag); 849087SZhong.Wang@Sun.COM if (ret != 0) { 859087SZhong.Wang@Sun.COM (void) fcoe_close_mac(mac); 869087SZhong.Wang@Sun.COM return (FCOE_FAILURE); 879087SZhong.Wang@Sun.COM } 889087SZhong.Wang@Sun.COM /* 899087SZhong.Wang@Sun.COM * Cache the pointer of the immutable MAC inforamtion and 909087SZhong.Wang@Sun.COM * the current and primary MAC address 919087SZhong.Wang@Sun.COM */ 929087SZhong.Wang@Sun.COM mac_unicast_primary_get(mac->fm_handle, mac->fm_primary_addr); 939087SZhong.Wang@Sun.COM bcopy(mac->fm_primary_addr, mac->fm_current_addr, 949087SZhong.Wang@Sun.COM ETHERADDRL); 959087SZhong.Wang@Sun.COM 969087SZhong.Wang@Sun.COM if (mac_unicast_add(mac->fm_cli_handle, NULL, MAC_UNICAST_PRIMARY, 979087SZhong.Wang@Sun.COM &mac->fm_unicst_handle, 0, &diag)) { 989087SZhong.Wang@Sun.COM (void) fcoe_close_mac(mac); 999087SZhong.Wang@Sun.COM return (FCOE_FAILURE); 1009087SZhong.Wang@Sun.COM } 1019087SZhong.Wang@Sun.COM 1029087SZhong.Wang@Sun.COM if (force_promisc) { 1039087SZhong.Wang@Sun.COM mac->fm_force_promisc = B_TRUE; 1049087SZhong.Wang@Sun.COM } 1059087SZhong.Wang@Sun.COM 1069087SZhong.Wang@Sun.COM /* Get mtu */ 1079087SZhong.Wang@Sun.COM mac_sdu_get(mac->fm_handle, NULL, &mac->fm_eport.eport_mtu); 1089087SZhong.Wang@Sun.COM if (mac->fm_eport.eport_mtu < FCOE_MIN_MTU_SIZE) { 1099087SZhong.Wang@Sun.COM if (!fcoe_enable_p2pmode || mac->fm_eport.eport_mtu < 1500) { 1109087SZhong.Wang@Sun.COM /* 1119087SZhong.Wang@Sun.COM * Fail open if fail to get mtu, or we are not 1129087SZhong.Wang@Sun.COM * using p2p, or we are using p2p, but 1139087SZhong.Wang@Sun.COM * the mtu is too small 1149087SZhong.Wang@Sun.COM */ 1159087SZhong.Wang@Sun.COM (void) fcoe_close_mac(mac); 1169087SZhong.Wang@Sun.COM *err_detail = FCOEIOE_NEED_JUMBO_FRAME; 1179087SZhong.Wang@Sun.COM return (FCOE_FAILURE); 1189087SZhong.Wang@Sun.COM } 1199087SZhong.Wang@Sun.COM } 1209087SZhong.Wang@Sun.COM 1219087SZhong.Wang@Sun.COM mac->fm_eport.eport_link_speed = 1229087SZhong.Wang@Sun.COM mac_client_stat_get(mac->fm_cli_handle, MAC_STAT_IFSPEED); 1239087SZhong.Wang@Sun.COM 1249087SZhong.Wang@Sun.COM cv_init(&mac->fm_tx_cv, NULL, CV_DRIVER, NULL); 1259087SZhong.Wang@Sun.COM mutex_init(&mac->fm_mutex, NULL, MUTEX_DRIVER, NULL); 1269087SZhong.Wang@Sun.COM mac->fm_running = B_TRUE; 1279087SZhong.Wang@Sun.COM 1289087SZhong.Wang@Sun.COM fcoe_ret = FCOE_SUCCESS; 1299087SZhong.Wang@Sun.COM return (fcoe_ret); 1309087SZhong.Wang@Sun.COM } 1319087SZhong.Wang@Sun.COM 1329087SZhong.Wang@Sun.COM int 1339087SZhong.Wang@Sun.COM fcoe_close_mac(fcoe_mac_t *mac) 1349087SZhong.Wang@Sun.COM { 1359087SZhong.Wang@Sun.COM int ret; 1369087SZhong.Wang@Sun.COM 1379087SZhong.Wang@Sun.COM if (mac->fm_handle == NULL) { 1389087SZhong.Wang@Sun.COM return (FCOE_SUCCESS); 1399087SZhong.Wang@Sun.COM } 1409087SZhong.Wang@Sun.COM 1419087SZhong.Wang@Sun.COM if (mac->fm_running) { 1429087SZhong.Wang@Sun.COM cv_destroy(&mac->fm_tx_cv); 1439087SZhong.Wang@Sun.COM mutex_destroy(&mac->fm_mutex); 1449087SZhong.Wang@Sun.COM mac->fm_running = B_FALSE; 1459087SZhong.Wang@Sun.COM } 1469087SZhong.Wang@Sun.COM 1479087SZhong.Wang@Sun.COM if (mac->fm_promisc_handle != NULL) { 1489087SZhong.Wang@Sun.COM mac_promisc_remove(mac->fm_promisc_handle); 1499087SZhong.Wang@Sun.COM mac->fm_promisc_handle = NULL; 1509087SZhong.Wang@Sun.COM } else { 1519087SZhong.Wang@Sun.COM mac_rx_clear(mac->fm_cli_handle); 1529087SZhong.Wang@Sun.COM } 1539087SZhong.Wang@Sun.COM 1549087SZhong.Wang@Sun.COM if (mac->fm_notify_handle != NULL) { 1559087SZhong.Wang@Sun.COM ret = mac_notify_remove(mac->fm_notify_handle, B_TRUE); 1569087SZhong.Wang@Sun.COM ASSERT(ret == 0); 1579087SZhong.Wang@Sun.COM mac->fm_notify_handle = NULL; 1589087SZhong.Wang@Sun.COM } 1599087SZhong.Wang@Sun.COM 1609087SZhong.Wang@Sun.COM if (mac->fm_unicst_handle != NULL) { 1619087SZhong.Wang@Sun.COM (void) mac_unicast_remove(mac->fm_cli_handle, 1629087SZhong.Wang@Sun.COM mac->fm_unicst_handle); 1639087SZhong.Wang@Sun.COM mac->fm_unicst_handle = NULL; 1649087SZhong.Wang@Sun.COM } 1659087SZhong.Wang@Sun.COM 1669087SZhong.Wang@Sun.COM mac_client_close(mac->fm_cli_handle, 0); 1679087SZhong.Wang@Sun.COM mac->fm_cli_handle = NULL; 1689087SZhong.Wang@Sun.COM 1699087SZhong.Wang@Sun.COM (void) mac_close(mac->fm_handle); 1709087SZhong.Wang@Sun.COM mac->fm_handle = NULL; 1719087SZhong.Wang@Sun.COM 1729087SZhong.Wang@Sun.COM return (FCOE_SUCCESS); 1739087SZhong.Wang@Sun.COM } 1749087SZhong.Wang@Sun.COM 1759087SZhong.Wang@Sun.COM int 1769087SZhong.Wang@Sun.COM fcoe_enable_callback(fcoe_mac_t *mac) 1779087SZhong.Wang@Sun.COM { 1789087SZhong.Wang@Sun.COM int ret; 1799087SZhong.Wang@Sun.COM 1809087SZhong.Wang@Sun.COM /* 1819087SZhong.Wang@Sun.COM * Set message callback 1829087SZhong.Wang@Sun.COM */ 1839087SZhong.Wang@Sun.COM if (mac->fm_force_promisc) { 1849087SZhong.Wang@Sun.COM ret = mac_promisc_add(mac->fm_cli_handle, 1859087SZhong.Wang@Sun.COM MAC_CLIENT_PROMISC_FILTERED, fcoe_rx, mac, 1869087SZhong.Wang@Sun.COM &mac->fm_promisc_handle, 1879087SZhong.Wang@Sun.COM MAC_PROMISC_FLAGS_NO_TX_LOOP); 1889087SZhong.Wang@Sun.COM if (ret != 0) { 189*9307Skelly.hu@Sun.COM FCOE_LOG("foce", "mac_promisc_add on %d failed %x", 190*9307Skelly.hu@Sun.COM mac->fm_linkid, ret); 1919087SZhong.Wang@Sun.COM return (FCOE_FAILURE); 1929087SZhong.Wang@Sun.COM } 1939087SZhong.Wang@Sun.COM } else { 1949087SZhong.Wang@Sun.COM mac_rx_set(mac->fm_cli_handle, fcoe_rx, mac); 1959087SZhong.Wang@Sun.COM } 1969087SZhong.Wang@Sun.COM 1979087SZhong.Wang@Sun.COM /* Get the link state, if it's up, we will need to notify client */ 1989087SZhong.Wang@Sun.COM mac->fm_link_state = 1999087SZhong.Wang@Sun.COM mac_stat_get(mac->fm_handle, MAC_STAT_LINK_UP)? 2009087SZhong.Wang@Sun.COM FCOE_MAC_LINK_STATE_UP:FCOE_MAC_LINK_STATE_DOWN; 2019087SZhong.Wang@Sun.COM 2029087SZhong.Wang@Sun.COM /* 2039087SZhong.Wang@Sun.COM * Add a notify function so that we get updates from MAC 2049087SZhong.Wang@Sun.COM */ 2059087SZhong.Wang@Sun.COM mac->fm_notify_handle = mac_notify_add(mac->fm_handle, 2069087SZhong.Wang@Sun.COM fcoe_mac_notify, (void *)mac); 2079087SZhong.Wang@Sun.COM return (FCOE_SUCCESS); 2089087SZhong.Wang@Sun.COM } 2099087SZhong.Wang@Sun.COM 2109087SZhong.Wang@Sun.COM int 2119087SZhong.Wang@Sun.COM fcoe_disable_callback(fcoe_mac_t *mac) 2129087SZhong.Wang@Sun.COM { 2139087SZhong.Wang@Sun.COM int ret; 2149087SZhong.Wang@Sun.COM 2159087SZhong.Wang@Sun.COM if (mac->fm_promisc_handle) { 2169087SZhong.Wang@Sun.COM mac_promisc_remove(mac->fm_promisc_handle); 2179087SZhong.Wang@Sun.COM mac->fm_promisc_handle = NULL; 2189087SZhong.Wang@Sun.COM } else { 2199087SZhong.Wang@Sun.COM mac_rx_clear(mac->fm_cli_handle); 2209087SZhong.Wang@Sun.COM } 2219087SZhong.Wang@Sun.COM 2229087SZhong.Wang@Sun.COM if (mac->fm_notify_handle) { 2239087SZhong.Wang@Sun.COM ret = mac_notify_remove(mac->fm_notify_handle, B_TRUE); 2249087SZhong.Wang@Sun.COM ASSERT(ret == 0); 2259087SZhong.Wang@Sun.COM mac->fm_notify_handle = NULL; 2269087SZhong.Wang@Sun.COM } 2279087SZhong.Wang@Sun.COM 2289087SZhong.Wang@Sun.COM ret = fcoe_mac_set_address(&mac->fm_eport, 2299087SZhong.Wang@Sun.COM mac->fm_primary_addr, B_FALSE); 2309087SZhong.Wang@Sun.COM FCOE_SET_DEFAULT_FPORT_ADDR(mac->fm_eport.eport_efh_dst); 2319087SZhong.Wang@Sun.COM return (ret); 2329087SZhong.Wang@Sun.COM } 2339087SZhong.Wang@Sun.COM 2349087SZhong.Wang@Sun.COM /* ARGSUSED */ 2359087SZhong.Wang@Sun.COM static void 2369087SZhong.Wang@Sun.COM fcoe_rx(void *arg, mac_resource_handle_t mrh, mblk_t *mp, boolean_t loopback) 2379087SZhong.Wang@Sun.COM { 2389087SZhong.Wang@Sun.COM fcoe_mac_t *mac = (fcoe_mac_t *)arg; 2399087SZhong.Wang@Sun.COM mblk_t *next; 2409087SZhong.Wang@Sun.COM fcoe_frame_t *frm; 2419087SZhong.Wang@Sun.COM uint32_t raw_frame_size, frame_size; 2429087SZhong.Wang@Sun.COM uint16_t frm_type; 2439087SZhong.Wang@Sun.COM 2449087SZhong.Wang@Sun.COM while (mp != NULL) { 2459087SZhong.Wang@Sun.COM next = mp->b_next; 2469087SZhong.Wang@Sun.COM mp->b_next = NULL; 2479087SZhong.Wang@Sun.COM frm_type = ntohs(*(uint16_t *)((uintptr_t)mp->b_rptr + 12)); 2489087SZhong.Wang@Sun.COM 2499087SZhong.Wang@Sun.COM if (frm_type != ETHERTYPE_FCOE) { 2509087SZhong.Wang@Sun.COM /* 2519087SZhong.Wang@Sun.COM * This mp is not allocated in FCoE, but we must free it 2529087SZhong.Wang@Sun.COM */ 2539087SZhong.Wang@Sun.COM freeb(mp); 2549087SZhong.Wang@Sun.COM mp = next; 2559087SZhong.Wang@Sun.COM continue; 2569087SZhong.Wang@Sun.COM } 2579087SZhong.Wang@Sun.COM 2589087SZhong.Wang@Sun.COM raw_frame_size = MBLKL(mp); 2599087SZhong.Wang@Sun.COM frame_size = raw_frame_size - PADDING_SIZE; 2609087SZhong.Wang@Sun.COM frm = fcoe_allocate_frame(&mac->fm_eport, frame_size, mp); 2619087SZhong.Wang@Sun.COM if (frm != NULL) { 2629087SZhong.Wang@Sun.COM fcoe_post_frame(frm); 2639087SZhong.Wang@Sun.COM } 2649087SZhong.Wang@Sun.COM 2659087SZhong.Wang@Sun.COM mp = next; 2669087SZhong.Wang@Sun.COM } 2679087SZhong.Wang@Sun.COM } 2689087SZhong.Wang@Sun.COM 2699087SZhong.Wang@Sun.COM static void 2709087SZhong.Wang@Sun.COM fcoe_mac_notify(void *arg, mac_notify_type_t type) 2719087SZhong.Wang@Sun.COM { 2729087SZhong.Wang@Sun.COM fcoe_mac_t *mac = (fcoe_mac_t *)arg; 2739087SZhong.Wang@Sun.COM 2749087SZhong.Wang@Sun.COM /* 2759087SZhong.Wang@Sun.COM * We assume that the calls to this notification callback are serialized 2769087SZhong.Wang@Sun.COM * by MAC layer 2779087SZhong.Wang@Sun.COM */ 2789087SZhong.Wang@Sun.COM 2799087SZhong.Wang@Sun.COM switch (type) { 2809087SZhong.Wang@Sun.COM case MAC_NOTE_LINK: 2819087SZhong.Wang@Sun.COM /* 2829087SZhong.Wang@Sun.COM * This notification is sent every time the MAC driver 2839087SZhong.Wang@Sun.COM * updates the link state. 2849087SZhong.Wang@Sun.COM */ 2859087SZhong.Wang@Sun.COM if (mac_stat_get(mac->fm_handle, MAC_STAT_LINK_UP) != 0) { 2869087SZhong.Wang@Sun.COM if (mac->fm_link_state == FCOE_MAC_LINK_STATE_UP) { 2879087SZhong.Wang@Sun.COM break; 2889087SZhong.Wang@Sun.COM } 2899087SZhong.Wang@Sun.COM /* Get speed */ 2909087SZhong.Wang@Sun.COM mac->fm_eport.eport_link_speed = 2919087SZhong.Wang@Sun.COM mac_client_stat_get(mac->fm_cli_handle, 2929087SZhong.Wang@Sun.COM MAC_STAT_IFSPEED); 2939087SZhong.Wang@Sun.COM 2949087SZhong.Wang@Sun.COM (void) fcoe_mac_set_address(&mac->fm_eport, 2959087SZhong.Wang@Sun.COM mac->fm_primary_addr, B_FALSE); 2969087SZhong.Wang@Sun.COM 2979087SZhong.Wang@Sun.COM FCOE_SET_DEFAULT_FPORT_ADDR( 2989087SZhong.Wang@Sun.COM mac->fm_eport.eport_efh_dst); 2999087SZhong.Wang@Sun.COM 3009087SZhong.Wang@Sun.COM mac->fm_link_state = FCOE_MAC_LINK_STATE_UP; 301*9307Skelly.hu@Sun.COM FCOE_LOG(NULL, 302*9307Skelly.hu@Sun.COM "fcoe_mac_notify: link/%d arg/%p LINK up", 303*9307Skelly.hu@Sun.COM mac->fm_linkid, arg, type); 3049087SZhong.Wang@Sun.COM fcoe_mac_notify_link_up(mac); 3059087SZhong.Wang@Sun.COM } else { 3069087SZhong.Wang@Sun.COM if (mac->fm_link_state == FCOE_MAC_LINK_STATE_DOWN) { 3079087SZhong.Wang@Sun.COM break; 3089087SZhong.Wang@Sun.COM } 3099087SZhong.Wang@Sun.COM mac->fm_link_state = FCOE_MAC_LINK_STATE_DOWN; 310*9307Skelly.hu@Sun.COM FCOE_LOG(NULL, 311*9307Skelly.hu@Sun.COM "fcoe_mac_notify: link/%d arg/%p LINK down", 312*9307Skelly.hu@Sun.COM mac->fm_linkid, arg, type); 3139087SZhong.Wang@Sun.COM fcoe_mac_notify_link_down(mac); 3149087SZhong.Wang@Sun.COM } 3159087SZhong.Wang@Sun.COM break; 3169087SZhong.Wang@Sun.COM 3179087SZhong.Wang@Sun.COM case MAC_NOTE_TX: 3189087SZhong.Wang@Sun.COM /* 3199087SZhong.Wang@Sun.COM * MAC is not so busy now, then wake up fcoe_tx_frame to try 3209087SZhong.Wang@Sun.COM */ 3219087SZhong.Wang@Sun.COM mutex_enter(&mac->fm_mutex); 3229087SZhong.Wang@Sun.COM cv_broadcast(&mac->fm_tx_cv); 3239087SZhong.Wang@Sun.COM mutex_exit(&mac->fm_mutex); 3249087SZhong.Wang@Sun.COM 3259087SZhong.Wang@Sun.COM FCOE_LOG("fcoe_mac_notify", "wake up"); 3269087SZhong.Wang@Sun.COM break; 3279087SZhong.Wang@Sun.COM 3289087SZhong.Wang@Sun.COM default: 3299087SZhong.Wang@Sun.COM FCOE_LOG("fcoe_mac_notify", "not supported arg/%p, type/%d", 3309087SZhong.Wang@Sun.COM arg, type); 3319087SZhong.Wang@Sun.COM break; 3329087SZhong.Wang@Sun.COM } 3339087SZhong.Wang@Sun.COM } 3349087SZhong.Wang@Sun.COM 3359087SZhong.Wang@Sun.COM int 3369087SZhong.Wang@Sun.COM fcoe_mac_set_address(fcoe_port_t *eport, uint8_t *addr, boolean_t fc_assigned) 3379087SZhong.Wang@Sun.COM { 3389087SZhong.Wang@Sun.COM fcoe_mac_t *mac = EPORT2MAC(eport); 3399087SZhong.Wang@Sun.COM int ret; 3409087SZhong.Wang@Sun.COM 3419087SZhong.Wang@Sun.COM if (bcmp(addr, mac->fm_current_addr, 6) == 0) { 3429087SZhong.Wang@Sun.COM return (FCOE_SUCCESS); 3439087SZhong.Wang@Sun.COM } 3449087SZhong.Wang@Sun.COM 3459087SZhong.Wang@Sun.COM mutex_enter(&mac->fm_mutex); 3469087SZhong.Wang@Sun.COM if (mac->fm_promisc_handle == NULL) { 3479087SZhong.Wang@Sun.COM ret = mac_unicast_primary_set(mac->fm_handle, addr); 3489087SZhong.Wang@Sun.COM if (ret != 0) { 3499087SZhong.Wang@Sun.COM mutex_exit(&mac->fm_mutex); 350*9307Skelly.hu@Sun.COM FCOE_LOG("fcoe", "mac_unicast_primary_set on %d " 351*9307Skelly.hu@Sun.COM "failed %x", mac->fm_linkid, ret); 3529087SZhong.Wang@Sun.COM return (FCOE_FAILURE); 3539087SZhong.Wang@Sun.COM } 3549087SZhong.Wang@Sun.COM } 3559087SZhong.Wang@Sun.COM if (fc_assigned) { 3569087SZhong.Wang@Sun.COM bcopy(addr, mac->fm_current_addr, ETHERADDRL); 3579087SZhong.Wang@Sun.COM } else { 3589087SZhong.Wang@Sun.COM bcopy(mac->fm_primary_addr, 3599087SZhong.Wang@Sun.COM mac->fm_current_addr, ETHERADDRL); 3609087SZhong.Wang@Sun.COM } 3619087SZhong.Wang@Sun.COM mutex_exit(&mac->fm_mutex); 3629087SZhong.Wang@Sun.COM return (FCOE_SUCCESS); 3639087SZhong.Wang@Sun.COM } 364