xref: /illumos-gate/usr/src/uts/common/io/fcoe/fcoe_eth.c (revision 7ff83669)
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 <sys/stat.h>
272a8164dfSZhong Wang #include <sys/types.h>
282a8164dfSZhong Wang #include <netinet/in.h>
292a8164dfSZhong Wang #include <sys/inttypes.h>
302a8164dfSZhong Wang #include <sys/strsun.h>
312a8164dfSZhong Wang #include <sys/mac_client.h>
322a8164dfSZhong Wang 
332a8164dfSZhong Wang /*
342a8164dfSZhong Wang  * FCoE header files
352a8164dfSZhong Wang  */
362a8164dfSZhong Wang #include <sys/fcoe/fcoeio.h>
372a8164dfSZhong Wang #include <sys/fcoe/fcoe_common.h>
382a8164dfSZhong Wang 
392a8164dfSZhong Wang /*
402a8164dfSZhong Wang  * Driver's own header files
412a8164dfSZhong Wang  */
422a8164dfSZhong Wang #include <fcoe.h>
432a8164dfSZhong Wang #include <fcoe_eth.h>
442a8164dfSZhong Wang #include <fcoe_fc.h>
452a8164dfSZhong Wang 
462a8164dfSZhong Wang static void fcoe_rx(void *arg, mac_resource_handle_t mrh,
472a8164dfSZhong Wang     mblk_t *mp, boolean_t loopback);
482a8164dfSZhong Wang static void fcoe_mac_notify(void *arg, mac_notify_type_t type);
492a8164dfSZhong Wang 
502a8164dfSZhong Wang /*
512a8164dfSZhong Wang  * Global variable definitions
522a8164dfSZhong Wang  */
532a8164dfSZhong Wang 
542a8164dfSZhong Wang /*
552a8164dfSZhong Wang  * Internal tunable, used to enable p2p mode
562a8164dfSZhong Wang  */
572a8164dfSZhong Wang volatile uint32_t	fcoe_enable_p2pmode = 0;
582a8164dfSZhong Wang 
592a8164dfSZhong Wang int
fcoe_open_mac(fcoe_mac_t * mac,int force_promisc,fcoeio_stat_t * err_detail)602a8164dfSZhong Wang fcoe_open_mac(fcoe_mac_t *mac, int force_promisc, fcoeio_stat_t *err_detail)
612a8164dfSZhong Wang {
622a8164dfSZhong Wang 	int		ret;
632a8164dfSZhong Wang 	int		fcoe_ret;
642a8164dfSZhong Wang 	char		cli_name[MAXNAMELEN];
652a8164dfSZhong Wang 	mac_diag_t	diag;
662a8164dfSZhong Wang 	uint16_t	fm_open_flag = 0;
672a8164dfSZhong Wang 
682a8164dfSZhong Wang 	*err_detail = 0;
692a8164dfSZhong Wang 
702a8164dfSZhong Wang 	/*
712a8164dfSZhong Wang 	 * Open MAC interface
722a8164dfSZhong Wang 	 */
73d4401b99SKelly Hu 	ret = mac_open_by_linkid(mac->fm_linkid, &mac->fm_handle);
742a8164dfSZhong Wang 	if (ret != 0) {
75d4401b99SKelly Hu 		FCOE_LOG("fcoe", "mac_open_by_linkname %d failed %x",
76d4401b99SKelly Hu 		    mac->fm_linkid, ret);
772a8164dfSZhong Wang 		return (FCOE_FAILURE);
782a8164dfSZhong Wang 	}
792a8164dfSZhong Wang 
80d4401b99SKelly Hu 	(void) sprintf(cli_name, "%s-%d", "fcoe", mac->fm_linkid);
812a8164dfSZhong Wang 
822a8164dfSZhong Wang 	ret = mac_client_open(mac->fm_handle,
832a8164dfSZhong Wang 	    &mac->fm_cli_handle, cli_name, fm_open_flag);
842a8164dfSZhong Wang 	if (ret != 0) {
852a8164dfSZhong Wang 		(void) fcoe_close_mac(mac);
862a8164dfSZhong Wang 		return (FCOE_FAILURE);
872a8164dfSZhong Wang 	}
882a8164dfSZhong Wang 	/*
892a8164dfSZhong Wang 	 * Cache the pointer of the immutable MAC inforamtion and
902a8164dfSZhong Wang 	 * the current and primary MAC address
912a8164dfSZhong Wang 	 */
922a8164dfSZhong Wang 	mac_unicast_primary_get(mac->fm_handle, mac->fm_primary_addr);
932a8164dfSZhong Wang 	bcopy(mac->fm_primary_addr, mac->fm_current_addr,
942a8164dfSZhong Wang 	    ETHERADDRL);
952a8164dfSZhong Wang 
962a8164dfSZhong Wang 	if (mac_unicast_add(mac->fm_cli_handle, NULL, MAC_UNICAST_PRIMARY,
972a8164dfSZhong Wang 	    &mac->fm_unicst_handle, 0, &diag)) {
982a8164dfSZhong Wang 		(void) fcoe_close_mac(mac);
992a8164dfSZhong Wang 		return (FCOE_FAILURE);
1002a8164dfSZhong Wang 	}
1012a8164dfSZhong Wang 
1022a8164dfSZhong Wang 	if (force_promisc) {
1032a8164dfSZhong Wang 		mac->fm_force_promisc = B_TRUE;
1042a8164dfSZhong Wang 	}
1052a8164dfSZhong Wang 
1062a8164dfSZhong Wang 	/* Get mtu */
1072a8164dfSZhong Wang 	mac_sdu_get(mac->fm_handle, NULL, &mac->fm_eport.eport_mtu);
1082a8164dfSZhong Wang 	if (mac->fm_eport.eport_mtu < FCOE_MIN_MTU_SIZE) {
1092a8164dfSZhong Wang 		if (!fcoe_enable_p2pmode || mac->fm_eport.eport_mtu < 1500) {
1102a8164dfSZhong Wang 			/*
1112a8164dfSZhong Wang 			 * Fail open if fail to get mtu, or we are not
1122a8164dfSZhong Wang 			 * using p2p, or we are using p2p, but
1132a8164dfSZhong Wang 			 * the mtu is too small
1142a8164dfSZhong Wang 			 */
1152a8164dfSZhong Wang 			(void) fcoe_close_mac(mac);
1162a8164dfSZhong Wang 			*err_detail = FCOEIOE_NEED_JUMBO_FRAME;
1172a8164dfSZhong Wang 			return (FCOE_FAILURE);
1182a8164dfSZhong Wang 		}
1192a8164dfSZhong Wang 	}
1202a8164dfSZhong Wang 
1212a8164dfSZhong Wang 	mac->fm_eport.eport_link_speed =
1222a8164dfSZhong Wang 	    mac_client_stat_get(mac->fm_cli_handle, MAC_STAT_IFSPEED);
1232a8164dfSZhong Wang 
1242a8164dfSZhong Wang 	cv_init(&mac->fm_tx_cv, NULL, CV_DRIVER, NULL);
1252a8164dfSZhong Wang 	mutex_init(&mac->fm_mutex, NULL, MUTEX_DRIVER, NULL);
1262a8164dfSZhong Wang 	mac->fm_running = B_TRUE;
1272a8164dfSZhong Wang 
1282a8164dfSZhong Wang 	fcoe_ret = FCOE_SUCCESS;
1292a8164dfSZhong Wang 	return (fcoe_ret);
1302a8164dfSZhong Wang }
1312a8164dfSZhong Wang 
1322a8164dfSZhong Wang int
fcoe_close_mac(fcoe_mac_t * mac)1332a8164dfSZhong Wang fcoe_close_mac(fcoe_mac_t *mac)
1342a8164dfSZhong Wang {
1352a8164dfSZhong Wang 	int ret;
1362a8164dfSZhong Wang 
1372a8164dfSZhong Wang 	if (mac->fm_handle == NULL) {
1382a8164dfSZhong Wang 		return (FCOE_SUCCESS);
1392a8164dfSZhong Wang 	}
1402a8164dfSZhong Wang 
1412a8164dfSZhong Wang 	if (mac->fm_running) {
1422a8164dfSZhong Wang 		cv_destroy(&mac->fm_tx_cv);
1432a8164dfSZhong Wang 		mutex_destroy(&mac->fm_mutex);
1442a8164dfSZhong Wang 		mac->fm_running = B_FALSE;
1452a8164dfSZhong Wang 	}
1462a8164dfSZhong Wang 
1472a8164dfSZhong Wang 	if (mac->fm_promisc_handle != NULL) {
1482a8164dfSZhong Wang 		mac_promisc_remove(mac->fm_promisc_handle);
1492a8164dfSZhong Wang 		mac->fm_promisc_handle = NULL;
1502a8164dfSZhong Wang 	} else {
1512a8164dfSZhong Wang 		mac_rx_clear(mac->fm_cli_handle);
1522a8164dfSZhong Wang 	}
1532a8164dfSZhong Wang 
1542a8164dfSZhong Wang 	if (mac->fm_notify_handle != NULL) {
1552a8164dfSZhong Wang 		ret = mac_notify_remove(mac->fm_notify_handle, B_TRUE);
1562a8164dfSZhong Wang 		ASSERT(ret == 0);
1572a8164dfSZhong Wang 		mac->fm_notify_handle = NULL;
1582a8164dfSZhong Wang 	}
1592a8164dfSZhong Wang 
1602a8164dfSZhong Wang 	if (mac->fm_unicst_handle != NULL) {
1612a8164dfSZhong Wang 		(void) mac_unicast_remove(mac->fm_cli_handle,
1622a8164dfSZhong Wang 		    mac->fm_unicst_handle);
1632a8164dfSZhong Wang 		mac->fm_unicst_handle = NULL;
1642a8164dfSZhong Wang 	}
1652a8164dfSZhong Wang 
1662a8164dfSZhong Wang 	mac_client_close(mac->fm_cli_handle, 0);
1672a8164dfSZhong Wang 	mac->fm_cli_handle = NULL;
1682a8164dfSZhong Wang 
1692a8164dfSZhong Wang 	(void) mac_close(mac->fm_handle);
1702a8164dfSZhong Wang 	mac->fm_handle = NULL;
1712a8164dfSZhong Wang 
1722a8164dfSZhong Wang 	return (FCOE_SUCCESS);
1732a8164dfSZhong Wang }
1742a8164dfSZhong Wang 
1752a8164dfSZhong Wang int
fcoe_enable_callback(fcoe_mac_t * mac)1762a8164dfSZhong Wang fcoe_enable_callback(fcoe_mac_t *mac)
1772a8164dfSZhong Wang {
1782a8164dfSZhong Wang 	int ret;
1792a8164dfSZhong Wang 
1802a8164dfSZhong Wang 	/*
1812a8164dfSZhong Wang 	 * Set message callback
1822a8164dfSZhong Wang 	 */
1832a8164dfSZhong Wang 	if (mac->fm_force_promisc) {
1842a8164dfSZhong Wang 		ret = mac_promisc_add(mac->fm_cli_handle,
1852a8164dfSZhong Wang 		    MAC_CLIENT_PROMISC_FILTERED, fcoe_rx, mac,
1862a8164dfSZhong Wang 		    &mac->fm_promisc_handle,
1872a8164dfSZhong Wang 		    MAC_PROMISC_FLAGS_NO_TX_LOOP);
1882a8164dfSZhong Wang 		if (ret != 0) {
189d4401b99SKelly Hu 			FCOE_LOG("foce", "mac_promisc_add on %d failed %x",
190d4401b99SKelly Hu 			    mac->fm_linkid, ret);
1912a8164dfSZhong Wang 			return (FCOE_FAILURE);
1922a8164dfSZhong Wang 		}
1932a8164dfSZhong Wang 	} else {
1942a8164dfSZhong Wang 		mac_rx_set(mac->fm_cli_handle, fcoe_rx, mac);
1952a8164dfSZhong Wang 	}
1962a8164dfSZhong Wang 
1972a8164dfSZhong Wang 	/* Get the link state, if it's up, we will need to notify client */
1982a8164dfSZhong Wang 	mac->fm_link_state =
1992a8164dfSZhong Wang 	    mac_stat_get(mac->fm_handle, MAC_STAT_LINK_UP)?
2002a8164dfSZhong Wang 	    FCOE_MAC_LINK_STATE_UP:FCOE_MAC_LINK_STATE_DOWN;
2012a8164dfSZhong Wang 
202*7ff83669SZhong Wang 	mac->fm_eport.eport_link_speed =
203*7ff83669SZhong Wang 	    mac_client_stat_get(mac->fm_cli_handle, MAC_STAT_IFSPEED);
204*7ff83669SZhong Wang 
2052a8164dfSZhong Wang 	/*
2062a8164dfSZhong Wang 	 * Add a notify function so that we get updates from MAC
2072a8164dfSZhong Wang 	 */
2082a8164dfSZhong Wang 	mac->fm_notify_handle = mac_notify_add(mac->fm_handle,
2092a8164dfSZhong Wang 	    fcoe_mac_notify, (void *)mac);
2102a8164dfSZhong Wang 	return (FCOE_SUCCESS);
2112a8164dfSZhong Wang }
2122a8164dfSZhong Wang 
2132a8164dfSZhong Wang int
fcoe_disable_callback(fcoe_mac_t * mac)2142a8164dfSZhong Wang fcoe_disable_callback(fcoe_mac_t *mac)
2152a8164dfSZhong Wang {
2162a8164dfSZhong Wang 	int ret;
2172a8164dfSZhong Wang 
2182a8164dfSZhong Wang 	if (mac->fm_promisc_handle) {
2192a8164dfSZhong Wang 		mac_promisc_remove(mac->fm_promisc_handle);
2202a8164dfSZhong Wang 		mac->fm_promisc_handle = NULL;
2212a8164dfSZhong Wang 	} else {
2222a8164dfSZhong Wang 		mac_rx_clear(mac->fm_cli_handle);
2232a8164dfSZhong Wang 	}
2242a8164dfSZhong Wang 
2252a8164dfSZhong Wang 	if (mac->fm_notify_handle) {
2262a8164dfSZhong Wang 		ret = mac_notify_remove(mac->fm_notify_handle, B_TRUE);
2272a8164dfSZhong Wang 		ASSERT(ret == 0);
2282a8164dfSZhong Wang 		mac->fm_notify_handle = NULL;
2292a8164dfSZhong Wang 	}
2302a8164dfSZhong Wang 
2312a8164dfSZhong Wang 	ret = fcoe_mac_set_address(&mac->fm_eport,
2322a8164dfSZhong Wang 	    mac->fm_primary_addr, B_FALSE);
2332a8164dfSZhong Wang 	FCOE_SET_DEFAULT_FPORT_ADDR(mac->fm_eport.eport_efh_dst);
2342a8164dfSZhong Wang 	return (ret);
2352a8164dfSZhong Wang }
2362a8164dfSZhong Wang 
2372a8164dfSZhong Wang /* ARGSUSED */
2382a8164dfSZhong Wang static void
fcoe_rx(void * arg,mac_resource_handle_t mrh,mblk_t * mp,boolean_t loopback)2392a8164dfSZhong Wang fcoe_rx(void *arg, mac_resource_handle_t mrh, mblk_t *mp, boolean_t loopback)
2402a8164dfSZhong Wang {
2412a8164dfSZhong Wang 	fcoe_mac_t	*mac = (fcoe_mac_t *)arg;
2422a8164dfSZhong Wang 	mblk_t		*next;
2432a8164dfSZhong Wang 	fcoe_frame_t	*frm;
2442a8164dfSZhong Wang 	uint32_t	raw_frame_size, frame_size;
2452a8164dfSZhong Wang 	uint16_t	frm_type;
2462a8164dfSZhong Wang 
2472a8164dfSZhong Wang 	while (mp != NULL) {
2482a8164dfSZhong Wang 		next = mp->b_next;
2492a8164dfSZhong Wang 		mp->b_next = NULL;
2502a8164dfSZhong Wang 		frm_type = ntohs(*(uint16_t *)((uintptr_t)mp->b_rptr + 12));
2512a8164dfSZhong Wang 
2522a8164dfSZhong Wang 		if (frm_type != ETHERTYPE_FCOE) {
2532a8164dfSZhong Wang 			/*
2542a8164dfSZhong Wang 			 * This mp is not allocated in FCoE, but we must free it
2552a8164dfSZhong Wang 			 */
2562a8164dfSZhong Wang 			freeb(mp);
2572a8164dfSZhong Wang 			mp = next;
2582a8164dfSZhong Wang 			continue;
2592a8164dfSZhong Wang 		}
2602a8164dfSZhong Wang 
2612a8164dfSZhong Wang 		raw_frame_size = MBLKL(mp);
2622a8164dfSZhong Wang 		frame_size = raw_frame_size - PADDING_SIZE;
2632a8164dfSZhong Wang 		frm = fcoe_allocate_frame(&mac->fm_eport, frame_size, mp);
2642a8164dfSZhong Wang 		if (frm != NULL) {
265*7ff83669SZhong Wang 			frm->frm_clock = CURRENT_CLOCK;
2662a8164dfSZhong Wang 			fcoe_post_frame(frm);
2672a8164dfSZhong Wang 		}
2682a8164dfSZhong Wang 
2692a8164dfSZhong Wang 		mp = next;
2702a8164dfSZhong Wang 	}
2712a8164dfSZhong Wang }
2722a8164dfSZhong Wang 
2732a8164dfSZhong Wang static void
fcoe_mac_notify(void * arg,mac_notify_type_t type)2742a8164dfSZhong Wang fcoe_mac_notify(void *arg, mac_notify_type_t type)
2752a8164dfSZhong Wang {
2762a8164dfSZhong Wang 	fcoe_mac_t *mac = (fcoe_mac_t *)arg;
2772a8164dfSZhong Wang 
2782a8164dfSZhong Wang 	/*
2792a8164dfSZhong Wang 	 * We assume that the calls to this notification callback are serialized
2802a8164dfSZhong Wang 	 * by MAC layer
2812a8164dfSZhong Wang 	 */
2822a8164dfSZhong Wang 
2832a8164dfSZhong Wang 	switch (type) {
2842a8164dfSZhong Wang 	case MAC_NOTE_LINK:
2852a8164dfSZhong Wang 		/*
2862a8164dfSZhong Wang 		 * This notification is sent every time the MAC driver
2872a8164dfSZhong Wang 		 * updates the link state.
2882a8164dfSZhong Wang 		 */
2892a8164dfSZhong Wang 		if (mac_stat_get(mac->fm_handle, MAC_STAT_LINK_UP) != 0) {
2902a8164dfSZhong Wang 			if (mac->fm_link_state == FCOE_MAC_LINK_STATE_UP) {
2912a8164dfSZhong Wang 				break;
2922a8164dfSZhong Wang 			}
2932a8164dfSZhong Wang 			/* Get speed */
2942a8164dfSZhong Wang 			mac->fm_eport.eport_link_speed =
2952a8164dfSZhong Wang 			    mac_client_stat_get(mac->fm_cli_handle,
2962a8164dfSZhong Wang 			    MAC_STAT_IFSPEED);
2972a8164dfSZhong Wang 			(void) fcoe_mac_set_address(&mac->fm_eport,
2982a8164dfSZhong Wang 			    mac->fm_primary_addr, B_FALSE);
2992a8164dfSZhong Wang 
3002a8164dfSZhong Wang 			FCOE_SET_DEFAULT_FPORT_ADDR(
3012a8164dfSZhong Wang 			    mac->fm_eport.eport_efh_dst);
3022a8164dfSZhong Wang 
3032a8164dfSZhong Wang 			mac->fm_link_state = FCOE_MAC_LINK_STATE_UP;
304d4401b99SKelly Hu 			FCOE_LOG(NULL,
305d4401b99SKelly Hu 			    "fcoe_mac_notify: link/%d arg/%p LINK up",
306d4401b99SKelly Hu 			    mac->fm_linkid, arg, type);
3072a8164dfSZhong Wang 			fcoe_mac_notify_link_up(mac);
3082a8164dfSZhong Wang 		} else {
3092a8164dfSZhong Wang 			if (mac->fm_link_state == FCOE_MAC_LINK_STATE_DOWN) {
3102a8164dfSZhong Wang 				break;
3112a8164dfSZhong Wang 			}
3122a8164dfSZhong Wang 			mac->fm_link_state = FCOE_MAC_LINK_STATE_DOWN;
313d4401b99SKelly Hu 			FCOE_LOG(NULL,
314d4401b99SKelly Hu 			    "fcoe_mac_notify: link/%d arg/%p LINK down",
315d4401b99SKelly Hu 			    mac->fm_linkid, arg, type);
3162a8164dfSZhong Wang 			fcoe_mac_notify_link_down(mac);
3172a8164dfSZhong Wang 		}
3182a8164dfSZhong Wang 		break;
3192a8164dfSZhong Wang 
3202a8164dfSZhong Wang 	case MAC_NOTE_TX:
3212a8164dfSZhong Wang 		/*
3222a8164dfSZhong Wang 		 * MAC is not so busy now, then wake up fcoe_tx_frame to try
3232a8164dfSZhong Wang 		 */
3242a8164dfSZhong Wang 		mutex_enter(&mac->fm_mutex);
3252a8164dfSZhong Wang 		cv_broadcast(&mac->fm_tx_cv);
3262a8164dfSZhong Wang 		mutex_exit(&mac->fm_mutex);
3272a8164dfSZhong Wang 
3282a8164dfSZhong Wang 		FCOE_LOG("fcoe_mac_notify", "wake up");
3292a8164dfSZhong Wang 		break;
3302a8164dfSZhong Wang 
3312a8164dfSZhong Wang 	default:
3322a8164dfSZhong Wang 		FCOE_LOG("fcoe_mac_notify", "not supported arg/%p, type/%d",
3332a8164dfSZhong Wang 		    arg, type);
3342a8164dfSZhong Wang 		break;
3352a8164dfSZhong Wang 	}
3362a8164dfSZhong Wang }
3372a8164dfSZhong Wang 
3382a8164dfSZhong Wang int
fcoe_mac_set_address(fcoe_port_t * eport,uint8_t * addr,boolean_t fc_assigned)3392a8164dfSZhong Wang fcoe_mac_set_address(fcoe_port_t *eport, uint8_t *addr, boolean_t fc_assigned)
3402a8164dfSZhong Wang {
3412a8164dfSZhong Wang 	fcoe_mac_t	*mac = EPORT2MAC(eport);
3422a8164dfSZhong Wang 	int		ret;
3432a8164dfSZhong Wang 
3442a8164dfSZhong Wang 	if (bcmp(addr, mac->fm_current_addr, 6) == 0) {
3452a8164dfSZhong Wang 		return (FCOE_SUCCESS);
3462a8164dfSZhong Wang 	}
3472a8164dfSZhong Wang 
3482a8164dfSZhong Wang 	mutex_enter(&mac->fm_mutex);
3492a8164dfSZhong Wang 	if (mac->fm_promisc_handle == NULL) {
3502a8164dfSZhong Wang 		ret = mac_unicast_primary_set(mac->fm_handle, addr);
3512a8164dfSZhong Wang 		if (ret != 0) {
3522a8164dfSZhong Wang 			mutex_exit(&mac->fm_mutex);
353d4401b99SKelly Hu 			FCOE_LOG("fcoe", "mac_unicast_primary_set on %d "
354d4401b99SKelly Hu 			    "failed %x", mac->fm_linkid, ret);
3552a8164dfSZhong Wang 			return (FCOE_FAILURE);
3562a8164dfSZhong Wang 		}
3572a8164dfSZhong Wang 	}
3582a8164dfSZhong Wang 	if (fc_assigned) {
3592a8164dfSZhong Wang 		bcopy(addr, mac->fm_current_addr, ETHERADDRL);
3602a8164dfSZhong Wang 	} else {
3612a8164dfSZhong Wang 		bcopy(mac->fm_primary_addr,
3622a8164dfSZhong Wang 		    mac->fm_current_addr, ETHERADDRL);
3632a8164dfSZhong Wang 	}
3642a8164dfSZhong Wang 	mutex_exit(&mac->fm_mutex);
3652a8164dfSZhong Wang 	return (FCOE_SUCCESS);
3662a8164dfSZhong Wang }
367