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
fcoe_open_mac(fcoe_mac_t * mac,int force_promisc,fcoeio_stat_t * err_detail)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 */
739307Skelly.hu@Sun.COM ret = mac_open_by_linkid(mac->fm_linkid, &mac->fm_handle);
749087SZhong.Wang@Sun.COM if (ret != 0) {
759307Skelly.hu@Sun.COM FCOE_LOG("fcoe", "mac_open_by_linkname %d failed %x",
769307Skelly.hu@Sun.COM mac->fm_linkid, ret);
779087SZhong.Wang@Sun.COM return (FCOE_FAILURE);
789087SZhong.Wang@Sun.COM }
799087SZhong.Wang@Sun.COM
809307Skelly.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
fcoe_close_mac(fcoe_mac_t * mac)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
fcoe_enable_callback(fcoe_mac_t * mac)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) {
1899307Skelly.hu@Sun.COM FCOE_LOG("foce", "mac_promisc_add on %d failed %x",
1909307Skelly.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
202*10264SZhong.Wang@Sun.COM mac->fm_eport.eport_link_speed =
203*10264SZhong.Wang@Sun.COM mac_client_stat_get(mac->fm_cli_handle, MAC_STAT_IFSPEED);
204*10264SZhong.Wang@Sun.COM
2059087SZhong.Wang@Sun.COM /*
2069087SZhong.Wang@Sun.COM * Add a notify function so that we get updates from MAC
2079087SZhong.Wang@Sun.COM */
2089087SZhong.Wang@Sun.COM mac->fm_notify_handle = mac_notify_add(mac->fm_handle,
2099087SZhong.Wang@Sun.COM fcoe_mac_notify, (void *)mac);
2109087SZhong.Wang@Sun.COM return (FCOE_SUCCESS);
2119087SZhong.Wang@Sun.COM }
2129087SZhong.Wang@Sun.COM
2139087SZhong.Wang@Sun.COM int
fcoe_disable_callback(fcoe_mac_t * mac)2149087SZhong.Wang@Sun.COM fcoe_disable_callback(fcoe_mac_t *mac)
2159087SZhong.Wang@Sun.COM {
2169087SZhong.Wang@Sun.COM int ret;
2179087SZhong.Wang@Sun.COM
2189087SZhong.Wang@Sun.COM if (mac->fm_promisc_handle) {
2199087SZhong.Wang@Sun.COM mac_promisc_remove(mac->fm_promisc_handle);
2209087SZhong.Wang@Sun.COM mac->fm_promisc_handle = NULL;
2219087SZhong.Wang@Sun.COM } else {
2229087SZhong.Wang@Sun.COM mac_rx_clear(mac->fm_cli_handle);
2239087SZhong.Wang@Sun.COM }
2249087SZhong.Wang@Sun.COM
2259087SZhong.Wang@Sun.COM if (mac->fm_notify_handle) {
2269087SZhong.Wang@Sun.COM ret = mac_notify_remove(mac->fm_notify_handle, B_TRUE);
2279087SZhong.Wang@Sun.COM ASSERT(ret == 0);
2289087SZhong.Wang@Sun.COM mac->fm_notify_handle = NULL;
2299087SZhong.Wang@Sun.COM }
2309087SZhong.Wang@Sun.COM
2319087SZhong.Wang@Sun.COM ret = fcoe_mac_set_address(&mac->fm_eport,
2329087SZhong.Wang@Sun.COM mac->fm_primary_addr, B_FALSE);
2339087SZhong.Wang@Sun.COM FCOE_SET_DEFAULT_FPORT_ADDR(mac->fm_eport.eport_efh_dst);
2349087SZhong.Wang@Sun.COM return (ret);
2359087SZhong.Wang@Sun.COM }
2369087SZhong.Wang@Sun.COM
2379087SZhong.Wang@Sun.COM /* ARGSUSED */
2389087SZhong.Wang@Sun.COM static void
fcoe_rx(void * arg,mac_resource_handle_t mrh,mblk_t * mp,boolean_t loopback)2399087SZhong.Wang@Sun.COM fcoe_rx(void *arg, mac_resource_handle_t mrh, mblk_t *mp, boolean_t loopback)
2409087SZhong.Wang@Sun.COM {
2419087SZhong.Wang@Sun.COM fcoe_mac_t *mac = (fcoe_mac_t *)arg;
2429087SZhong.Wang@Sun.COM mblk_t *next;
2439087SZhong.Wang@Sun.COM fcoe_frame_t *frm;
2449087SZhong.Wang@Sun.COM uint32_t raw_frame_size, frame_size;
2459087SZhong.Wang@Sun.COM uint16_t frm_type;
2469087SZhong.Wang@Sun.COM
2479087SZhong.Wang@Sun.COM while (mp != NULL) {
2489087SZhong.Wang@Sun.COM next = mp->b_next;
2499087SZhong.Wang@Sun.COM mp->b_next = NULL;
2509087SZhong.Wang@Sun.COM frm_type = ntohs(*(uint16_t *)((uintptr_t)mp->b_rptr + 12));
2519087SZhong.Wang@Sun.COM
2529087SZhong.Wang@Sun.COM if (frm_type != ETHERTYPE_FCOE) {
2539087SZhong.Wang@Sun.COM /*
2549087SZhong.Wang@Sun.COM * This mp is not allocated in FCoE, but we must free it
2559087SZhong.Wang@Sun.COM */
2569087SZhong.Wang@Sun.COM freeb(mp);
2579087SZhong.Wang@Sun.COM mp = next;
2589087SZhong.Wang@Sun.COM continue;
2599087SZhong.Wang@Sun.COM }
2609087SZhong.Wang@Sun.COM
2619087SZhong.Wang@Sun.COM raw_frame_size = MBLKL(mp);
2629087SZhong.Wang@Sun.COM frame_size = raw_frame_size - PADDING_SIZE;
2639087SZhong.Wang@Sun.COM frm = fcoe_allocate_frame(&mac->fm_eport, frame_size, mp);
2649087SZhong.Wang@Sun.COM if (frm != NULL) {
265*10264SZhong.Wang@Sun.COM frm->frm_clock = CURRENT_CLOCK;
2669087SZhong.Wang@Sun.COM fcoe_post_frame(frm);
2679087SZhong.Wang@Sun.COM }
2689087SZhong.Wang@Sun.COM
2699087SZhong.Wang@Sun.COM mp = next;
2709087SZhong.Wang@Sun.COM }
2719087SZhong.Wang@Sun.COM }
2729087SZhong.Wang@Sun.COM
2739087SZhong.Wang@Sun.COM static void
fcoe_mac_notify(void * arg,mac_notify_type_t type)2749087SZhong.Wang@Sun.COM fcoe_mac_notify(void *arg, mac_notify_type_t type)
2759087SZhong.Wang@Sun.COM {
2769087SZhong.Wang@Sun.COM fcoe_mac_t *mac = (fcoe_mac_t *)arg;
2779087SZhong.Wang@Sun.COM
2789087SZhong.Wang@Sun.COM /*
2799087SZhong.Wang@Sun.COM * We assume that the calls to this notification callback are serialized
2809087SZhong.Wang@Sun.COM * by MAC layer
2819087SZhong.Wang@Sun.COM */
2829087SZhong.Wang@Sun.COM
2839087SZhong.Wang@Sun.COM switch (type) {
2849087SZhong.Wang@Sun.COM case MAC_NOTE_LINK:
2859087SZhong.Wang@Sun.COM /*
2869087SZhong.Wang@Sun.COM * This notification is sent every time the MAC driver
2879087SZhong.Wang@Sun.COM * updates the link state.
2889087SZhong.Wang@Sun.COM */
2899087SZhong.Wang@Sun.COM if (mac_stat_get(mac->fm_handle, MAC_STAT_LINK_UP) != 0) {
2909087SZhong.Wang@Sun.COM if (mac->fm_link_state == FCOE_MAC_LINK_STATE_UP) {
2919087SZhong.Wang@Sun.COM break;
2929087SZhong.Wang@Sun.COM }
2939087SZhong.Wang@Sun.COM /* Get speed */
2949087SZhong.Wang@Sun.COM mac->fm_eport.eport_link_speed =
2959087SZhong.Wang@Sun.COM mac_client_stat_get(mac->fm_cli_handle,
2969087SZhong.Wang@Sun.COM MAC_STAT_IFSPEED);
2979087SZhong.Wang@Sun.COM (void) fcoe_mac_set_address(&mac->fm_eport,
2989087SZhong.Wang@Sun.COM mac->fm_primary_addr, B_FALSE);
2999087SZhong.Wang@Sun.COM
3009087SZhong.Wang@Sun.COM FCOE_SET_DEFAULT_FPORT_ADDR(
3019087SZhong.Wang@Sun.COM mac->fm_eport.eport_efh_dst);
3029087SZhong.Wang@Sun.COM
3039087SZhong.Wang@Sun.COM mac->fm_link_state = FCOE_MAC_LINK_STATE_UP;
3049307Skelly.hu@Sun.COM FCOE_LOG(NULL,
3059307Skelly.hu@Sun.COM "fcoe_mac_notify: link/%d arg/%p LINK up",
3069307Skelly.hu@Sun.COM mac->fm_linkid, arg, type);
3079087SZhong.Wang@Sun.COM fcoe_mac_notify_link_up(mac);
3089087SZhong.Wang@Sun.COM } else {
3099087SZhong.Wang@Sun.COM if (mac->fm_link_state == FCOE_MAC_LINK_STATE_DOWN) {
3109087SZhong.Wang@Sun.COM break;
3119087SZhong.Wang@Sun.COM }
3129087SZhong.Wang@Sun.COM mac->fm_link_state = FCOE_MAC_LINK_STATE_DOWN;
3139307Skelly.hu@Sun.COM FCOE_LOG(NULL,
3149307Skelly.hu@Sun.COM "fcoe_mac_notify: link/%d arg/%p LINK down",
3159307Skelly.hu@Sun.COM mac->fm_linkid, arg, type);
3169087SZhong.Wang@Sun.COM fcoe_mac_notify_link_down(mac);
3179087SZhong.Wang@Sun.COM }
3189087SZhong.Wang@Sun.COM break;
3199087SZhong.Wang@Sun.COM
3209087SZhong.Wang@Sun.COM case MAC_NOTE_TX:
3219087SZhong.Wang@Sun.COM /*
3229087SZhong.Wang@Sun.COM * MAC is not so busy now, then wake up fcoe_tx_frame to try
3239087SZhong.Wang@Sun.COM */
3249087SZhong.Wang@Sun.COM mutex_enter(&mac->fm_mutex);
3259087SZhong.Wang@Sun.COM cv_broadcast(&mac->fm_tx_cv);
3269087SZhong.Wang@Sun.COM mutex_exit(&mac->fm_mutex);
3279087SZhong.Wang@Sun.COM
3289087SZhong.Wang@Sun.COM FCOE_LOG("fcoe_mac_notify", "wake up");
3299087SZhong.Wang@Sun.COM break;
3309087SZhong.Wang@Sun.COM
3319087SZhong.Wang@Sun.COM default:
3329087SZhong.Wang@Sun.COM FCOE_LOG("fcoe_mac_notify", "not supported arg/%p, type/%d",
3339087SZhong.Wang@Sun.COM arg, type);
3349087SZhong.Wang@Sun.COM break;
3359087SZhong.Wang@Sun.COM }
3369087SZhong.Wang@Sun.COM }
3379087SZhong.Wang@Sun.COM
3389087SZhong.Wang@Sun.COM int
fcoe_mac_set_address(fcoe_port_t * eport,uint8_t * addr,boolean_t fc_assigned)3399087SZhong.Wang@Sun.COM fcoe_mac_set_address(fcoe_port_t *eport, uint8_t *addr, boolean_t fc_assigned)
3409087SZhong.Wang@Sun.COM {
3419087SZhong.Wang@Sun.COM fcoe_mac_t *mac = EPORT2MAC(eport);
3429087SZhong.Wang@Sun.COM int ret;
3439087SZhong.Wang@Sun.COM
3449087SZhong.Wang@Sun.COM if (bcmp(addr, mac->fm_current_addr, 6) == 0) {
3459087SZhong.Wang@Sun.COM return (FCOE_SUCCESS);
3469087SZhong.Wang@Sun.COM }
3479087SZhong.Wang@Sun.COM
3489087SZhong.Wang@Sun.COM mutex_enter(&mac->fm_mutex);
3499087SZhong.Wang@Sun.COM if (mac->fm_promisc_handle == NULL) {
3509087SZhong.Wang@Sun.COM ret = mac_unicast_primary_set(mac->fm_handle, addr);
3519087SZhong.Wang@Sun.COM if (ret != 0) {
3529087SZhong.Wang@Sun.COM mutex_exit(&mac->fm_mutex);
3539307Skelly.hu@Sun.COM FCOE_LOG("fcoe", "mac_unicast_primary_set on %d "
3549307Skelly.hu@Sun.COM "failed %x", mac->fm_linkid, ret);
3559087SZhong.Wang@Sun.COM return (FCOE_FAILURE);
3569087SZhong.Wang@Sun.COM }
3579087SZhong.Wang@Sun.COM }
3589087SZhong.Wang@Sun.COM if (fc_assigned) {
3599087SZhong.Wang@Sun.COM bcopy(addr, mac->fm_current_addr, ETHERADDRL);
3609087SZhong.Wang@Sun.COM } else {
3619087SZhong.Wang@Sun.COM bcopy(mac->fm_primary_addr,
3629087SZhong.Wang@Sun.COM mac->fm_current_addr, ETHERADDRL);
3639087SZhong.Wang@Sun.COM }
3649087SZhong.Wang@Sun.COM mutex_exit(&mac->fm_mutex);
3659087SZhong.Wang@Sun.COM return (FCOE_SUCCESS);
3669087SZhong.Wang@Sun.COM }
367