xref: /onnv-gate/usr/src/uts/common/io/nxge/nxge_mac.c (revision 5553:fef821d16f97)
13859Sml29623 /*
23859Sml29623  * CDDL HEADER START
33859Sml29623  *
43859Sml29623  * The contents of this file are subject to the terms of the
53859Sml29623  * Common Development and Distribution License (the "License").
63859Sml29623  * You may not use this file except in compliance with the License.
73859Sml29623  *
83859Sml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93859Sml29623  * or http://www.opensolaris.org/os/licensing.
103859Sml29623  * See the License for the specific language governing permissions
113859Sml29623  * and limitations under the License.
123859Sml29623  *
133859Sml29623  * When distributing Covered Code, include this CDDL HEADER in each
143859Sml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153859Sml29623  * If applicable, add the following below this CDDL HEADER, with the
163859Sml29623  * fields enclosed by brackets "[]" replaced with your own identifying
173859Sml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
183859Sml29623  *
193859Sml29623  * CDDL HEADER END
203859Sml29623  */
213859Sml29623 /*
223859Sml29623  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
233859Sml29623  * Use is subject to license terms.
243859Sml29623  */
253859Sml29623 
263859Sml29623 #pragma ident	"%Z%%M%	%I%	%E% SMI"
273859Sml29623 
283859Sml29623 #include <sys/nxge/nxge_impl.h>
293859Sml29623 #include <sys/nxge/nxge_mac.h>
303859Sml29623 
314693Stm144005 #define	LINK_MONITOR_PERIOD	(1000 * 1000)
324693Stm144005 #define	LM_WAIT_MULTIPLIER	8
334693Stm144005 
343859Sml29623 extern uint32_t nxge_no_link_notify;
354732Sdavemq extern boolean_t nxge_no_msg;
363859Sml29623 extern uint32_t nxge_lb_dbg;
373859Sml29623 extern nxge_os_mutex_t	nxge_mdio_lock;
383859Sml29623 extern nxge_os_mutex_t	nxge_mii_lock;
393859Sml29623 extern boolean_t nxge_jumbo_enable;
403859Sml29623 
414693Stm144005 typedef enum {
424693Stm144005 	CHECK_LINK_RESCHEDULE,
434693Stm144005 	CHECK_LINK_STOP
444693Stm144005 } check_link_state_t;
454693Stm144005 
464693Stm144005 static check_link_state_t nxge_check_link_stop(nxge_t *);
474693Stm144005 
483859Sml29623 /*
493859Sml29623  * Ethernet broadcast address definition.
503859Sml29623  */
513859Sml29623 static ether_addr_st etherbroadcastaddr =
523859Sml29623 				{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
534732Sdavemq /*
544732Sdavemq  * Ethernet zero address definition.
554732Sdavemq  */
564185Sspeer static ether_addr_st etherzeroaddr =
574185Sspeer 				{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
584732Sdavemq /*
594732Sdavemq  * Supported chip types
604732Sdavemq  */
614732Sdavemq static uint32_t nxge_supported_cl45_ids[] = {BCM8704_DEV_ID};
624732Sdavemq static uint32_t nxge_supported_cl22_ids[] = {BCM5464R_PHY_ID};
634732Sdavemq 
644732Sdavemq #define	NUM_CLAUSE_45_IDS	(sizeof (nxge_supported_cl45_ids) /	\
654732Sdavemq 				sizeof (uint32_t))
664732Sdavemq #define	NUM_CLAUSE_22_IDS	(sizeof (nxge_supported_cl22_ids) /	\
674732Sdavemq 				sizeof (uint32_t))
684732Sdavemq /*
694732Sdavemq  * static functions
704732Sdavemq  */
714977Sraghus static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int);
724977Sraghus static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int);
734977Sraghus static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int);
744732Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t);
754732Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t);
764732Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t);
774732Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t);
784732Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t);
794732Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t);
804732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t);
814732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t);
824732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t);
834732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t);
844732Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t);
854732Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t);
864732Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t);
874732Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t);
884732Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t);
894732Sdavemq 
904732Sdavemq /*
914732Sdavemq  * xcvr tables for supported transceivers
924732Sdavemq  */
934732Sdavemq 
944977Sraghus static nxge_xcvr_table_t nxge_n2_10G_table = {
954732Sdavemq 	nxge_n2_serdes_init,
964732Sdavemq 	nxge_10G_xcvr_init,
974732Sdavemq 	nxge_10G_link_intr_stop,
984732Sdavemq 	nxge_10G_link_intr_start,
994732Sdavemq 	nxge_check_10g_link,
1004732Sdavemq 	PCS_XCVR,
1014732Sdavemq 	BCM8704_N2_PORT_ADDR_BASE
1024732Sdavemq };
1034732Sdavemq 
1044977Sraghus static nxge_xcvr_table_t nxge_n2_1G_table = {
1054977Sraghus 	nxge_n2_serdes_init,
1064977Sraghus 	nxge_1G_xcvr_init,
1074977Sraghus 	nxge_1G_fiber_link_intr_stop,
1084977Sraghus 	nxge_1G_fiber_link_intr_start,
1094977Sraghus 	nxge_check_mii_link,
1104977Sraghus 	PCS_XCVR,
1114977Sraghus 	0
1124977Sraghus };
1134977Sraghus 
1144732Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = {
1154732Sdavemq 	nxge_neptune_10G_serdes_init,
1164732Sdavemq 	nxge_10G_xcvr_init,
1174732Sdavemq 	nxge_10G_link_intr_stop,
1184732Sdavemq 	nxge_10G_link_intr_start,
1194732Sdavemq 	nxge_check_10g_link,
1204732Sdavemq 	PCS_XCVR,
1214732Sdavemq 	BCM8704_NEPTUNE_PORT_ADDR_BASE
1224732Sdavemq };
1234732Sdavemq 
1244732Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = {
1254732Sdavemq 	NULL,
1264732Sdavemq 	nxge_1G_xcvr_init,
1274732Sdavemq 	nxge_1G_copper_link_intr_stop,
1284732Sdavemq 	nxge_1G_copper_link_intr_start,
1294732Sdavemq 	nxge_check_mii_link,
1304732Sdavemq 	INT_MII_XCVR,
1314732Sdavemq 	BCM5464_NEPTUNE_PORT_ADDR_BASE
1324732Sdavemq };
1334732Sdavemq 
1344732Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = {
1354732Sdavemq 	nxge_1G_serdes_init,
1364732Sdavemq 	nxge_1G_xcvr_init,
1374732Sdavemq 	nxge_1G_fiber_link_intr_stop,
1384732Sdavemq 	nxge_1G_fiber_link_intr_start,
1394732Sdavemq 	nxge_check_mii_link,
1404732Sdavemq 	PCS_XCVR,
1414732Sdavemq 	0
1424732Sdavemq };
1434732Sdavemq 
1444732Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = {
1454732Sdavemq 	nxge_neptune_10G_serdes_init,
1464732Sdavemq 	NULL,
1474732Sdavemq 	NULL,
1484732Sdavemq 	NULL,
1494977Sraghus 	NULL,
1504732Sdavemq 	PCS_XCVR,
1514732Sdavemq 	0
1524732Sdavemq };
1533859Sml29623 
1543859Sml29623 nxge_status_t nxge_mac_init(p_nxge_t);
1553859Sml29623 
1565196Ssbehera #ifdef NXGE_DEBUG
1575196Ssbehera static void nxge_mii_dump(p_nxge_t);
1585196Ssbehera #endif
1595196Ssbehera static nxge_status_t nxge_mii_get_link_mode(p_nxge_t);
1605196Ssbehera 
1614977Sraghus nxge_status_t
1624977Sraghus nxge_get_xcvr_type(p_nxge_t nxgep)
1634977Sraghus {
1644977Sraghus 	nxge_status_t status = NXGE_OK;
1654977Sraghus 	char *phy_type;
1664977Sraghus 	char *prop_val;
1674977Sraghus 
1684977Sraghus 	nxgep->mac.portmode = 0;
1694977Sraghus 
1704977Sraghus 	/* Get property from the driver conf. file */
1714977Sraghus 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip,
1724977Sraghus 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1734977Sraghus 	    "phy-type", &prop_val)) == DDI_PROP_SUCCESS) {
1744977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1754977Sraghus 		    "found  conf file: phy-type %s", prop_val));
1764977Sraghus 		if (strcmp("xgsd", prop_val) == 0) {
1774977Sraghus 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
1784977Sraghus 			nxgep->mac.portmode = PORT_10G_SERDES;
1794977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1804977Sraghus 			    "found: 10G Serdes"));
1814977Sraghus 		} else if (strcmp("gsd", prop_val) == 0) {
1824977Sraghus 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
1834977Sraghus 			nxgep->mac.portmode = PORT_1G_SERDES;
1844977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes"));
1854977Sraghus 		} else if (strcmp("mif", prop_val) == 0) {
1864977Sraghus 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
1874977Sraghus 			nxgep->mac.portmode = PORT_1G_COPPER;
1884977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
1894977Sraghus 		} else if (strcmp("pcs", prop_val) == 0) {
1904977Sraghus 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
1914977Sraghus 			nxgep->mac.portmode = PORT_1G_FIBER;
1924977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr"));
1934977Sraghus 		}
1944977Sraghus 
1954977Sraghus 		(void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip,
1964977Sraghus 		    "phy-type", prop_val);
1974977Sraghus 		ddi_prop_free(prop_val);
1984977Sraghus 
1994977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
2004977Sraghus 		    "Got phy type [0x%x] from conf file",
2014977Sraghus 		    nxgep->mac.portmode));
2024977Sraghus 
2034977Sraghus 		return (NXGE_OK);
2044977Sraghus 	}
2054977Sraghus /*
2064977Sraghus  * TODO add MDIO support for Monza RTM card, Glendale (also Goa) -
2074977Sraghus  * only N2-NIU
2084977Sraghus  */
2094977Sraghus 	if (nxgep->niu_type == N2_NIU) {
2104977Sraghus 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
2114977Sraghus 		    "phy-type", &prop_val) == DDI_PROP_SUCCESS) {
2124977Sraghus 			if (strcmp("xgf", prop_val) == 0) {
2134977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse =
2144977Sraghus 				    XPCS_XCVR;
2154977Sraghus 				nxgep->mac.portmode = PORT_10G_FIBER;
2164977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2174977Sraghus 				    "10G Fiber Xcvr"));
2184977Sraghus 			} else if (strcmp("mif", prop_val) == 0) {
2194977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse =
2204977Sraghus 				    INT_MII_XCVR;
2214977Sraghus 				nxgep->mac.portmode = PORT_1G_COPPER;
2224977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2234977Sraghus 				    "1G Copper Xcvr"));
2244977Sraghus 			} else if (strcmp("pcs", prop_val) == 0) {
2254977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
2264977Sraghus 				nxgep->mac.portmode = PORT_1G_FIBER;
2274977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2284977Sraghus 				    "1G Fiber Xcvr"));
2294977Sraghus 			} else if (strcmp("xgc", prop_val) == 0) {
2304977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse =
2314977Sraghus 				    XPCS_XCVR;
2324977Sraghus 				nxgep->mac.portmode = PORT_10G_COPPER;
2334977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2344977Sraghus 				    "10G Copper Xcvr"));
2354977Sraghus 			} else if (strcmp("xgsd", prop_val) == 0) {
2364977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
2374977Sraghus 				nxgep->mac.portmode = PORT_10G_SERDES;
2384977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2394977Sraghus 				    "OBP: 10G Serdes"));
2404977Sraghus 			} else if (strcmp("gsd", prop_val) == 0) {
2414977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
2424977Sraghus 				nxgep->mac.portmode = PORT_1G_SERDES;
2434977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2444977Sraghus 				    "OBP: 1G Serdes"));
2454977Sraghus 			} else {
2464977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2474977Sraghus 				    "Unknown phy-type: %s", prop_val));
2484977Sraghus 				ddi_prop_free(prop_val);
2494977Sraghus 				return (NXGE_ERROR);
2504977Sraghus 			}
2514977Sraghus 			status = NXGE_OK;
2524977Sraghus 			(void) ddi_prop_update_string(DDI_DEV_T_NONE,
2534977Sraghus 			    nxgep->dip, "phy-type", prop_val);
2544977Sraghus 			ddi_prop_free(prop_val);
2554977Sraghus 
2564977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
2574977Sraghus 			    "Got phy type [0x%x] from OBP",
2584977Sraghus 			    nxgep->mac.portmode));
2594977Sraghus 
2604977Sraghus 			return (status);
2614977Sraghus 		} else {
2624977Sraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2634977Sraghus 			    "Exiting...phy-type property not found"));
2644977Sraghus 			return (NXGE_ERROR);
2654977Sraghus 		}
2664977Sraghus 	}
2674977Sraghus 
2684977Sraghus 
2694977Sraghus 	if (!nxgep->vpd_info.present) {
2704977Sraghus 		return (NXGE_OK);
2714977Sraghus 	}
2724977Sraghus 
2734977Sraghus 	if (!nxgep->vpd_info.ver_valid) {
2744977Sraghus 		goto read_seeprom;
2754977Sraghus 	}
2764977Sraghus 
2774977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2784977Sraghus 	    "Reading phy type from expansion ROM"));
2794977Sraghus 	/*
2804977Sraghus 	 * Try to read the phy type from the vpd data read off the
2814977Sraghus 	 * expansion ROM.
2824977Sraghus 	 */
2834977Sraghus 	phy_type = nxgep->vpd_info.phy_type;
2844977Sraghus 
2855196Ssbehera 	if (strncmp(phy_type, "mif", 3) == 0) {
2864977Sraghus 		nxgep->mac.portmode = PORT_1G_COPPER;
2874977Sraghus 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
2885196Ssbehera 	} else if (strncmp(phy_type, "xgf", 3) == 0) {
2894977Sraghus 		nxgep->mac.portmode = PORT_10G_FIBER;
2904977Sraghus 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
2915196Ssbehera 	} else if (strncmp(phy_type, "pcs", 3) == 0) {
2924977Sraghus 		nxgep->mac.portmode = PORT_1G_FIBER;
2934977Sraghus 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
2945196Ssbehera 	} else if (strncmp(phy_type, "xgc", 3) == 0) {
2954977Sraghus 		nxgep->mac.portmode = PORT_10G_COPPER;
2964977Sraghus 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
2975196Ssbehera 	} else if (strncmp(phy_type, "xgsd", 4) == 0) {
2985196Ssbehera 		nxgep->mac.portmode = PORT_10G_SERDES;
2995196Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3005196Ssbehera 	} else if (strncmp(phy_type, "gsd", 3) == 0) {
3015196Ssbehera 		nxgep->mac.portmode = PORT_1G_SERDES;
3025196Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3034977Sraghus 	} else {
3045196Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3054977Sraghus 		    "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
3064977Sraghus 		    phy_type[0], phy_type[1], phy_type[2]));
3074977Sraghus 		goto read_seeprom;
3084977Sraghus 	}
3094977Sraghus 
3104977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
3114977Sraghus 	    "Got phy type [0x%x] from VPD", nxgep->mac.portmode));
3124977Sraghus 
3134977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
3144977Sraghus 	return (status);
3154977Sraghus 
3164977Sraghus read_seeprom:
3174977Sraghus 	/*
3184977Sraghus 	 * read the phy type from the SEEPROM - NCR registers
3194977Sraghus 	 */
3204977Sraghus 	status = nxge_espc_phy_type_get(nxgep);
3214977Sraghus 	if (status != NXGE_OK) {
3224977Sraghus 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3234977Sraghus 		    "Failed to get phy type"));
3244977Sraghus 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
3254977Sraghus 		    "[%s] invalid...please update", nxgep->vpd_info.ver));
3264977Sraghus 	}
3274977Sraghus 
3284977Sraghus 	return (status);
3294977Sraghus 
3304977Sraghus }
3314977Sraghus 
3324732Sdavemq /* Set up the PHY specific values. */
3334732Sdavemq 
3344732Sdavemq nxge_status_t
3354732Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep)
3364732Sdavemq {
3374732Sdavemq 	nxge_status_t	status = NXGE_OK;
3384732Sdavemq 	uint32_t	port_type;
3394732Sdavemq 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
3404977Sraghus 	uint32_t	pcs_id = 0;
3414977Sraghus 	uint32_t	pma_pmd_id = 0;
3424977Sraghus 	uint32_t	phy_id = 0;
3434732Sdavemq 
3444732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>",
3454732Sdavemq 	    portn));
3464732Sdavemq 
3474977Sraghus 	switch (nxgep->niu_type) {
3484977Sraghus 	case N2_NIU:
3494977Sraghus 		switch (nxgep->mac.portmode) {
3504977Sraghus 		case PORT_1G_FIBER:
3514977Sraghus 		case PORT_1G_SERDES:
3524977Sraghus 			nxgep->xcvr = nxge_n2_1G_table;
3534977Sraghus 			nxgep->xcvr.xcvr_addr = portn;
3544977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr",
3554977Sraghus 			    (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" :
3564977Sraghus 			    "Serdes"));
3574977Sraghus 			break;
3584977Sraghus 		case PORT_10G_FIBER:
3594977Sraghus 		case PORT_10G_SERDES:
3604977Sraghus 			nxgep->xcvr = nxge_n2_10G_table;
3614977Sraghus 			nxgep->xcvr.xcvr_addr += portn;
3624977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr",
3634977Sraghus 			    (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" :
3644977Sraghus 			    "Serdes"));
3654977Sraghus 			break;
3664977Sraghus 		default:
3674977Sraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3684977Sraghus 			    "<== nxge_setup_xcvr_table: "
3694977Sraghus 			    "Unable to determine NIU portmode"));
3704977Sraghus 			return (NXGE_ERROR);
3714977Sraghus 		}
3724977Sraghus 		break;
3734977Sraghus 	default:
3744977Sraghus 		if (nxgep->mac.portmode == 0) {
3754977Sraghus 			/*
3764977Sraghus 			 * Would be the case for platforms like Maramba
3774977Sraghus 			 * in which the phy type could not be got from conf
3784977Sraghus 			 * file, OBP, VPD or Serial PROM.
3794977Sraghus 			 */
3804977Sraghus 			if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
3814977Sraghus 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3824977Sraghus 				    "<== nxge_setup_xcvr_table:"
3834977Sraghus 				    " Invalid Neptune type [0x%x]",
3844977Sraghus 				    nxgep->niu_type));
3854977Sraghus 				return (NXGE_ERROR);
3864977Sraghus 			}
3874977Sraghus 
3884977Sraghus 			port_type = nxgep->niu_type >>
3894977Sraghus 			    (NXGE_PORT_TYPE_SHIFT * portn);
3904977Sraghus 			port_type = port_type & (NXGE_PORT_TYPE_MASK);
3914977Sraghus 
3924977Sraghus 			switch (port_type) {
3934977Sraghus 
3944977Sraghus 			case NXGE_PORT_1G_COPPER:
3954977Sraghus 				nxgep->mac.portmode = PORT_1G_COPPER;
3964977Sraghus 				break;
3974977Sraghus 			case NXGE_PORT_10G_COPPER:
3984977Sraghus 				nxgep->mac.portmode = PORT_10G_COPPER;
3994977Sraghus 				break;
4004977Sraghus 			case NXGE_PORT_1G_FIBRE:
4014977Sraghus 				nxgep->mac.portmode = PORT_1G_FIBER;
4024977Sraghus 				break;
4034977Sraghus 			case NXGE_PORT_10G_FIBRE:
4044977Sraghus 				nxgep->mac.portmode = PORT_10G_FIBER;
4054977Sraghus 				break;
4064977Sraghus 			case NXGE_PORT_1G_SERDES:
4074977Sraghus 				nxgep->mac.portmode = PORT_1G_SERDES;
4084977Sraghus 				break;
4094977Sraghus 			case NXGE_PORT_10G_SERDES:
4104977Sraghus 				nxgep->mac.portmode = PORT_10G_SERDES;
4114977Sraghus 				break;
4124977Sraghus 			case NXGE_PORT_1G_RGMII_FIBER:
4134977Sraghus 				nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
4144977Sraghus 				break;
4154977Sraghus 			default:
4164977Sraghus 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4174977Sraghus 				    "<== nxge_setup_xcvr_table: "
4184977Sraghus 				    "Unknown port-type: 0x%x", port_type));
4194977Sraghus 				return (NXGE_ERROR);
4204977Sraghus 			}
4214977Sraghus 		}
4224977Sraghus 
4234977Sraghus 		switch (nxgep->mac.portmode) {
4244977Sraghus 		case PORT_1G_COPPER:
4254977Sraghus 		case PORT_1G_RGMII_FIBER:
4264732Sdavemq 			nxgep->xcvr = nxge_1G_copper_table;
4274977Sraghus 
4284977Sraghus 			/*
4294977Sraghus 			 * For Altas 4-1G copper, Xcvr port numbers are
4304977Sraghus 			 * swapped with ethernet port number. This is
4314977Sraghus 			 * designed for better signal integrity in
4324977Sraghus 			 * routing. This is also the case for the
4334977Sraghus 			 * on-board Neptune copper ports on the Maramba
4344977Sraghus 			 * platform.
4354977Sraghus 			 */
4364977Sraghus 			switch (nxgep->platform_type) {
4374977Sraghus 			case P_NEPTUNE_MARAMBA_P1:
4384732Sdavemq 				nxgep->xcvr.xcvr_addr =
4394732Sdavemq 				    BCM5464_MARAMBA_P1_PORT_ADDR_BASE;
4404977Sraghus 				break;
4414977Sraghus 			case P_NEPTUNE_MARAMBA_P0:
4424732Sdavemq 				nxgep->xcvr.xcvr_addr =
4434732Sdavemq 				    BCM5464_MARAMBA_P0_PORT_ADDR_BASE;
4444977Sraghus 				break;
4454977Sraghus 			default:
4464977Sraghus 				break;
4474732Sdavemq 			}
4484732Sdavemq 			/*
4494732Sdavemq 			 * For Altas 4-1G copper, Xcvr port numbers are
4504732Sdavemq 			 * swapped with ethernet port number. This is
4514977Sraghus 			 * designed for better signal integrity in
4524977Sraghus 			 * routing. This is also the case for the
4534977Sraghus 			 * on-board Neptune copper ports on the Maramba
4544977Sraghus 			 * platform.
4554732Sdavemq 			 */
4564977Sraghus 			switch (nxgep->platform_type) {
4574977Sraghus 			case P_NEPTUNE_ATLAS_4PORT:
4584977Sraghus 			case P_NEPTUNE_MARAMBA_P0:
4594977Sraghus 			case P_NEPTUNE_MARAMBA_P1:
4604977Sraghus 				switch (portn) {
4614977Sraghus 				case 0:
4624977Sraghus 					nxgep->xcvr.xcvr_addr += 3;
4634977Sraghus 					break;
4644977Sraghus 				case 1:
4654977Sraghus 					nxgep->xcvr.xcvr_addr += 2;
4664977Sraghus 					break;
4674977Sraghus 				case 2:
4684977Sraghus 					nxgep->xcvr.xcvr_addr += 1;
4694977Sraghus 					break;
4704977Sraghus 				case 3:
4714977Sraghus 					break;
4724977Sraghus 				default:
4734977Sraghus 					return (NXGE_ERROR);
4744977Sraghus 				}
4754732Sdavemq 				break;
4765196Ssbehera 			case P_NEPTUNE_ALONSO:
4775196Ssbehera 			/*
4785196Ssbehera 			 * The Alonso Neptune, xcvr port numbers for
4795196Ssbehera 			 * ports 2 and 3 are not swapped. Port 2 has
4805196Ssbehera 			 * the BCM5464_PORT_BASE_ADDR and port 3 has
4815196Ssbehera 			 * next address.
4825196Ssbehera 			 */
4835196Ssbehera 				if (portn == 3) {
4845196Ssbehera 					nxgep->xcvr.xcvr_addr += 1;
4855196Ssbehera 				}
4865196Ssbehera 				break;
4874732Sdavemq 			default:
4884977Sraghus 				break;
4894732Sdavemq 			}
4905196Ssbehera 
4914977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
4924977Sraghus 			    (nxgep->mac.portmode == PORT_1G_COPPER) ?
4934977Sraghus 			    "Copper" : "RGMII Fiber"));
4944732Sdavemq 			break;
4954977Sraghus 		case PORT_10G_COPPER:
4964732Sdavemq 			nxgep->xcvr = nxge_10G_copper_table;
4974732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
4984732Sdavemq 			break;
4994977Sraghus 		case PORT_1G_FIBER:
5004977Sraghus 		case PORT_1G_SERDES:
5014732Sdavemq 			nxgep->xcvr = nxge_1G_fiber_table;
5024977Sraghus 			nxgep->xcvr.xcvr_addr = portn;
5034977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
5044977Sraghus 			    (nxgep->mac.portmode == PORT_1G_FIBER) ?
5054977Sraghus 			    "Fiber" : "Serdes"));
5064732Sdavemq 			break;
5074977Sraghus 		case PORT_10G_FIBER:
5084977Sraghus 		case PORT_10G_SERDES:
5094732Sdavemq 			nxgep->xcvr = nxge_10G_fiber_table;
5104977Sraghus 			switch (nxgep->platform_type) {
5114977Sraghus 			case P_NEPTUNE_MARAMBA_P0:
5124977Sraghus 			case P_NEPTUNE_MARAMBA_P1:
5134732Sdavemq 				nxgep->xcvr.xcvr_addr =
5144732Sdavemq 				    BCM8704_MARAMBA_PORT_ADDR_BASE;
5154732Sdavemq 				/*
5164732Sdavemq 				 * Switch off LED for corresponding copper
5174732Sdavemq 				 * port
5184732Sdavemq 				 */
5194732Sdavemq 				nxge_bcm5464_link_led_off(nxgep);
5204977Sraghus 				break;
5214977Sraghus 			default:
5224977Sraghus 				break;
5234732Sdavemq 			}
5244732Sdavemq 			nxgep->xcvr.xcvr_addr += portn;
5254977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr",
5264977Sraghus 			    (nxgep->mac.portmode == PORT_10G_FIBER) ?
5274977Sraghus 			    "Fiber" : "Serdes"));
5284732Sdavemq 			break;
5294732Sdavemq 		default:
5304732Sdavemq 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5314732Sdavemq 			    "Unknown port-type: 0x%x", port_type));
5324732Sdavemq 			return (NXGE_ERROR);
5334732Sdavemq 		}
5344732Sdavemq 	}
5354732Sdavemq 
5364732Sdavemq 	nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse;
5374732Sdavemq 	nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr.xcvr_addr;
5384977Sraghus 
5394977Sraghus 	/*
5404977Sraghus 	 * Get the actual device ID value returned by MDIO read.
5414977Sraghus 	 */
5424977Sraghus 	nxgep->statsp->mac_stats.xcvr_id = 0;
5434977Sraghus 
5444977Sraghus 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr.xcvr_addr);
5454977Sraghus 	if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) {
5464977Sraghus 		nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id;
5474977Sraghus 	} else {
5484977Sraghus 		pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr.xcvr_addr);
5494977Sraghus 		if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) {
5504977Sraghus 			nxgep->statsp->mac_stats.xcvr_id = pcs_id;
5514977Sraghus 		} else {
5524977Sraghus 			phy_id = nxge_get_cl22_phy_id(nxgep,
5534977Sraghus 			    nxgep->xcvr.xcvr_addr);
5544977Sraghus 			if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
5554977Sraghus 				nxgep->statsp->mac_stats.xcvr_id = phy_id;
5564977Sraghus 			}
5574977Sraghus 		}
5584977Sraghus 	}
5594977Sraghus 
5604732Sdavemq 	nxgep->mac.linkchkmode = LINKCHK_TIMER;
5614732Sdavemq 
5624977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type"
5634977Sraghus 	    "[0x%x] platform type[0x%x]", nxgep->niu_type,
5644977Sraghus 	    nxgep->platform_type));
5654977Sraghus 
5664732Sdavemq 	return (status);
5674732Sdavemq }
5684732Sdavemq 
5693859Sml29623 /* Initialize the entire MAC and physical layer */
5703859Sml29623 
5713859Sml29623 nxge_status_t
5723859Sml29623 nxge_mac_init(p_nxge_t nxgep)
5733859Sml29623 {
5743859Sml29623 	uint8_t			portn;
5753859Sml29623 	nxge_status_t		status = NXGE_OK;
5763859Sml29623 
5773859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
5783859Sml29623 
5793859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn));
5803859Sml29623 
5813859Sml29623 	nxgep->mac.portnum = portn;
5823859Sml29623 	nxgep->mac.porttype = PORT_TYPE_XMAC;
5833859Sml29623 
5843859Sml29623 	if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1))
5853859Sml29623 		nxgep->mac.porttype = PORT_TYPE_BMAC;
5863859Sml29623 
5873859Sml29623 	/* Initialize XIF to configure a network mode */
5883859Sml29623 	if ((status = nxge_xif_init(nxgep)) != NXGE_OK) {
5893859Sml29623 		goto fail;
5903859Sml29623 	}
5913859Sml29623 
5923859Sml29623 	if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) {
5933859Sml29623 		goto fail;
5943859Sml29623 	}
5953859Sml29623 
5963859Sml29623 	/* Initialize TX and RX MACs */
5973859Sml29623 	/*
5983859Sml29623 	 * Always perform XIF init first, before TX and RX MAC init
5993859Sml29623 	 */
6003859Sml29623 	if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK)
6013859Sml29623 		goto fail;
6023859Sml29623 
6033859Sml29623 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
6043859Sml29623 		goto fail;
6053859Sml29623 
6063859Sml29623 	if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK)
6073859Sml29623 		goto fail;
6083859Sml29623 
6093859Sml29623 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
6103859Sml29623 		goto fail;
6113859Sml29623 
6123859Sml29623 	if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK)
6133859Sml29623 		goto fail;
6143859Sml29623 
6153859Sml29623 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
6163859Sml29623 		goto fail;
6173859Sml29623 
618*5553Smisaki 	/* Initialize MAC control configuration */
619*5553Smisaki 	if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) {
620*5553Smisaki 		goto fail;
621*5553Smisaki 	}
622*5553Smisaki 
6233859Sml29623 	nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize;
6243859Sml29623 
6255196Ssbehera 	/* The Neptune Serdes needs to be reinitialized again */
6265196Ssbehera 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
6275196Ssbehera 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
6285196Ssbehera 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
6295196Ssbehera 	    ((portn == 0) || (portn == 1))) {
6305196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6315196Ssbehera 		    "nxge_mac_init: reinit Neptune 1G Serdes "));
6325196Ssbehera 		if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) {
6335196Ssbehera 			goto fail;
6345196Ssbehera 		}
6355196Ssbehera 	}
6365196Ssbehera 
6374977Sraghus 
6383859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn));
6393859Sml29623 
6403859Sml29623 	return (NXGE_OK);
6413859Sml29623 fail:
6423859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6433859Sml29623 			"nxge_mac_init: failed to initialize MAC port<%d>",
6443859Sml29623 			portn));
6453859Sml29623 	return (status);
6463859Sml29623 }
6473859Sml29623 
6483859Sml29623 /* Initialize the Ethernet Link */
6493859Sml29623 
6503859Sml29623 nxge_status_t
6513859Sml29623 nxge_link_init(p_nxge_t nxgep)
6523859Sml29623 {
6533859Sml29623 	nxge_status_t		status = NXGE_OK;
6544977Sraghus 	nxge_port_mode_t	portmode;
6553859Sml29623 #ifdef	NXGE_DEBUG
6563859Sml29623 	uint8_t			portn;
6573859Sml29623 
6583859Sml29623 	portn = nxgep->mac.portnum;
6593859Sml29623 
6603859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn));
6613859Sml29623 #endif
6623859Sml29623 
6634977Sraghus 	portmode = nxgep->mac.portmode;
6644977Sraghus 	if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) &&
6654977Sraghus 	    (portmode != PORT_1G_SERDES)) {
6663859Sml29623 		/* Workaround to get link up in both NIU ports */
6674977Sraghus 		if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) {
6683859Sml29623 			goto fail;
6694977Sraghus 		}
6703859Sml29623 	}
6713859Sml29623 	NXGE_DELAY(200000);
6723859Sml29623 	/* Initialize internal serdes */
6733859Sml29623 	if ((status = nxge_serdes_init(nxgep)) != NXGE_OK)
6743859Sml29623 		goto fail;
6753859Sml29623 	NXGE_DELAY(200000);
6763859Sml29623 	if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
6773859Sml29623 		goto fail;
6783859Sml29623 
6793859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn));
6803859Sml29623 
6813859Sml29623 	return (NXGE_OK);
6823859Sml29623 
6833859Sml29623 fail:
6843859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6853859Sml29623 		"nxge_link_init: ",
6863859Sml29623 		"failed to initialize Ethernet link on port<%d>",
6873859Sml29623 		portn));
6883859Sml29623 
6893859Sml29623 	return (status);
6903859Sml29623 }
6913859Sml29623 
6923859Sml29623 
6933859Sml29623 /* Initialize the XIF sub-block within the MAC */
6943859Sml29623 
6953859Sml29623 nxge_status_t
6963859Sml29623 nxge_xif_init(p_nxge_t nxgep)
6973859Sml29623 {
6983859Sml29623 	uint32_t		xif_cfg = 0;
6993859Sml29623 	npi_attr_t		ap;
7003859Sml29623 	uint8_t			portn;
7013859Sml29623 	nxge_port_t		portt;
7023859Sml29623 	nxge_port_mode_t	portmode;
7033859Sml29623 	p_nxge_stats_t		statsp;
7043859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
7053859Sml29623 	npi_handle_t		handle;
7063859Sml29623 
7073859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
7083859Sml29623 
7093859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn));
7103859Sml29623 
7113859Sml29623 	handle = nxgep->npi_handle;
7123859Sml29623 	portmode = nxgep->mac.portmode;
7133859Sml29623 	portt = nxgep->mac.porttype;
7143859Sml29623 	statsp = nxgep->statsp;
7153859Sml29623 
7165196Ssbehera 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
7175196Ssbehera 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
7185196Ssbehera 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
7195196Ssbehera 	    ((portn == 0) || (portn == 1))) {
7205196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
7215196Ssbehera 		    "nxge_xcvr_init: set ATCA mode"));
7225196Ssbehera 		npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE);
7235196Ssbehera 	}
7245196Ssbehera 
7253859Sml29623 	if (portt == PORT_TYPE_XMAC) {
7263859Sml29623 
7273859Sml29623 		/* Setup XIF Configuration for XMAC */
7283859Sml29623 
7293859Sml29623 		if ((portmode == PORT_10G_FIBER) ||
7304977Sraghus 		    (portmode == PORT_10G_COPPER) ||
7314977Sraghus 		    (portmode == PORT_10G_SERDES))
7323859Sml29623 			xif_cfg |= CFG_XMAC_XIF_LFS;
7333859Sml29623 
7343859Sml29623 		if (portmode == PORT_1G_COPPER) {
7353859Sml29623 			xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS;
7363859Sml29623 		}
7373859Sml29623 
7383859Sml29623 		/* Set MAC Internal Loopback if necessary */
7393859Sml29623 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
7403859Sml29623 			xif_cfg |= CFG_XMAC_XIF_LOOPBACK;
7413859Sml29623 
7423859Sml29623 		if (statsp->mac_stats.link_speed == 100)
7433859Sml29623 			xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ;
7443859Sml29623 
7453859Sml29623 		xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT;
7463859Sml29623 
7474977Sraghus 		if ((portmode == PORT_10G_FIBER) ||
7484977Sraghus 		    (portmode == PORT_10G_SERDES)) {
7493859Sml29623 			if (statsp->mac_stats.link_up) {
7503859Sml29623 				xif_cfg |= CFG_XMAC_XIF_LED_POLARITY;
7513859Sml29623 			} else {
7523859Sml29623 				xif_cfg |= CFG_XMAC_XIF_LED_FORCE;
7533859Sml29623 			}
7543859Sml29623 		}
7553859Sml29623 
7563859Sml29623 		rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg);
7573859Sml29623 		if (rs != NPI_SUCCESS)
7583859Sml29623 			goto fail;
7593859Sml29623 
7603859Sml29623 		nxgep->mac.xif_config = xif_cfg;
7613859Sml29623 
7623859Sml29623 		/* Set Port Mode */
7633859Sml29623 		if ((portmode == PORT_10G_FIBER) ||
7644977Sraghus 		    (portmode == PORT_10G_COPPER) ||
7654977Sraghus 		    (portmode == PORT_10G_SERDES)) {
7663859Sml29623 			SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
7673859Sml29623 						MAC_XGMII_MODE, rs);
7683859Sml29623 			if (rs != NPI_SUCCESS)
7693859Sml29623 				goto fail;
7703859Sml29623 			if (statsp->mac_stats.link_up) {
7713859Sml29623 				if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
7723859Sml29623 					goto fail;
7733859Sml29623 			} else {
7743859Sml29623 				if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
7753859Sml29623 					goto fail;
7763859Sml29623 			}
7773859Sml29623 		} else if ((portmode == PORT_1G_FIBER) ||
7784977Sraghus 		    (portmode == PORT_1G_COPPER) ||
7795196Ssbehera 		    (portmode == PORT_1G_SERDES) ||
7805196Ssbehera 		    (portmode == PORT_1G_RGMII_FIBER)) {
7815196Ssbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
7825196Ssbehera 			    "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]",
7835196Ssbehera 			    portn, portmode, statsp->mac_stats.link_speed));
7843859Sml29623 			if (statsp->mac_stats.link_speed == 1000) {
7853859Sml29623 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
7863859Sml29623 							MAC_GMII_MODE, rs);
7873859Sml29623 			} else {
7883859Sml29623 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
7893859Sml29623 							MAC_MII_MODE, rs);
7903859Sml29623 			}
7913859Sml29623 			if (rs != NPI_SUCCESS)
7923859Sml29623 				goto fail;
7933859Sml29623 		} else {
7943859Sml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
7953859Sml29623 					"nxge_xif_init: Unknown port mode (%d)"
7963859Sml29623 					" for port<%d>", portmode, portn));
7973859Sml29623 			goto fail;
7983859Sml29623 		}
7993859Sml29623 
8005196Ssbehera 		/* Enable ATCA mode */
8015196Ssbehera 
8023859Sml29623 	} else if (portt == PORT_TYPE_BMAC) {
8033859Sml29623 
8043859Sml29623 		/* Setup XIF Configuration for BMAC */
8053859Sml29623 
8065196Ssbehera 		if ((portmode == PORT_1G_COPPER) ||
8075196Ssbehera 		    (portmode == PORT_1G_RGMII_FIBER)) {
8083859Sml29623 			if (statsp->mac_stats.link_speed == 100)
8093859Sml29623 				xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ;
8103859Sml29623 		}
8113859Sml29623 
8123859Sml29623 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
8133859Sml29623 			xif_cfg |= CFG_BMAC_XIF_LOOPBACK;
8143859Sml29623 
8153859Sml29623 		if (statsp->mac_stats.link_speed == 1000)
8163859Sml29623 			xif_cfg |= CFG_BMAC_XIF_GMII_MODE;
8173859Sml29623 
8183859Sml29623 		xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT;
8193859Sml29623 
8203859Sml29623 		rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg);
8213859Sml29623 		if (rs != NPI_SUCCESS)
8223859Sml29623 			goto fail;
8233859Sml29623 		nxgep->mac.xif_config = xif_cfg;
8243859Sml29623 	}
8253859Sml29623 
8263859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn));
8273859Sml29623 	return (NXGE_OK);
8283859Sml29623 fail:
8293859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8303859Sml29623 			"nxge_xif_init: Failed to initialize XIF port<%d>",
8313859Sml29623 			portn));
8323859Sml29623 	return (NXGE_ERROR | rs);
8333859Sml29623 }
8343859Sml29623 
8353859Sml29623 /* Initialize the PCS sub-block in the MAC */
8363859Sml29623 
8373859Sml29623 nxge_status_t
8383859Sml29623 nxge_pcs_init(p_nxge_t nxgep)
8393859Sml29623 {
8403859Sml29623 	pcs_cfg_t		pcs_cfg;
8413859Sml29623 	uint32_t		val;
8423859Sml29623 	uint8_t			portn;
8433859Sml29623 	nxge_port_mode_t	portmode;
8443859Sml29623 	npi_handle_t		handle;
8453859Sml29623 	p_nxge_stats_t		statsp;
8463859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
8473859Sml29623 
8483859Sml29623 	handle = nxgep->npi_handle;
8493859Sml29623 	portmode = nxgep->mac.portmode;
8503859Sml29623 	portn = nxgep->mac.portnum;
8513859Sml29623 	statsp = nxgep->statsp;
8523859Sml29623 
8533859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn));
8543859Sml29623 
8554977Sraghus 	if ((portmode == PORT_1G_FIBER) || (portmode == PORT_1G_SERDES)) {
8564977Sraghus 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) {
8574977Sraghus 			goto fail;
8584977Sraghus 		}
8594977Sraghus 
8603859Sml29623 		/* Initialize port's PCS */
8613859Sml29623 		pcs_cfg.value = 0;
8623859Sml29623 		pcs_cfg.bits.w0.enable = 1;
8633859Sml29623 		pcs_cfg.bits.w0.mask = 1;
8643859Sml29623 		PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value);
8653859Sml29623 		PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0);
8664977Sraghus 
8674977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8684977Sraghus 		    "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx",
8694977Sraghus 		    portn, pcs_cfg.value));
8703859Sml29623 	} else if ((portmode == PORT_10G_FIBER) ||
8714977Sraghus 	    (portmode == PORT_10G_COPPER) || (portmode == PORT_10G_SERDES)) {
8723859Sml29623 		/* Use internal XPCS, bypass 1G PCS */
8733859Sml29623 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
8743859Sml29623 		val &= ~XMAC_XIF_XPCS_BYPASS;
8753859Sml29623 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
8763859Sml29623 
8773859Sml29623 		if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS)
8783859Sml29623 			goto fail;
8793859Sml29623 
8803859Sml29623 		/* Set XPCS Internal Loopback if necessary */
8813859Sml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
8823859Sml29623 						XPCS_REG_CONTROL1, &val))
8833859Sml29623 						!= NPI_SUCCESS)
8843859Sml29623 			goto fail;
8853859Sml29623 		if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) ||
8863859Sml29623 			(statsp->port_stats.lb_mode == nxge_lb_mac1000))
8873859Sml29623 			val |= XPCS_CTRL1_LOOPBK;
8883859Sml29623 		else
8893859Sml29623 			val &= ~XPCS_CTRL1_LOOPBK;
8903859Sml29623 		if ((rs = npi_xmac_xpcs_write(handle, portn,
8913859Sml29623 						XPCS_REG_CONTROL1, val))
8923859Sml29623 						!= NPI_SUCCESS)
8933859Sml29623 			goto fail;
8943859Sml29623 
8953859Sml29623 		/* Clear descw errors */
8963859Sml29623 		if ((rs = npi_xmac_xpcs_write(handle, portn,
8973859Sml29623 						XPCS_REG_DESCWERR_COUNTER, 0))
8983859Sml29623 						!= NPI_SUCCESS)
8993859Sml29623 			goto fail;
9003859Sml29623 		/* Clear symbol errors */
9013859Sml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
9023859Sml29623 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val))
9033859Sml29623 					!= NPI_SUCCESS)
9043859Sml29623 			goto fail;
9053859Sml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
9063859Sml29623 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val))
9073859Sml29623 					!= NPI_SUCCESS)
9083859Sml29623 			goto fail;
9093859Sml29623 
9105196Ssbehera 	} else if ((portmode == PORT_1G_COPPER) ||
9115196Ssbehera 	    (portmode == PORT_1G_RGMII_FIBER)) {
9125196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
9135196Ssbehera 		    "==> nxge_pcs_init: (1G) copper port<%d>", portn));
9143859Sml29623 		if (portn < 4) {
9153859Sml29623 			PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG,
9163859Sml29623 					PCS_DATAPATH_MODE_MII);
9173859Sml29623 		}
9183859Sml29623 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
9193859Sml29623 			goto fail;
9203859Sml29623 
9213859Sml29623 	} else {
9223859Sml29623 		goto fail;
9233859Sml29623 	}
9243859Sml29623 pass:
9253859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn));
9263859Sml29623 	return (NXGE_OK);
9273859Sml29623 fail:
9283859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
9293859Sml29623 			"nxge_pcs_init: Failed to initialize PCS port<%d>",
9303859Sml29623 			portn));
9313859Sml29623 	return (NXGE_ERROR | rs);
9323859Sml29623 }
9333859Sml29623 
934*5553Smisaki /*
935*5553Smisaki  * Initialize the MAC CTRL sub-block within the MAC
936*5553Smisaki  * Only the receive-pause-cap is supported.
937*5553Smisaki  */
938*5553Smisaki nxge_status_t
939*5553Smisaki nxge_mac_ctrl_init(p_nxge_t nxgep)
940*5553Smisaki {
941*5553Smisaki 	uint8_t			portn;
942*5553Smisaki 	nxge_port_t		portt;
943*5553Smisaki 	p_nxge_stats_t		statsp;
944*5553Smisaki 	npi_handle_t		handle;
945*5553Smisaki 	uint32_t		val;
946*5553Smisaki 
947*5553Smisaki 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
948*5553Smisaki 
949*5553Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>",
950*5553Smisaki 	    portn));
951*5553Smisaki 
952*5553Smisaki 	handle = nxgep->npi_handle;
953*5553Smisaki 	portt = nxgep->mac.porttype;
954*5553Smisaki 	statsp = nxgep->statsp;
955*5553Smisaki 
956*5553Smisaki 	if (portt == PORT_TYPE_XMAC) {
957*5553Smisaki 		/* Readin the current XMAC Config Register for XMAC */
958*5553Smisaki 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
959*5553Smisaki 
960*5553Smisaki 		/*
961*5553Smisaki 		 * Setup XMAC Configuration for XMAC
962*5553Smisaki 		 * XMAC only supports receive-pause
963*5553Smisaki 		 */
964*5553Smisaki 		if (statsp->mac_stats.adv_cap_asmpause) {
965*5553Smisaki 			if (!statsp->mac_stats.adv_cap_pause) {
966*5553Smisaki 				/*
967*5553Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
968*5553Smisaki 				 * is 0, enable receive pause.
969*5553Smisaki 				 */
970*5553Smisaki 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
971*5553Smisaki 			} else {
972*5553Smisaki 				/*
973*5553Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
974*5553Smisaki 				 * is 1, disable receive pause.  Send pause is
975*5553Smisaki 				 * not supported.
976*5553Smisaki 				 */
977*5553Smisaki 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
978*5553Smisaki 			}
979*5553Smisaki 		} else {
980*5553Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
981*5553Smisaki 				/*
982*5553Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
983*5553Smisaki 				 * is 1, enable receive pause.
984*5553Smisaki 				 */
985*5553Smisaki 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
986*5553Smisaki 			} else {
987*5553Smisaki 				/*
988*5553Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
989*5553Smisaki 				 * is 0, disable receive pause. Send pause is
990*5553Smisaki 				 * not supported
991*5553Smisaki 				 */
992*5553Smisaki 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
993*5553Smisaki 			}
994*5553Smisaki 		}
995*5553Smisaki 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
996*5553Smisaki 	} else if (portt == PORT_TYPE_BMAC) {
997*5553Smisaki 		/* Readin the current MAC CTRL Config Register for BMAC */
998*5553Smisaki 		BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val);
999*5553Smisaki 
1000*5553Smisaki 		/* Setup MAC CTRL Configuration for BMAC */
1001*5553Smisaki 		if (statsp->mac_stats.adv_cap_asmpause) {
1002*5553Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
1003*5553Smisaki 				/*
1004*5553Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1005*5553Smisaki 				 * is 1, disable receive pause. Send pause
1006*5553Smisaki 				 * is not supported
1007*5553Smisaki 				 */
1008*5553Smisaki 				val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN;
1009*5553Smisaki 			} else {
1010*5553Smisaki 				/*
1011*5553Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1012*5553Smisaki 				 * is 0, enable receive pause and disable
1013*5553Smisaki 				 * send pause.
1014*5553Smisaki 				 */
1015*5553Smisaki 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
1016*5553Smisaki 				val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN;
1017*5553Smisaki 			}
1018*5553Smisaki 		} else {
1019*5553Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
1020*5553Smisaki 				/*
1021*5553Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1022*5553Smisaki 				 * is 1, enable receive pause. Send pause is
1023*5553Smisaki 				 * not supported.
1024*5553Smisaki 				 */
1025*5553Smisaki 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
1026*5553Smisaki 			} else {
1027*5553Smisaki 				/*
1028*5553Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1029*5553Smisaki 				 * is 0, pause capability is not available in
1030*5553Smisaki 				 * either direction.
1031*5553Smisaki 				 */
1032*5553Smisaki 				val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN &
1033*5553Smisaki 					~MAC_CTRL_CFG_RECV_PAUSE_EN);
1034*5553Smisaki 			}
1035*5553Smisaki 		}
1036*5553Smisaki 		BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val);
1037*5553Smisaki 	}
1038*5553Smisaki 
1039*5553Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>",
1040*5553Smisaki 	    portn));
1041*5553Smisaki 
1042*5553Smisaki 	return (NXGE_OK);
1043*5553Smisaki }
1044*5553Smisaki 
10453859Sml29623 /* Initialize the Internal Serdes */
10463859Sml29623 
10473859Sml29623 nxge_status_t
10483859Sml29623 nxge_serdes_init(p_nxge_t nxgep)
10493859Sml29623 {
10503859Sml29623 	p_nxge_stats_t		statsp;
10513859Sml29623 #ifdef	NXGE_DEBUG
10523859Sml29623 	uint8_t			portn;
10533859Sml29623 #endif
10543859Sml29623 	nxge_status_t		status = NXGE_OK;
10553859Sml29623 
10563859Sml29623 #ifdef	NXGE_DEBUG
10573859Sml29623 	portn = nxgep->mac.portnum;
10583859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
10594732Sdavemq 	    "==> nxge_serdes_init port<%d>", portn));
10603859Sml29623 #endif
10613859Sml29623 
10624732Sdavemq 	if (nxgep->xcvr.serdes_init) {
10634732Sdavemq 		statsp = nxgep->statsp;
10644732Sdavemq 		status = nxgep->xcvr.serdes_init(nxgep);
10654732Sdavemq 		if (status != NXGE_OK)
10663859Sml29623 			goto fail;
10674732Sdavemq 		statsp->mac_stats.serdes_inits++;
10683859Sml29623 	}
10693859Sml29623 
10703859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
10714732Sdavemq 	    portn));
10723859Sml29623 
10733859Sml29623 	return (NXGE_OK);
10743859Sml29623 
10753859Sml29623 fail:
10763859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
10774732Sdavemq 	    "nxge_serdes_init: Failed to initialize serdes for port<%d>",
10784732Sdavemq 	    portn));
10793859Sml29623 
10803859Sml29623 	return (status);
10813859Sml29623 }
10823859Sml29623 
10833859Sml29623 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
10843859Sml29623 
10854732Sdavemq static nxge_status_t
10863859Sml29623 nxge_n2_serdes_init(p_nxge_t nxgep)
10873859Sml29623 {
10883859Sml29623 	uint8_t portn;
10893859Sml29623 	int chan;
10903859Sml29623 	esr_ti_cfgpll_l_t pll_cfg_l;
10914977Sraghus 	esr_ti_cfgpll_l_t pll_sts_l;
10923859Sml29623 	esr_ti_cfgrx_l_t rx_cfg_l;
10933859Sml29623 	esr_ti_cfgrx_h_t rx_cfg_h;
10943859Sml29623 	esr_ti_cfgtx_l_t tx_cfg_l;
10953859Sml29623 	esr_ti_cfgtx_h_t tx_cfg_h;
10964977Sraghus #ifdef NXGE_DEBUG
10974977Sraghus 	esr_ti_testcfg_t cfg;
10984977Sraghus #endif
10993859Sml29623 	esr_ti_testcfg_t test_cfg;
11003859Sml29623 	nxge_status_t status = NXGE_OK;
11013859Sml29623 
11023859Sml29623 	portn = nxgep->mac.portnum;
11033859Sml29623 
11043859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>",
11053859Sml29623 			portn));
11063859Sml29623 
11073859Sml29623 	tx_cfg_l.value = 0;
11083859Sml29623 	tx_cfg_h.value = 0;
11093859Sml29623 	rx_cfg_l.value = 0;
11103859Sml29623 	rx_cfg_h.value = 0;
11113859Sml29623 	pll_cfg_l.value = 0;
11124977Sraghus 	pll_sts_l.value = 0;
11133859Sml29623 	test_cfg.value = 0;
11143859Sml29623 
11154977Sraghus 	if ((nxgep->mac.portmode == PORT_10G_FIBER) ||
11164977Sraghus 	    (nxgep->mac.portmode == PORT_10G_SERDES)) {
11173859Sml29623 		/* 0x0E01 */
11183859Sml29623 		tx_cfg_l.bits.entx = 1;
11193859Sml29623 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
11203859Sml29623 
11213859Sml29623 		/* 0x9101 */
11223859Sml29623 		rx_cfg_l.bits.enrx = 1;
11233859Sml29623 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
11243859Sml29623 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
11253859Sml29623 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
11263859Sml29623 
11273859Sml29623 		/* 0x0008 */
11283859Sml29623 		rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
11293859Sml29623 
11303859Sml29623 		/* Set loopback mode if necessary */
11313859Sml29623 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
11323859Sml29623 			tx_cfg_l.bits.entest = 1;
11333859Sml29623 			rx_cfg_l.bits.entest = 1;
11343859Sml29623 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
11353859Sml29623 			if ((status = nxge_mdio_write(nxgep, portn,
11363859Sml29623 				ESR_N2_DEV_ADDR,
11373859Sml29623 				ESR_N2_TEST_CFG_REG, test_cfg.value))
11383859Sml29623 				!= NXGE_OK)
11393859Sml29623 			goto fail;
11403859Sml29623 		}
11413859Sml29623 
11423859Sml29623 		/* Use default PLL value */
11433859Sml29623 
11444977Sraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
11454977Sraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
11463859Sml29623 
11473859Sml29623 		/* 0x0E21 */
11483859Sml29623 		tx_cfg_l.bits.entx = 1;
11493859Sml29623 		tx_cfg_l.bits.rate = CFGTX_RATE_HALF;
11503859Sml29623 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
11513859Sml29623 
11523859Sml29623 		/* 0x9121 */
11533859Sml29623 		rx_cfg_l.bits.enrx = 1;
11543859Sml29623 		rx_cfg_l.bits.rate = CFGRX_RATE_HALF;
11553859Sml29623 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
11563859Sml29623 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
11573859Sml29623 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
11583859Sml29623 
11594977Sraghus 		if (portn == 0) {
11604977Sraghus 			/* 0x8 */
11614977Sraghus 			rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
11624977Sraghus 		}
11633859Sml29623 
11643859Sml29623 		/* MPY = 0x100 */
11653859Sml29623 		pll_cfg_l.bits.mpy = CFGPLL_MPY_8X;
11663859Sml29623 
11673859Sml29623 		/* Set PLL */
11683859Sml29623 		pll_cfg_l.bits.enpll = 1;
11694977Sraghus 		pll_sts_l.bits.enpll = 1;
11703859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
11713859Sml29623 				ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value))
11723859Sml29623 				!= NXGE_OK)
11733859Sml29623 			goto fail;
11744977Sraghus 
11754977Sraghus 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
11764977Sraghus 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
11774977Sraghus 			goto fail;
11784977Sraghus 
11794977Sraghus #ifdef  NXGE_DEBUG
11804977Sraghus 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
11814977Sraghus 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
11824977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11834977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
11844977Sraghus 		    portn, pll_cfg_l.value, cfg.value));
11854977Sraghus 
11864977Sraghus 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
11874977Sraghus 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
11884977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11894977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
11904977Sraghus 		    portn, pll_sts_l.value, cfg.value));
11914977Sraghus #endif
11924977Sraghus 
11934977Sraghus 		/* Set loopback mode if necessary */
11944977Sraghus 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
11954977Sraghus 			tx_cfg_l.bits.entest = 1;
11964977Sraghus 			rx_cfg_l.bits.entest = 1;
11974977Sraghus 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
11984977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11994977Sraghus 			    "==> nxge_n2_serdes_init port<%d>: loopback 0x%x",
12004977Sraghus 			    portn, test_cfg.value));
12014977Sraghus 			if ((status = nxge_mdio_write(nxgep, portn,
12024977Sraghus 			    ESR_N2_DEV_ADDR,
12034977Sraghus 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
12044977Sraghus 				goto fail;
12054977Sraghus 			}
12064977Sraghus 		}
12073859Sml29623 	} else {
12083859Sml29623 		goto fail;
12093859Sml29623 	}
12103859Sml29623 
12113859Sml29623 	/*   MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
12123859Sml29623 
12133859Sml29623 	NXGE_DELAY(20);
12143859Sml29623 
12153859Sml29623 	/* init TX channels */
12163859Sml29623 	for (chan = 0; chan < 4; chan++) {
12173859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
12183859Sml29623 				ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value))
12193859Sml29623 				!= NXGE_OK)
12203859Sml29623 			goto fail;
12213859Sml29623 
12223859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
12233859Sml29623 				ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value))
12243859Sml29623 				!= NXGE_OK)
12253859Sml29623 			goto fail;
12264977Sraghus 
12274977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12284977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x",
12294977Sraghus 		    portn, chan, tx_cfg_l.value));
12304977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12314977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x",
12324977Sraghus 		    portn, chan, tx_cfg_h.value));
12333859Sml29623 	}
12343859Sml29623 
12353859Sml29623 	/* init RX channels */
12363859Sml29623 	for (chan = 0; chan < 4; chan++) {
12373859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
12383859Sml29623 				ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value))
12393859Sml29623 				!= NXGE_OK)
12403859Sml29623 			goto fail;
12413859Sml29623 
12423859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
12433859Sml29623 				ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value))
12443859Sml29623 				!= NXGE_OK)
12453859Sml29623 			goto fail;
12464977Sraghus 
12474977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12484977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x",
12494977Sraghus 		    portn, chan, rx_cfg_l.value));
12504977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12514977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x",
12524977Sraghus 		    portn, chan, rx_cfg_h.value));
12533859Sml29623 	}
12543859Sml29623 
12553859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>",
12563859Sml29623 			portn));
12573859Sml29623 
12583859Sml29623 	return (NXGE_OK);
12593859Sml29623 fail:
12603859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12613859Sml29623 	"nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
12623859Sml29623 				portn));
12633859Sml29623 
12643859Sml29623 	return (status);
12653859Sml29623 }
12663859Sml29623 
12674732Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
12684732Sdavemq 
12694732Sdavemq static nxge_status_t
12704732Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep)
12713859Sml29623 {
12723859Sml29623 	npi_handle_t		handle;
12733859Sml29623 	uint8_t			portn;
12743859Sml29623 	int			chan;
12753859Sml29623 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
12763859Sml29623 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
12773859Sml29623 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
12783859Sml29623 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
12793859Sml29623 	uint64_t		val;
12803859Sml29623 	uint16_t		val16l;
12813859Sml29623 	uint16_t		val16h;
12823859Sml29623 	nxge_status_t		status = NXGE_OK;
12833859Sml29623 
12843859Sml29623 	portn = nxgep->mac.portnum;
12853859Sml29623 
12863859Sml29623 	if ((portn != 0) && (portn != 1))
12873859Sml29623 		return (NXGE_OK);
12883859Sml29623 
12894732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12904732Sdavemq 	    "==> nxge_neptune_10G_serdes_init port<%d>", portn));
12913859Sml29623 
12923859Sml29623 	handle = nxgep->npi_handle;
12934732Sdavemq 	switch (portn) {
12944732Sdavemq 	case 0:
12954732Sdavemq 		ESR_REG_WR(handle, ESR_0_CONTROL_REG,
12964732Sdavemq 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
12974732Sdavemq 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
12984732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
12994732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
13004732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
13014732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
13024732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
13034732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
13044732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
13054732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
13064732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
13074732Sdavemq 
13084732Sdavemq 		/* Set Serdes0 Internal Loopback if necessary */
13094732Sdavemq 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
13104732Sdavemq 			ESR_REG_WR(handle,
13114732Sdavemq 			    ESR_0_TEST_CONFIG_REG,
13124732Sdavemq 			    ESR_PAD_LOOPBACK_CH3 |
13134732Sdavemq 			    ESR_PAD_LOOPBACK_CH2 |
13144732Sdavemq 			    ESR_PAD_LOOPBACK_CH1 |
13154732Sdavemq 			    ESR_PAD_LOOPBACK_CH0);
13164732Sdavemq 		} else {
13174732Sdavemq 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
13183859Sml29623 		}
13194732Sdavemq 		break;
13204732Sdavemq 	case 1:
13214732Sdavemq 		ESR_REG_WR(handle, ESR_1_CONTROL_REG,
13224732Sdavemq 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
13234732Sdavemq 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
13244732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
13254732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
13264732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
13274732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
13284732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
13294732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
13304732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
13314732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
13324732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
13334732Sdavemq 
13344732Sdavemq 		/* Set Serdes1 Internal Loopback if necessary */
13354732Sdavemq 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
13364732Sdavemq 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
13374732Sdavemq 			    ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 |
13384732Sdavemq 			    ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0);
13394732Sdavemq 		} else {
13404732Sdavemq 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
13413859Sml29623 		}
13424732Sdavemq 		break;
13434732Sdavemq 	default:
13444732Sdavemq 		/* Nothing to do here */
13454732Sdavemq 		goto done;
13464732Sdavemq 	}
13474732Sdavemq 
13484732Sdavemq 	/* init TX RX channels */
13494732Sdavemq 	for (chan = 0; chan < 4; chan++) {
13504732Sdavemq 		if ((status = nxge_mdio_read(nxgep, portn,
13514732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
13524732Sdavemq 		    &rx_tx_ctrl_l.value)) != NXGE_OK)
13533859Sml29623 			goto fail;
13544732Sdavemq 		if ((status = nxge_mdio_read(nxgep, portn,
13554732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
13564732Sdavemq 		    &rx_tx_ctrl_h.value)) != NXGE_OK)
13573859Sml29623 			goto fail;
13583859Sml29623 		if ((status = nxge_mdio_read(nxgep, portn,
13594732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
13604732Sdavemq 		    &glue_ctrl0_l.value)) != NXGE_OK)
13613859Sml29623 			goto fail;
13623859Sml29623 		if ((status = nxge_mdio_read(nxgep, portn,
13634732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
13644732Sdavemq 		    &glue_ctrl0_h.value)) != NXGE_OK)
13654732Sdavemq 			goto fail;
13664732Sdavemq 		rx_tx_ctrl_l.bits.enstretch = 1;
13674732Sdavemq 		rx_tx_ctrl_h.bits.vmuxlo = 2;
13684732Sdavemq 		rx_tx_ctrl_h.bits.vpulselo = 2;
13694732Sdavemq 		glue_ctrl0_l.bits.rxlosenable = 1;
13704732Sdavemq 		glue_ctrl0_l.bits.samplerate = 0xF;
13714732Sdavemq 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
13724732Sdavemq 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
13734732Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
13744732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
13754732Sdavemq 		    rx_tx_ctrl_l.value)) != NXGE_OK)
13764732Sdavemq 			goto fail;
13774732Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
13784732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
13794732Sdavemq 		    rx_tx_ctrl_h.value)) != NXGE_OK)
13804732Sdavemq 			goto fail;
13814732Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
13824732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
13834732Sdavemq 		    glue_ctrl0_l.value)) != NXGE_OK)
13844732Sdavemq 			goto fail;
13854732Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
13864732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
13874732Sdavemq 		    glue_ctrl0_h.value)) != NXGE_OK)
13883859Sml29623 			goto fail;
13893859Sml29623 		}
13903859Sml29623 
13914732Sdavemq 	/* Apply Tx core reset */
13924732Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn,
13934732Sdavemq 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
13944732Sdavemq 	    (uint16_t)0)) != NXGE_OK)
13954732Sdavemq 		goto fail;
13964732Sdavemq 
13974732Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
13984732Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
13994732Sdavemq 	    NXGE_OK)
14004732Sdavemq 		goto fail;
14014732Sdavemq 
14024732Sdavemq 	NXGE_DELAY(200);
14034732Sdavemq 
14044732Sdavemq 	/* Apply Rx core reset */
14054732Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
14064732Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
14074732Sdavemq 	    NXGE_OK)
14084732Sdavemq 		goto fail;
14094732Sdavemq 
14104732Sdavemq 	NXGE_DELAY(200);
14114732Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
14124732Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK)
14134732Sdavemq 		goto fail;
14144732Sdavemq 
14154732Sdavemq 	NXGE_DELAY(200);
14164732Sdavemq 	if ((status = nxge_mdio_read(nxgep, portn,
14174732Sdavemq 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
14184732Sdavemq 	    &val16l)) != NXGE_OK)
14194732Sdavemq 		goto fail;
14204732Sdavemq 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
14214732Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK)
14224732Sdavemq 		goto fail;
14234732Sdavemq 	if ((val16l != 0) || (val16h != 0)) {
14244732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14255196Ssbehera 		    "Failed to reset port<%d> XAUI Serdes "
14265196Ssbehera 		    "(val16l 0x%x val16h 0x%x)",
14275196Ssbehera 		    portn, val16l, val16h));
14284732Sdavemq 	}
14294732Sdavemq 
14304732Sdavemq 	ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
14314732Sdavemq 
14324732Sdavemq 	if (portn == 0) {
14334732Sdavemq 		if ((val & ESR_SIG_P0_BITS_MASK) !=
14343859Sml29623 				(ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
14353859Sml29623 					ESR_SIG_XSERDES_RDY_P0 |
14363859Sml29623 					ESR_SIG_XDETECT_P0_CH3 |
14373859Sml29623 					ESR_SIG_XDETECT_P0_CH2 |
14383859Sml29623 					ESR_SIG_XDETECT_P0_CH1 |
14393859Sml29623 					ESR_SIG_XDETECT_P0_CH0)) {
14404732Sdavemq 			goto fail;
14414732Sdavemq 		}
14424732Sdavemq 	} else if (portn == 1) {
14434732Sdavemq 		if ((val & ESR_SIG_P1_BITS_MASK) !=
14443859Sml29623 				(ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
14453859Sml29623 					ESR_SIG_XSERDES_RDY_P1 |
14463859Sml29623 					ESR_SIG_XDETECT_P1_CH3 |
14473859Sml29623 					ESR_SIG_XDETECT_P1_CH2 |
14483859Sml29623 					ESR_SIG_XDETECT_P1_CH1 |
14493859Sml29623 					ESR_SIG_XDETECT_P1_CH0)) {
14503859Sml29623 			goto fail;
14513859Sml29623 		}
14523859Sml29623 	}
14533859Sml29623 
14543859Sml29623 done:
14554732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14564732Sdavemq 	    "<== nxge_neptune_10G_serdes_init port<%d>", portn));
14574732Sdavemq 
14583859Sml29623 	return (NXGE_OK);
14593859Sml29623 fail:
14604732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14614732Sdavemq 	    "nxge_neptune_10G_serdes_init: "
14624732Sdavemq 	    "Failed to initialize Neptune serdes for port<%d>", portn));
14633859Sml29623 
14643859Sml29623 	return (status);
14653859Sml29623 }
14663859Sml29623 
14674732Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */
14684732Sdavemq 
14694732Sdavemq static nxge_status_t
14704732Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep)
14713859Sml29623 {
14724732Sdavemq 	npi_handle_t		handle;
14734732Sdavemq 	uint8_t			portn;
14745196Ssbehera 	int			chan;
14755196Ssbehera 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
14765196Ssbehera 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
14775196Ssbehera 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
14785196Ssbehera 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
14794732Sdavemq 	uint64_t		val;
14805196Ssbehera 	uint16_t		val16l;
14815196Ssbehera 	uint16_t		val16h;
14825196Ssbehera 	nxge_status_t		status = NXGE_OK;
14833859Sml29623 
14843859Sml29623 	portn = nxgep->mac.portnum;
14854732Sdavemq 
14864732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14874732Sdavemq 	    "==> nxge_1G_serdes_init port<%d>", portn));
14884732Sdavemq 
14894732Sdavemq 	handle = nxgep->npi_handle;
14904732Sdavemq 
14914732Sdavemq 	switch (portn) {
14924732Sdavemq 	case 0:
14935196Ssbehera 		/* Assert the reset register */
14945196Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
14955196Ssbehera 		val |= ESR_RESET_0;
14965196Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
14975196Ssbehera 
14985196Ssbehera 		/* Set the PLL register to 0x79 */
14995196Ssbehera 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
15005196Ssbehera 		    ESR_PLL_CFG_1G_SERDES);
15015196Ssbehera 
15025196Ssbehera 		/* Set the control register to 0x249249f */
15035196Ssbehera 		ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES);
15045196Ssbehera 
15055196Ssbehera 		/* Set Serdes0 Internal Loopback if necessary */
15065196Ssbehera 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
15075196Ssbehera 			/* Set pad loopback modes 0xaa */
15085196Ssbehera 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG,
15095196Ssbehera 			    ESR_TSTCFG_LBTEST_PAD);
15105196Ssbehera 		} else {
15115196Ssbehera 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
15125196Ssbehera 		}
15135196Ssbehera 
15145196Ssbehera 		/* Deassert the reset register */
15155196Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
15165196Ssbehera 		val &= ~ESR_RESET_0;
15175196Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
15184732Sdavemq 		break;
15195196Ssbehera 
15204732Sdavemq 	case 1:
15215196Ssbehera 		/* Assert the reset register */
15225196Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
15235196Ssbehera 		val |= ESR_RESET_1;
15245196Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
15255196Ssbehera 
15265196Ssbehera 		/* Set PLL register to 0x79 */
15275196Ssbehera 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
15285196Ssbehera 		    ESR_PLL_CFG_1G_SERDES);
15295196Ssbehera 
15305196Ssbehera 		/* Set the control register to 0x249249f */
15315196Ssbehera 		ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES);
15325196Ssbehera 
15335196Ssbehera 		/* Set Serdes1 Internal Loopback if necessary */
15345196Ssbehera 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
15355196Ssbehera 			/* Set pad loopback mode 0xaa */
15365196Ssbehera 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
15375196Ssbehera 			    ESR_TSTCFG_LBTEST_PAD);
15385196Ssbehera 		} else {
15395196Ssbehera 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
15405196Ssbehera 		}
15415196Ssbehera 
15425196Ssbehera 		/* Deassert the reset register */
15435196Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
15445196Ssbehera 		val &= ~ESR_RESET_1;
15455196Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
15464732Sdavemq 		break;
15475196Ssbehera 
15484732Sdavemq 	default:
15495196Ssbehera 		/* Nothing to do here */
15505196Ssbehera 		goto done;
15515196Ssbehera 	}
15525196Ssbehera 
15535196Ssbehera 	/* init TX RX channels */
15545196Ssbehera 	for (chan = 0; chan < 4; chan++) {
15555196Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
15565196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
15575196Ssbehera 		    &rx_tx_ctrl_l.value)) != NXGE_OK) {
15585196Ssbehera 			goto fail;
15595196Ssbehera 		}
15605196Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
15615196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
15625196Ssbehera 		    &rx_tx_ctrl_h.value)) != NXGE_OK) {
15635196Ssbehera 			goto fail;
15645196Ssbehera 		}
15655196Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
15665196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
15675196Ssbehera 		    &glue_ctrl0_l.value)) != NXGE_OK) {
15685196Ssbehera 			goto fail;
15695196Ssbehera 		}
15705196Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
15715196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
15725196Ssbehera 		    &glue_ctrl0_h.value)) != NXGE_OK) {
15735196Ssbehera 			goto fail;
15745196Ssbehera 		}
15755196Ssbehera 
15765196Ssbehera 		rx_tx_ctrl_l.bits.enstretch = 1;
15775196Ssbehera 		rx_tx_ctrl_h.bits.vmuxlo = 2;
15785196Ssbehera 		rx_tx_ctrl_h.bits.vpulselo = 2;
15795196Ssbehera 		glue_ctrl0_l.bits.rxlosenable = 1;
15805196Ssbehera 		glue_ctrl0_l.bits.samplerate = 0xF;
15815196Ssbehera 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
15825196Ssbehera 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
15835196Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
15845196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
15855196Ssbehera 		    rx_tx_ctrl_l.value)) != NXGE_OK) {
15865196Ssbehera 			goto fail;
15875196Ssbehera 		}
15885196Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
15895196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
15905196Ssbehera 		    rx_tx_ctrl_h.value)) != NXGE_OK) {
15915196Ssbehera 			goto fail;
15925196Ssbehera 		}
15935196Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
15945196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
15955196Ssbehera 		    glue_ctrl0_l.value)) != NXGE_OK) {
15965196Ssbehera 			goto fail;
15975196Ssbehera 		}
15985196Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
15995196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
16005196Ssbehera 		    glue_ctrl0_h.value)) != NXGE_OK) {
16015196Ssbehera 			goto fail;
16025196Ssbehera 		}
16035196Ssbehera 	}
16045196Ssbehera 
16055196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16065196Ssbehera 	    ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) {
16074732Sdavemq 		goto fail;
16083859Sml29623 	}
16095196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16105196Ssbehera 	    ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
16115196Ssbehera 		goto fail;
16125196Ssbehera 	}
16135196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16145196Ssbehera 	    ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) {
16155196Ssbehera 		goto fail;
16165196Ssbehera 	}
16175196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16185196Ssbehera 	    ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
16195196Ssbehera 		goto fail;
16205196Ssbehera 	}
16215196Ssbehera 
16225196Ssbehera 	/* Apply Tx core reset */
16235196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16245196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) {
16255196Ssbehera 		goto fail;
16265196Ssbehera 	}
16275196Ssbehera 
16285196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16295196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
16305196Ssbehera 	    NXGE_OK) {
16315196Ssbehera 		goto fail;
16325196Ssbehera 	}
16335196Ssbehera 
16345196Ssbehera 	NXGE_DELAY(200);
16355196Ssbehera 
16365196Ssbehera 	/* Apply Rx core reset */
16375196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16385196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
16395196Ssbehera 	    NXGE_OK) {
16405196Ssbehera 		goto fail;
16415196Ssbehera 	}
16425196Ssbehera 
16435196Ssbehera 	NXGE_DELAY(200);
16445196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16455196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) {
16465196Ssbehera 		goto fail;
16475196Ssbehera 	}
16485196Ssbehera 
16495196Ssbehera 	NXGE_DELAY(200);
16505196Ssbehera 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16515196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) {
16525196Ssbehera 		goto fail;
16535196Ssbehera 	}
16545196Ssbehera 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
16555196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) {
16565196Ssbehera 		goto fail;
16575196Ssbehera 	}
16585196Ssbehera 	if ((val16l != 0) || (val16h != 0)) {
16595196Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16605196Ssbehera 		    "Failed to reset port<%d> XAUI Serdes "
16615196Ssbehera 		    "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h));
16625196Ssbehera 		status = NXGE_ERROR;
16635196Ssbehera 		goto fail;
16645196Ssbehera 	}
16655196Ssbehera 
16665196Ssbehera 	NXGE_DELAY(200);
16675196Ssbehera 	ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
16685196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16695196Ssbehera 	    "nxge_neptune_serdes_init: read internal signal reg port<%d> "
16705196Ssbehera 	    "val 0x%x", portn, val));
16715196Ssbehera 	if (portn == 0) {
16725196Ssbehera 		if ((val & ESR_SIG_P0_BITS_MASK_1G) !=
16735196Ssbehera 		    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) {
16745196Ssbehera 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16755196Ssbehera 			    "nxge_neptune_serdes_init: "
16765196Ssbehera 			    "Failed to get Serdes up for port<%d> val 0x%x",
16775196Ssbehera 			    portn, (val & ESR_SIG_P0_BITS_MASK)));
16785196Ssbehera 			status = NXGE_ERROR;
16795196Ssbehera 			goto fail;
16805196Ssbehera 		}
16815196Ssbehera 	} else if (portn == 1) {
16825196Ssbehera 		if ((val & ESR_SIG_P1_BITS_MASK_1G) !=
16835196Ssbehera 		    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) {
16845196Ssbehera 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16855196Ssbehera 			    "nxge_neptune_serdes_init: "
16865196Ssbehera 			    "Failed to get Serdes up for port<%d> val 0x%x",
16875196Ssbehera 			    portn, (val & ESR_SIG_P1_BITS_MASK)));
16885196Ssbehera 			status = NXGE_ERROR;
16895196Ssbehera 			goto fail;
16905196Ssbehera 		}
16915196Ssbehera 	}
16925196Ssbehera done:
16934732Sdavemq 
16944732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16954732Sdavemq 	    "<== nxge_1G_serdes_init port<%d>", portn));
16963859Sml29623 	return (NXGE_OK);
16974732Sdavemq fail:
16985196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16994732Sdavemq 	    "nxge_1G_serdes_init: "
17004732Sdavemq 	    "Failed to initialize Neptune serdes for port<%d>",
17014732Sdavemq 	    portn));
17024732Sdavemq 
17035196Ssbehera 	return (status);
17043859Sml29623 }
17053859Sml29623 
17064732Sdavemq /* Initialize the 10G (BCM8704) Transceiver */
17074732Sdavemq 
17084732Sdavemq static nxge_status_t
17094732Sdavemq nxge_10G_xcvr_init(p_nxge_t nxgep)
17103859Sml29623 {
17113859Sml29623 	p_nxge_stats_t		statsp;
17123859Sml29623 	uint16_t		val;
17133859Sml29623 #ifdef	NXGE_DEBUG
17143859Sml29623 	uint8_t			portn;
17153859Sml29623 	uint16_t		val1;
17163859Sml29623 #endif
17173859Sml29623 	uint8_t			phy_port_addr;
17183859Sml29623 	pmd_tx_control_t	tx_ctl;
17193859Sml29623 	control_t		ctl;
17203859Sml29623 	phyxs_control_t		phyxs_ctl;
17213859Sml29623 	pcs_control_t		pcs_ctl;
17223859Sml29623 	uint32_t		delay = 0;
17233859Sml29623 	optics_dcntr_t		op_ctr;
17243859Sml29623 	nxge_status_t		status = NXGE_OK;
17253859Sml29623 #ifdef	NXGE_DEBUG
17263859Sml29623 	portn = nxgep->mac.portnum;
17273859Sml29623 #endif
17284732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
17294732Sdavemq 	    portn));
17304732Sdavemq 
17314732Sdavemq 	statsp = nxgep->statsp;
17324732Sdavemq 
17334977Sraghus 	if (nxgep->mac.portmode == PORT_10G_SERDES) {
17344977Sraghus 		goto done;
17354977Sraghus 	}
17364977Sraghus 
17374732Sdavemq 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
17384732Sdavemq 
17394732Sdavemq 	/* Disable Link LEDs */
17404732Sdavemq 	if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
17414732Sdavemq 		goto fail;
17424732Sdavemq 
17434732Sdavemq 	/* Set Clause 45 */
17444732Sdavemq 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
17454732Sdavemq 
17464732Sdavemq 	/* Reset the transceiver */
17474732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
17484732Sdavemq 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
17494732Sdavemq 		goto fail;
17504732Sdavemq 
17514732Sdavemq 	phyxs_ctl.bits.reset = 1;
17524732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
17534732Sdavemq 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
17544732Sdavemq 		goto fail;
17554732Sdavemq 
17564732Sdavemq 	do {
17574732Sdavemq 		drv_usecwait(500);
17584732Sdavemq 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
17594732Sdavemq 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
17604732Sdavemq 		    &phyxs_ctl.value)) != NXGE_OK)
17614732Sdavemq 			goto fail;
17624732Sdavemq 		delay++;
17634732Sdavemq 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
17644732Sdavemq 	if (delay == 100) {
17654732Sdavemq 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
17664732Sdavemq 		    "failed to reset Transceiver on port<%d>", portn));
17674732Sdavemq 		status = NXGE_ERROR;
17684732Sdavemq 		goto fail;
17694732Sdavemq 	}
17704732Sdavemq 
17714732Sdavemq 	/* Set to 0x7FBF */
17724732Sdavemq 	ctl.value = 0;
17734732Sdavemq 	ctl.bits.res1 = 0x3F;
17744732Sdavemq 	ctl.bits.optxon_lvl = 1;
17754732Sdavemq 	ctl.bits.oprxflt_lvl = 1;
17764732Sdavemq 	ctl.bits.optrxlos_lvl = 1;
17774732Sdavemq 	ctl.bits.optxflt_lvl = 1;
17784732Sdavemq 	ctl.bits.opprflt_lvl = 1;
17794732Sdavemq 	ctl.bits.obtmpflt_lvl = 1;
17804732Sdavemq 	ctl.bits.opbiasflt_lvl = 1;
17814732Sdavemq 	ctl.bits.optxrst_lvl = 1;
17824732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
17834732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value))
17844732Sdavemq 	    != NXGE_OK)
17854732Sdavemq 		goto fail;
17864732Sdavemq 
17874732Sdavemq 	/* Set to 0x164 */
17884732Sdavemq 	tx_ctl.value = 0;
17894732Sdavemq 	tx_ctl.bits.tsck_lpwren = 1;
17904732Sdavemq 	tx_ctl.bits.tx_dac_txck = 0x2;
17914732Sdavemq 	tx_ctl.bits.tx_dac_txd = 0x1;
17924732Sdavemq 	tx_ctl.bits.xfp_clken = 1;
17934732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
17944732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG,
17954732Sdavemq 	    tx_ctl.value)) != NXGE_OK)
17964732Sdavemq 		goto fail;
17974732Sdavemq 	/*
17984732Sdavemq 	 * According to Broadcom's instruction, SW needs to read
17994732Sdavemq 	 * back these registers twice after written.
18004732Sdavemq 	 */
18014732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
18024732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
18034732Sdavemq 	    != NXGE_OK)
18044732Sdavemq 		goto fail;
18054732Sdavemq 
18064732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
18074732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
18084732Sdavemq 	    != NXGE_OK)
18094732Sdavemq 		goto fail;
18104732Sdavemq 
18114732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
18124732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
18134732Sdavemq 	    != NXGE_OK)
18144732Sdavemq 		goto fail;
18154732Sdavemq 
18164732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
18174732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
18184732Sdavemq 	    != NXGE_OK)
18194732Sdavemq 		goto fail;
18204732Sdavemq 
18214732Sdavemq 	/* Enable Tx and Rx LEDs to be driven by traffic */
18224732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
18234732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
18244732Sdavemq 	    &op_ctr.value)) != NXGE_OK)
18254732Sdavemq 		goto fail;
1826*5553Smisaki 	if (NXGE_IS_XAUI_PLATFORM(nxgep)) {
1827*5553Smisaki 		op_ctr.bits.gpio_sel = 0x1;
1828*5553Smisaki 	} else {
1829*5553Smisaki 		op_ctr.bits.gpio_sel = 0x3;
1830*5553Smisaki 	}
18314732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
18324732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
18334732Sdavemq 	    op_ctr.value)) != NXGE_OK)
18344732Sdavemq 		goto fail;
18354732Sdavemq 
18364732Sdavemq 	NXGE_DELAY(1000000);
18374732Sdavemq 
18384732Sdavemq 	/* Set BCM8704 Internal Loopback mode if necessary */
18394732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
18404732Sdavemq 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
18414732Sdavemq 	    != NXGE_OK)
18424732Sdavemq 		goto fail;
18434732Sdavemq 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
18444732Sdavemq 		pcs_ctl.bits.loopback = 1;
18454732Sdavemq 	else
18464732Sdavemq 		pcs_ctl.bits.loopback = 0;
18474732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
18484732Sdavemq 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
18494732Sdavemq 	    != NXGE_OK)
18504732Sdavemq 		goto fail;
18514732Sdavemq 
18524732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val);
18534732Sdavemq 	if (status != NXGE_OK)
18544732Sdavemq 		goto fail;
18554732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18564732Sdavemq 	    "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val));
18574732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
18584732Sdavemq 	if (status != NXGE_OK)
18594732Sdavemq 		goto fail;
18604732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18614732Sdavemq 	    "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val));
18624732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
18634732Sdavemq 	if (status != NXGE_OK)
18644732Sdavemq 		goto fail;
18654732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18664732Sdavemq 	    "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val));
18674732Sdavemq 
18684732Sdavemq #ifdef	NXGE_DEBUG
18694732Sdavemq 	/* Diagnose link issue if link is not up */
18704732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR,
18714732Sdavemq 	    BCM8704_USER_ANALOG_STATUS0_REG,
18724732Sdavemq 	    &val);
18734732Sdavemq 	if (status != NXGE_OK)
18744732Sdavemq 		goto fail;
18754732Sdavemq 
18764732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
18774732Sdavemq 				BCM8704_USER_DEV3_ADDR,
18784732Sdavemq 				BCM8704_USER_ANALOG_STATUS0_REG,
18794732Sdavemq 				&val);
18804732Sdavemq 	if (status != NXGE_OK)
18814732Sdavemq 		goto fail;
18824732Sdavemq 
18834732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
18844732Sdavemq 				BCM8704_USER_DEV3_ADDR,
18854732Sdavemq 				BCM8704_USER_TX_ALARM_STATUS_REG,
18864732Sdavemq 				&val1);
18874732Sdavemq 	if (status != NXGE_OK)
18884732Sdavemq 		goto fail;
18894732Sdavemq 
18904732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
18914732Sdavemq 				BCM8704_USER_DEV3_ADDR,
18924732Sdavemq 				BCM8704_USER_TX_ALARM_STATUS_REG,
18934732Sdavemq 				&val1);
18944732Sdavemq 	if (status != NXGE_OK)
18954732Sdavemq 		goto fail;
18964732Sdavemq 
18974732Sdavemq 	if (val != 0x3FC) {
18984732Sdavemq 		if ((val == 0x43BC) && (val1 != 0)) {
18994732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
19004732Sdavemq 			    "Cable not connected to peer or bad"
19014732Sdavemq 			    " cable on port<%d>\n", portn));
19024732Sdavemq 		} else if (val == 0x639C) {
19034732Sdavemq 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19044732Sdavemq 			    "Optical module (XFP) is bad or absent"
19054732Sdavemq 			    " on port<%d>\n", portn));
19064732Sdavemq 		}
19074732Sdavemq 	}
19084732Sdavemq #endif
19094732Sdavemq 
19104977Sraghus done:
19114732Sdavemq 	statsp->mac_stats.cap_10gfdx = 1;
19124732Sdavemq 	statsp->mac_stats.lp_cap_10gfdx = 1;
19134732Sdavemq 
19144732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
19154732Sdavemq 	    portn));
19164732Sdavemq 	return (NXGE_OK);
19174732Sdavemq 
19184732Sdavemq fail:
19194732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
19204732Sdavemq 	    "nxge_10G_xcvr_init: failed to initialize transceiver for "
19214732Sdavemq 	    "port<%d>", portn));
19224732Sdavemq 	return (status);
19234732Sdavemq }
19244732Sdavemq 
19254732Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */
19264732Sdavemq 
19274732Sdavemq static nxge_status_t
19284732Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep)
19294732Sdavemq {
19304732Sdavemq 	p_nxge_param_t		param_arr = nxgep->param_arr;
19314732Sdavemq 	p_nxge_stats_t		statsp = nxgep->statsp;
19324732Sdavemq 	nxge_status_t		status = NXGE_OK;
19334732Sdavemq 
19344977Sraghus 	if (nxgep->mac.portmode == PORT_1G_SERDES) {
19354977Sraghus 		statsp->mac_stats.cap_1000fdx =
19364977Sraghus 		    param_arr[param_anar_1000fdx].value;
19374977Sraghus 		goto done;
19384977Sraghus 	}
19394977Sraghus 
19404732Sdavemq 	/* Set Clause 22 */
19414732Sdavemq 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
19424732Sdavemq 
19434732Sdavemq 	/* Set capability flags */
19444732Sdavemq 	statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value;
19454977Sraghus 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
19464977Sraghus 	    (nxgep->mac.portmode == PORT_1G_FIBER)) {
19474977Sraghus 		statsp->mac_stats.cap_100fdx =
19484977Sraghus 		    param_arr[param_anar_100fdx].value;
19494977Sraghus 		statsp->mac_stats.cap_10fdx =
19504977Sraghus 		    param_arr[param_anar_10fdx].value;
19514977Sraghus 	}
19524732Sdavemq 
19534732Sdavemq 	status = nxge_mii_xcvr_init(nxgep);
19544977Sraghus done:
19554732Sdavemq 	return (status);
19564732Sdavemq }
19574732Sdavemq 
19584732Sdavemq /* Initialize transceiver */
19594732Sdavemq 
19604732Sdavemq nxge_status_t
19614732Sdavemq nxge_xcvr_init(p_nxge_t nxgep)
19624732Sdavemq {
19634732Sdavemq 	p_nxge_stats_t		statsp;
19644732Sdavemq #ifdef	NXGE_DEBUG
19654732Sdavemq 	uint8_t			portn;
19664732Sdavemq #endif
19674732Sdavemq 
19684732Sdavemq 	nxge_status_t		status = NXGE_OK;
19694732Sdavemq #ifdef	NXGE_DEBUG
19704732Sdavemq 	portn = nxgep->mac.portnum;
19714732Sdavemq #endif
19723859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
19733859Sml29623 	statsp = nxgep->statsp;
19743859Sml29623 
19753859Sml29623 	/*
19763859Sml29623 	 * Initialize the xcvr statistics.
19773859Sml29623 	 */
19783859Sml29623 	statsp->mac_stats.cap_autoneg = 0;
19793859Sml29623 	statsp->mac_stats.cap_100T4 = 0;
19803859Sml29623 	statsp->mac_stats.cap_100fdx = 0;
19813859Sml29623 	statsp->mac_stats.cap_100hdx = 0;
19823859Sml29623 	statsp->mac_stats.cap_10fdx = 0;
19833859Sml29623 	statsp->mac_stats.cap_10hdx = 0;
19843859Sml29623 	statsp->mac_stats.cap_asmpause = 0;
19853859Sml29623 	statsp->mac_stats.cap_pause = 0;
19863859Sml29623 	statsp->mac_stats.cap_1000fdx = 0;
19873859Sml29623 	statsp->mac_stats.cap_1000hdx = 0;
19883859Sml29623 	statsp->mac_stats.cap_10gfdx = 0;
19893859Sml29623 	statsp->mac_stats.cap_10ghdx = 0;
19903859Sml29623 
19913859Sml29623 	/*
19923859Sml29623 	 * Initialize the link statistics.
19933859Sml29623 	 */
19943859Sml29623 	statsp->mac_stats.link_T4 = 0;
19953859Sml29623 	statsp->mac_stats.link_asmpause = 0;
19963859Sml29623 	statsp->mac_stats.link_pause = 0;
19973859Sml29623 
19984732Sdavemq 	if (nxgep->xcvr.xcvr_init) {
19994732Sdavemq 		status = nxgep->xcvr.xcvr_init(nxgep);
20003859Sml29623 		if (status != NXGE_OK)
20013859Sml29623 			goto fail;
20024732Sdavemq 		statsp->mac_stats.xcvr_inits++;
20033859Sml29623 	}
20043859Sml29623 
20054732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>",
20064732Sdavemq 	    portn));
20073859Sml29623 	return (NXGE_OK);
20083859Sml29623 
20093859Sml29623 fail:
20103859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
20114732Sdavemq 	    "nxge_xcvr_init: failed to initialize transceiver for port<%d>",
20124732Sdavemq 	    portn));
20133859Sml29623 	return (status);
20143859Sml29623 }
20153859Sml29623 
20164977Sraghus /* Look for transceiver type */
20174977Sraghus 
20184977Sraghus nxge_status_t
20194977Sraghus nxge_xcvr_find(p_nxge_t nxgep)
20204977Sraghus {
20215196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>",
20225196Ssbehera 	    nxgep->mac.portnum));
20234977Sraghus 
20244977Sraghus 	if (nxge_get_xcvr_type(nxgep) != NXGE_OK)
20254977Sraghus 		return (NXGE_ERROR);
20264977Sraghus 
20274977Sraghus 	if (nxge_setup_xcvr_table(nxgep) != NXGE_OK)
20284977Sraghus 		return (NXGE_ERROR);
20294977Sraghus 
20304977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d",
20314977Sraghus 	    nxgep->statsp->mac_stats.xcvr_inuse));
20324977Sraghus 	return (NXGE_OK);
20334977Sraghus }
20343859Sml29623 
20353859Sml29623 /* Initialize the TxMAC sub-block */
20363859Sml29623 
20373859Sml29623 nxge_status_t
20383859Sml29623 nxge_tx_mac_init(p_nxge_t nxgep)
20393859Sml29623 {
20403859Sml29623 	npi_attr_t		ap;
20413859Sml29623 	uint8_t			portn;
20423859Sml29623 	nxge_port_mode_t	portmode;
20433859Sml29623 	nxge_port_t		portt;
20443859Sml29623 	npi_handle_t		handle;
20453859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
20463859Sml29623 
20473859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
20483859Sml29623 	portt    = nxgep->mac.porttype;
20493859Sml29623 	handle   = nxgep->npi_handle;
20503859Sml29623 	portmode = nxgep->mac.portmode;
20513859Sml29623 
20523859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>",
20533859Sml29623 			portn));
20543859Sml29623 
20553859Sml29623 	/* Set Max and Min Frame Size */
20563859Sml29623 	if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) {
20573859Sml29623 		SET_MAC_ATTR2(handle, ap, portn,
20583859Sml29623 		    MAC_PORT_FRAME_SIZE, 64, 0x2400, rs);
20593859Sml29623 	} else {
20605237Ssbehera 		/* Do not add CRC 4 bytes to the max or the min frame size */
20613859Sml29623 		SET_MAC_ATTR2(handle, ap, portn,
20625237Ssbehera 		    MAC_PORT_FRAME_SIZE, 64, 0x5EE, rs);
20633859Sml29623 	}
20643859Sml29623 
20653859Sml29623 	if (rs != NPI_SUCCESS)
20663859Sml29623 		goto fail;
20673859Sml29623 	if (nxgep->param_arr[param_accept_jumbo].value ||
20683859Sml29623 		nxgep->mac.is_jumbo == B_TRUE)
20693859Sml29623 		nxgep->mac.maxframesize = 0x2400;
20703859Sml29623 	else
20713859Sml29623 		nxgep->mac.maxframesize = 0x5EE + 4;
20723859Sml29623 	nxgep->mac.minframesize = 64;
20733859Sml29623 
20743859Sml29623 	if (portt == PORT_TYPE_XMAC) {
20753859Sml29623 		if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn,
20763859Sml29623 				0)) != NPI_SUCCESS)
20773859Sml29623 			goto fail;
20783859Sml29623 		nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS;
20793859Sml29623 		if ((portmode == PORT_10G_FIBER) ||
20804977Sraghus 		    (portmode == PORT_10G_COPPER) ||
20814977Sraghus 		    (portmode == PORT_10G_SERDES)) {
20823859Sml29623 			SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG,
20833859Sml29623 					XGMII_IPG_12_15, rs);
20843859Sml29623 			if (rs != NPI_SUCCESS)
20853859Sml29623 				goto fail;
20863859Sml29623 			nxgep->mac.ipg[0] = XGMII_IPG_12_15;
20873859Sml29623 		} else {
20883859Sml29623 			SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG,
20893859Sml29623 					MII_GMII_IPG_12, rs);
20903859Sml29623 			if (rs != NPI_SUCCESS)
20913859Sml29623 				goto fail;
20923859Sml29623 			nxgep->mac.ipg[0] = MII_GMII_IPG_12;
20933859Sml29623 		}
20943859Sml29623 		if ((rs = npi_xmac_tx_config(handle, INIT, portn,
20953859Sml29623 				CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS)
20963859Sml29623 			goto fail;
20973859Sml29623 		nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX;
20983859Sml29623 		nxgep->mac.maxburstsize = 0;	/* not programmable */
20993859Sml29623 		nxgep->mac.ctrltype = 0;	/* not programmable */
21003859Sml29623 		nxgep->mac.pa_size = 0;		/* not programmable */
21013859Sml29623 
21023859Sml29623 		if ((rs = npi_xmac_zap_tx_counters(handle, portn))
21033859Sml29623 							!= NPI_SUCCESS)
21043859Sml29623 			goto fail;
21053859Sml29623 
21063859Sml29623 	} else {
21073859Sml29623 		if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn,
21083859Sml29623 				0)) != NPI_SUCCESS)
21093859Sml29623 			goto fail;
21103859Sml29623 		nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS;
21113859Sml29623 
21123859Sml29623 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808,
21133859Sml29623 				rs);
21143859Sml29623 		if (rs != NPI_SUCCESS)
21153859Sml29623 			goto fail;
21163859Sml29623 		nxgep->mac.ctrltype = 0x8808;
21173859Sml29623 
21183859Sml29623 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs);
21193859Sml29623 		if (rs != NPI_SUCCESS)
21203859Sml29623 			goto fail;
21213859Sml29623 		nxgep->mac.pa_size = 0x7;
21223859Sml29623 
21233859Sml29623 		if ((rs = npi_bmac_tx_config(handle, INIT, portn,
21243859Sml29623 				CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS)
21253859Sml29623 			goto fail;
21263859Sml29623 		nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX;
21273859Sml29623 	}
21283859Sml29623 
21293859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>",
21303859Sml29623 			portn));
21313859Sml29623 
21323859Sml29623 	return (NXGE_OK);
21333859Sml29623 fail:
21343859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
21353859Sml29623 		"nxge_tx_mac_init: failed to initialize port<%d> TXMAC",
21363859Sml29623 					portn));
21373859Sml29623 
21383859Sml29623 	return (NXGE_ERROR | rs);
21393859Sml29623 }
21403859Sml29623 
21413859Sml29623 /* Initialize the RxMAC sub-block */
21423859Sml29623 
21433859Sml29623 nxge_status_t
21443859Sml29623 nxge_rx_mac_init(p_nxge_t nxgep)
21453859Sml29623 {
21463859Sml29623 	npi_attr_t		ap;
21473859Sml29623 	uint32_t		i;
21483859Sml29623 	uint16_t		hashtab_e;
21493859Sml29623 	p_hash_filter_t		hash_filter;
21503859Sml29623 	nxge_port_t		portt;
21513859Sml29623 	uint8_t			portn;
21523859Sml29623 	npi_handle_t		handle;
21533859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
21543859Sml29623 	uint16_t 		*addr16p;
21553859Sml29623 	uint16_t 		addr0, addr1, addr2;
21563859Sml29623 	xmac_rx_config_t	xconfig;
21573859Sml29623 	bmac_rx_config_t	bconfig;
21583859Sml29623 
21593859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
21603859Sml29623 
21613859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n",
21623859Sml29623 			portn));
21633859Sml29623 	handle = nxgep->npi_handle;
21643859Sml29623 	portt = nxgep->mac.porttype;
21653859Sml29623 
21663859Sml29623 	addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet;
21673859Sml29623 	addr0 = ntohs(addr16p[2]);
21683859Sml29623 	addr1 = ntohs(addr16p[1]);
21693859Sml29623 	addr2 = ntohs(addr16p[0]);
21703859Sml29623 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2,
21713859Sml29623 		rs);
21723859Sml29623 
21733859Sml29623 	if (rs != NPI_SUCCESS)
21743859Sml29623 		goto fail;
21753859Sml29623 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs);
21763859Sml29623 	if (rs != NPI_SUCCESS)
21773859Sml29623 		goto fail;
21783859Sml29623 	SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs);
21793859Sml29623 	if (rs != NPI_SUCCESS)
21803859Sml29623 		goto fail;
21813859Sml29623 
21823859Sml29623 	/*
21833859Sml29623 	 * Load the multicast hash filter bits.
21843859Sml29623 	 */
21853859Sml29623 	hash_filter = nxgep->hash_filter;
21863859Sml29623 	for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) {
21873859Sml29623 		if (hash_filter != NULL) {
21883859Sml29623 			hashtab_e = (uint16_t)hash_filter->hash_filter_regs[
21893859Sml29623 				(NMCFILTER_REGS - 1) - i];
21903859Sml29623 		} else {
21913859Sml29623 			hashtab_e = 0;
21923859Sml29623 		}
21933859Sml29623 
21943859Sml29623 		if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i,
21953859Sml29623 					(uint16_t *)&hashtab_e)) != NPI_SUCCESS)
21963859Sml29623 			goto fail;
21973859Sml29623 	}
21983859Sml29623 
21993859Sml29623 	if (portt == PORT_TYPE_XMAC) {
22003859Sml29623 		if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn,
22013859Sml29623 				0)) != NPI_SUCCESS)
22023859Sml29623 			goto fail;
22033859Sml29623 		nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS;
22043859Sml29623 
22053859Sml29623 		(void) nxge_fflp_init_hostinfo(nxgep);
22063859Sml29623 
22073859Sml29623 		xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK |
22083859Sml29623 			CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK &
22093859Sml29623 			~CFG_XMAC_RX_STRIP_CRC;
22103859Sml29623 
22113859Sml29623 		if (nxgep->filter.all_phys_cnt != 0)
22123859Sml29623 			xconfig |= CFG_XMAC_RX_PROMISCUOUS;
22133859Sml29623 
22143859Sml29623 		if (nxgep->filter.all_multicast_cnt != 0)
22153859Sml29623 			xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP;
22163859Sml29623 
22173859Sml29623 		xconfig |= CFG_XMAC_RX_HASH_FILTER;
22183859Sml29623 
22193859Sml29623 		if ((rs = npi_xmac_rx_config(handle, INIT, portn,
22203859Sml29623 					xconfig)) != NPI_SUCCESS)
22213859Sml29623 			goto fail;
22223859Sml29623 		nxgep->mac.rx_config = xconfig;
22233859Sml29623 
22243859Sml29623 		/* Comparison of mac unique address is always enabled on XMAC */
22253859Sml29623 
22263859Sml29623 		if ((rs = npi_xmac_zap_rx_counters(handle, portn))
22273859Sml29623 							!= NPI_SUCCESS)
22283859Sml29623 			goto fail;
22293859Sml29623 	} else {
22303859Sml29623 		(void) nxge_fflp_init_hostinfo(nxgep);
22313859Sml29623 
22323859Sml29623 		if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn,
22333859Sml29623 					0) != NPI_SUCCESS)
22343859Sml29623 			goto fail;
22353859Sml29623 		nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS;
22363859Sml29623 
22373859Sml29623 		bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX &
22383859Sml29623 			~CFG_BMAC_RX_STRIP_CRC;
22393859Sml29623 
22403859Sml29623 		if (nxgep->filter.all_phys_cnt != 0)
22413859Sml29623 			bconfig |= CFG_BMAC_RX_PROMISCUOUS;
22423859Sml29623 
22433859Sml29623 		if (nxgep->filter.all_multicast_cnt != 0)
22443859Sml29623 			bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP;
22453859Sml29623 
22463859Sml29623 		bconfig |= CFG_BMAC_RX_HASH_FILTER;
22473859Sml29623 		if ((rs = npi_bmac_rx_config(handle, INIT, portn,
22483859Sml29623 					bconfig)) != NPI_SUCCESS)
22493859Sml29623 			goto fail;
22503859Sml29623 		nxgep->mac.rx_config = bconfig;
22513859Sml29623 
22523859Sml29623 		/* Always enable comparison of mac unique address */
22533859Sml29623 		if ((rs = npi_mac_altaddr_enable(handle, portn, 0))
22543859Sml29623 					!= NPI_SUCCESS)
22553859Sml29623 			goto fail;
22563859Sml29623 	}
22573859Sml29623 
22583859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n",
22593859Sml29623 			portn));
22603859Sml29623 
22613859Sml29623 	return (NXGE_OK);
22623859Sml29623 
22633859Sml29623 fail:
22643859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
22653859Sml29623 		"nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC",
22663859Sml29623 				portn));
22673859Sml29623 
22683859Sml29623 	return (NXGE_ERROR | rs);
22693859Sml29623 }
22703859Sml29623 
22713859Sml29623 /* Enable TXMAC */
22723859Sml29623 
22733859Sml29623 nxge_status_t
22743859Sml29623 nxge_tx_mac_enable(p_nxge_t nxgep)
22753859Sml29623 {
22763859Sml29623 	npi_handle_t	handle;
22773859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
22783859Sml29623 	nxge_status_t	status = NXGE_OK;
22793859Sml29623 
22803859Sml29623 	handle = nxgep->npi_handle;
22813859Sml29623 
22823859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>",
22833859Sml29623 			nxgep->mac.portnum));
22843859Sml29623 
22853859Sml29623 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
22863859Sml29623 		goto fail;
22873859Sml29623 
22883859Sml29623 	/* based on speed */
22893859Sml29623 	nxgep->msg_min = ETHERMIN;
22903859Sml29623 
22913859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
22923859Sml29623 		if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
22933859Sml29623 						CFG_XMAC_TX)) != NPI_SUCCESS)
22943859Sml29623 			goto fail;
22953859Sml29623 	} else {
22963859Sml29623 		if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
22973859Sml29623 						CFG_BMAC_TX)) != NPI_SUCCESS)
22983859Sml29623 			goto fail;
22993859Sml29623 	}
23003859Sml29623 
23013859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>",
23023859Sml29623 			nxgep->mac.portnum));
23033859Sml29623 
23043859Sml29623 	return (NXGE_OK);
23053859Sml29623 fail:
23063859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
23073859Sml29623 			"nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
23083859Sml29623 			nxgep->mac.portnum));
23093859Sml29623 	if (rs != NPI_SUCCESS)
23103859Sml29623 		return (NXGE_ERROR | rs);
23113859Sml29623 	else
23123859Sml29623 		return (status);
23133859Sml29623 }
23143859Sml29623 
23153859Sml29623 /* Disable TXMAC */
23163859Sml29623 
23173859Sml29623 nxge_status_t
23183859Sml29623 nxge_tx_mac_disable(p_nxge_t nxgep)
23193859Sml29623 {
23203859Sml29623 	npi_handle_t	handle;
23213859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
23223859Sml29623 
23233859Sml29623 	handle = nxgep->npi_handle;
23243859Sml29623 
23253859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>",
23263859Sml29623 			nxgep->mac.portnum));
23273859Sml29623 
23283859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
23293859Sml29623 		if ((rs = npi_xmac_tx_config(handle, DISABLE,
23303859Sml29623 			nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS)
23313859Sml29623 			goto fail;
23323859Sml29623 	} else {
23333859Sml29623 		if ((rs = npi_bmac_tx_config(handle, DISABLE,
23343859Sml29623 			nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS)
23353859Sml29623 			goto fail;
23363859Sml29623 	}
23373859Sml29623 
23383859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>",
23393859Sml29623 			nxgep->mac.portnum));
23403859Sml29623 	return (NXGE_OK);
23413859Sml29623 fail:
23423859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
23433859Sml29623 			"nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
23443859Sml29623 			nxgep->mac.portnum));
23453859Sml29623 	return (NXGE_ERROR | rs);
23463859Sml29623 }
23473859Sml29623 
23483859Sml29623 /* Enable RXMAC */
23493859Sml29623 
23503859Sml29623 nxge_status_t
23513859Sml29623 nxge_rx_mac_enable(p_nxge_t nxgep)
23523859Sml29623 {
23533859Sml29623 	npi_handle_t	handle;
23543859Sml29623 	uint8_t 	portn;
23553859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
23563859Sml29623 	nxge_status_t	status = NXGE_OK;
23573859Sml29623 
23583859Sml29623 	handle = nxgep->npi_handle;
23593859Sml29623 	portn = nxgep->mac.portnum;
23603859Sml29623 
23613859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>",
23623859Sml29623 			portn));
23633859Sml29623 
23643859Sml29623 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
23653859Sml29623 		goto fail;
23663859Sml29623 
23673859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
23683859Sml29623 		if ((rs = npi_xmac_rx_config(handle, ENABLE, portn,
23693859Sml29623 						CFG_XMAC_RX)) != NPI_SUCCESS)
23703859Sml29623 			goto fail;
23713859Sml29623 	} else {
23723859Sml29623 		if ((rs = npi_bmac_rx_config(handle, ENABLE, portn,
23733859Sml29623 						CFG_BMAC_RX)) != NPI_SUCCESS)
23743859Sml29623 			goto fail;
23753859Sml29623 	}
23763859Sml29623 
23773859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>",
23783859Sml29623 			portn));
23793859Sml29623 
23803859Sml29623 	return (NXGE_OK);
23813859Sml29623 fail:
23823859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
23833859Sml29623 			"nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC",
23843859Sml29623 			portn));
23853859Sml29623 
23863859Sml29623 	if (rs != NPI_SUCCESS)
23873859Sml29623 		return (NXGE_ERROR | rs);
23883859Sml29623 	else
23893859Sml29623 		return (status);
23903859Sml29623 }
23913859Sml29623 
23923859Sml29623 /* Disable RXMAC */
23933859Sml29623 
23943859Sml29623 nxge_status_t
23953859Sml29623 nxge_rx_mac_disable(p_nxge_t nxgep)
23963859Sml29623 {
23973859Sml29623 	npi_handle_t	handle;
23983859Sml29623 	uint8_t		portn;
23993859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
24003859Sml29623 
24013859Sml29623 	handle = nxgep->npi_handle;
24023859Sml29623 	portn = nxgep->mac.portnum;
24033859Sml29623 
24043859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>",
24053859Sml29623 			portn));
24063859Sml29623 
24073859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
24083859Sml29623 		if ((rs = npi_xmac_rx_config(handle, DISABLE, portn,
24093859Sml29623 						CFG_XMAC_RX)) != NPI_SUCCESS)
24103859Sml29623 			goto fail;
24113859Sml29623 	} else {
24123859Sml29623 		if ((rs = npi_bmac_rx_config(handle, DISABLE, portn,
24133859Sml29623 						CFG_BMAC_RX)) != NPI_SUCCESS)
24143859Sml29623 			goto fail;
24153859Sml29623 	}
24163859Sml29623 
24173859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>",
24183859Sml29623 			portn));
24193859Sml29623 	return (NXGE_OK);
24203859Sml29623 fail:
24213859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
24223859Sml29623 			"nxgep_rx_mac_disable: ",
24233859Sml29623 			"Failed to disable port<%d> RxMAC",
24243859Sml29623 			portn));
24253859Sml29623 
24263859Sml29623 	return (NXGE_ERROR | rs);
24273859Sml29623 }
24283859Sml29623 
24293859Sml29623 /* Reset TXMAC */
24303859Sml29623 
24313859Sml29623 nxge_status_t
24323859Sml29623 nxge_tx_mac_reset(p_nxge_t nxgep)
24333859Sml29623 {
24343859Sml29623 	npi_handle_t	handle;
24353859Sml29623 	uint8_t		portn;
24363859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
24373859Sml29623 
24383859Sml29623 	handle = nxgep->npi_handle;
24393859Sml29623 	portn = nxgep->mac.portnum;
24403859Sml29623 
24413859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>",
24423859Sml29623 			portn));
24433859Sml29623 
24443859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
24453859Sml29623 		if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL))
24463859Sml29623 		    != NPI_SUCCESS)
24473859Sml29623 			goto fail;
24483859Sml29623 	} else {
24493859Sml29623 		if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET))
24503859Sml29623 					!= NPI_SUCCESS)
24513859Sml29623 			goto fail;
24523859Sml29623 	}
24533859Sml29623 
24543859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>",
24553859Sml29623 			portn));
24563859Sml29623 
24573859Sml29623 	return (NXGE_OK);
24583859Sml29623 fail:
24593859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
24603859Sml29623 			"nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>",
24613859Sml29623 			portn));
24623859Sml29623 
24633859Sml29623 	return (NXGE_ERROR | rs);
24643859Sml29623 }
24653859Sml29623 
24663859Sml29623 /* Reset RXMAC */
24673859Sml29623 
24683859Sml29623 nxge_status_t
24693859Sml29623 nxge_rx_mac_reset(p_nxge_t nxgep)
24703859Sml29623 {
24713859Sml29623 	npi_handle_t	handle;
24723859Sml29623 	uint8_t		portn;
24733859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
24743859Sml29623 
24753859Sml29623 	handle = nxgep->npi_handle;
24763859Sml29623 	portn = nxgep->mac.portnum;
24773859Sml29623 
24783859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>",
24793859Sml29623 			portn));
24803859Sml29623 
24813859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
24823859Sml29623 		if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL))
24833859Sml29623 		    != NPI_SUCCESS)
24843859Sml29623 		goto fail;
24853859Sml29623 	} else {
24863859Sml29623 		if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET))
24873859Sml29623 					!= NPI_SUCCESS)
24883859Sml29623 		goto fail;
24893859Sml29623 	}
24903859Sml29623 
24913859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>",
24923859Sml29623 			portn));
24933859Sml29623 
24943859Sml29623 	return (NXGE_OK);
24953859Sml29623 fail:
24963859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
24973859Sml29623 			"nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>",
24983859Sml29623 			portn));
24993859Sml29623 	return (NXGE_ERROR | rs);
25003859Sml29623 }
25013859Sml29623 
25024732Sdavemq /* 10G fiber link interrupt start routine */
25034732Sdavemq 
25044732Sdavemq static nxge_status_t
25054732Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep)
25064732Sdavemq {
25074732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
25084732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
25094732Sdavemq 
25104732Sdavemq 	rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn);
25114732Sdavemq 
25124732Sdavemq 	if (rs != NPI_SUCCESS)
25134732Sdavemq 		return (NXGE_ERROR | rs);
25144732Sdavemq 	else
25154732Sdavemq 		return (NXGE_OK);
25164732Sdavemq }
25174732Sdavemq 
25184732Sdavemq /* 10G fiber link interrupt stop routine */
25194732Sdavemq 
25204732Sdavemq static nxge_status_t
25214732Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep)
25224732Sdavemq {
25234732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
25244732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
25254732Sdavemq 
25264732Sdavemq 	rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn);
25274732Sdavemq 
25284732Sdavemq 	if (rs != NPI_SUCCESS)
25294732Sdavemq 		return (NXGE_ERROR | rs);
25304732Sdavemq 	else
25314732Sdavemq 		return (NXGE_OK);
25324732Sdavemq }
25334732Sdavemq 
25344732Sdavemq /* 1G fiber link interrupt start routine */
25354732Sdavemq 
25364732Sdavemq static nxge_status_t
25374732Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)
25384732Sdavemq {
25394732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
25404732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
25414732Sdavemq 
25424732Sdavemq 	rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn);
25434732Sdavemq 	if (rs != NPI_SUCCESS)
25444732Sdavemq 		return (NXGE_ERROR | rs);
25454732Sdavemq 	else
25464732Sdavemq 		return (NXGE_OK);
25474732Sdavemq }
25484732Sdavemq 
25494732Sdavemq /* 1G fiber link interrupt stop routine */
25504732Sdavemq 
25514732Sdavemq static nxge_status_t
25524732Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)
25534732Sdavemq {
25544732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
25554732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
25564732Sdavemq 
25574732Sdavemq 	rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn);
25584732Sdavemq 
25594732Sdavemq 	if (rs != NPI_SUCCESS)
25604732Sdavemq 		return (NXGE_ERROR | rs);
25614732Sdavemq 	else
25624732Sdavemq 		return (NXGE_OK);
25634732Sdavemq }
25644732Sdavemq 
25654732Sdavemq /* 1G copper link interrupt start routine */
25664732Sdavemq 
25674732Sdavemq static nxge_status_t
25684732Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep)
25694732Sdavemq {
25704732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
25714732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
25724732Sdavemq 
25734732Sdavemq 	rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn,
25745203Ssbehera 	    MII_STATUS, MII_STATUS_LINKUP);
25754732Sdavemq 
25764732Sdavemq 	if (rs != NPI_SUCCESS)
25774732Sdavemq 		return (NXGE_ERROR | rs);
25784732Sdavemq 	else
25794732Sdavemq 		return (NXGE_OK);
25804732Sdavemq }
25814732Sdavemq 
25824732Sdavemq /* 1G copper link interrupt stop routine */
25834732Sdavemq 
25844732Sdavemq static nxge_status_t
25854732Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)
25864732Sdavemq {
25874732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
25884732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
25894732Sdavemq 
25904732Sdavemq 	rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn);
25914732Sdavemq 
25924732Sdavemq 	if (rs != NPI_SUCCESS)
25934732Sdavemq 		return (NXGE_ERROR | rs);
25944732Sdavemq 	else
25954732Sdavemq 		return (NXGE_OK);
25964732Sdavemq }
25974732Sdavemq 
25984732Sdavemq /* Enable/Disable Link Status change interrupt */
25993859Sml29623 
26003859Sml29623 nxge_status_t
26013859Sml29623 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
26023859Sml29623 {
26034732Sdavemq 	uint8_t		portn;
26044732Sdavemq 	nxge_status_t	status = NXGE_OK;
26053859Sml29623 
26063859Sml29623 	portn = nxgep->mac.portnum;
26073859Sml29623 
26083859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn));
26094732Sdavemq 	if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start)
26104732Sdavemq 		return (NXGE_OK);
26114732Sdavemq 
26124732Sdavemq 	if (enable == LINK_INTR_START)
26134732Sdavemq 		status = nxgep->xcvr.link_intr_start(nxgep);
26144732Sdavemq 	else if (enable == LINK_INTR_STOP)
26154732Sdavemq 		status = nxgep->xcvr.link_intr_stop(nxgep);
26164732Sdavemq 	if (status != NXGE_OK)
26174732Sdavemq 		goto fail;
26183859Sml29623 
26193859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
26203859Sml29623 
26213859Sml29623 	return (NXGE_OK);
26223859Sml29623 fail:
26233859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
26243859Sml29623 			"nxge_link_intr: Failed to set port<%d> mif intr mode",
26253859Sml29623 			portn));
26263859Sml29623 
26274732Sdavemq 	return (status);
26283859Sml29623 }
26293859Sml29623 
26303859Sml29623 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
26313859Sml29623 
26323859Sml29623 nxge_status_t
26333859Sml29623 nxge_mii_xcvr_init(p_nxge_t nxgep)
26343859Sml29623 {
26353859Sml29623 	p_nxge_param_t	param_arr;
26363859Sml29623 	p_nxge_stats_t	statsp;
26373859Sml29623 	uint8_t		xcvr_portn;
26383859Sml29623 	p_mii_regs_t	mii_regs;
26393859Sml29623 	mii_bmcr_t	bmcr;
26403859Sml29623 	mii_bmsr_t	bmsr;
26413859Sml29623 	mii_anar_t	anar;
26423859Sml29623 	mii_gcr_t	gcr;
26433859Sml29623 	mii_esr_t	esr;
26443859Sml29623 	mii_aux_ctl_t	bcm5464r_aux;
26453859Sml29623 	int		status = NXGE_OK;
26463859Sml29623 
26473859Sml29623 	uint_t delay;
26483859Sml29623 
26493859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init"));
26503859Sml29623 
26513859Sml29623 	param_arr = nxgep->param_arr;
26523859Sml29623 	statsp = nxgep->statsp;
26533859Sml29623 	xcvr_portn = statsp->mac_stats.xcvr_portn;
26543859Sml29623 
26553859Sml29623 	mii_regs = NULL;
26563859Sml29623 
26573859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
26583859Sml29623 		"nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
26593859Sml29623 
26603859Sml29623 	/*
26615196Ssbehera 	 * The mif phy mode may be connected to either a copper link
26625196Ssbehera 	 * or fiber link. Read the mode control register to get the fiber
26635196Ssbehera 	 * configuration if it is hard-wired to fiber link.
26645196Ssbehera 	 */
26655196Ssbehera 	(void) nxge_mii_get_link_mode(nxgep);
26665196Ssbehera 	if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
26675196Ssbehera 		return (nxge_mii_xcvr_fiber_init(nxgep));
26685196Ssbehera 	}
26695196Ssbehera 
26705196Ssbehera 	/*
26713859Sml29623 	 * Reset the transceiver.
26723859Sml29623 	 */
26733859Sml29623 	delay = 0;
26743859Sml29623 	bmcr.value = 0;
26753859Sml29623 	bmcr.bits.reset = 1;
26763859Sml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
26775125Sjoycey #if defined(__i386)
26785125Sjoycey 		(uint8_t)(uint32_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK)
26795125Sjoycey #else
26803859Sml29623 		(uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK)
26815125Sjoycey #endif
26823859Sml29623 		goto fail;
26833859Sml29623 	do {
26843859Sml29623 		drv_usecwait(500);
26853859Sml29623 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
26865125Sjoycey #if defined(__i386)
26875125Sjoycey 			(uint8_t)(uint32_t)&mii_regs->bmcr, &bmcr.value))
26885125Sjoycey #else
26893859Sml29623 			(uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value))
26905125Sjoycey #endif
26913859Sml29623 				!= NXGE_OK)
26923859Sml29623 			goto fail;
26933859Sml29623 		delay++;
26943859Sml29623 	} while ((bmcr.bits.reset) && (delay < 1000));
26953859Sml29623 	if (delay == 1000) {
26963859Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
26973859Sml29623 		goto fail;
26983859Sml29623 	}
26993859Sml29623 
27003859Sml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
27015125Sjoycey #if defined(__i386)
27025125Sjoycey 			(uint8_t)(uint32_t)(&mii_regs->bmsr),
27035125Sjoycey #else
27043859Sml29623 			(uint8_t)(uint64_t)(&mii_regs->bmsr),
27055125Sjoycey #endif
27063859Sml29623 			&bmsr.value)) != NXGE_OK)
27073859Sml29623 		goto fail;
27083859Sml29623 
27093859Sml29623 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
27103859Sml29623 	param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4;
27113859Sml29623 	param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx;
27123859Sml29623 	param_arr[param_anar_100hdx].value = 0;
27133859Sml29623 	param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx;
27143859Sml29623 	param_arr[param_anar_10hdx].value = 0;
27153859Sml29623 
27163859Sml29623 	/*
27173859Sml29623 	 * Initialize the xcvr statistics.
27183859Sml29623 	 */
27193859Sml29623 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
27203859Sml29623 	statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4;
27213859Sml29623 	statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx;
27223859Sml29623 	statsp->mac_stats.cap_100hdx = 0;
27233859Sml29623 	statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx;
27243859Sml29623 	statsp->mac_stats.cap_10hdx = 0;
27253859Sml29623 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
27263859Sml29623 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
27273859Sml29623 
27283859Sml29623 	/*
27293859Sml29623 	 * Initialise the xcvr advertised capability statistics.
27303859Sml29623 	 */
27313859Sml29623 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
27323859Sml29623 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
27333859Sml29623 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
27343859Sml29623 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
27353859Sml29623 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
27363859Sml29623 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
27373859Sml29623 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
27383859Sml29623 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
27393859Sml29623 	statsp->mac_stats.adv_cap_asmpause =
27403859Sml29623 					param_arr[param_anar_asmpause].value;
27413859Sml29623 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
27423859Sml29623 
27433859Sml29623 
27443859Sml29623 	/*
27453859Sml29623 	 * Check for extended status just in case we're
27463859Sml29623 	 * running a Gigibit phy.
27473859Sml29623 	 */
27483859Sml29623 	if (bmsr.bits.extend_status) {
27493859Sml29623 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
27505125Sjoycey #if defined(__i386)
27515125Sjoycey 			(uint8_t)(uint32_t)(&mii_regs->esr), &esr.value))
27525125Sjoycey #else
27533859Sml29623 			(uint8_t)(uint64_t)(&mii_regs->esr), &esr.value))
27545125Sjoycey #endif
27553859Sml29623 				!= NXGE_OK)
27563859Sml29623 			goto fail;
27573859Sml29623 		param_arr[param_anar_1000fdx].value &=
27583859Sml29623 					esr.bits.link_1000fdx;
27593859Sml29623 		param_arr[param_anar_1000hdx].value = 0;
27603859Sml29623 
27613859Sml29623 		statsp->mac_stats.cap_1000fdx =
27623859Sml29623 			(esr.bits.link_1000Xfdx ||
27633859Sml29623 				esr.bits.link_1000fdx);
27643859Sml29623 		statsp->mac_stats.cap_1000hdx = 0;
27653859Sml29623 	} else {
27663859Sml29623 		param_arr[param_anar_1000fdx].value = 0;
27673859Sml29623 		param_arr[param_anar_1000hdx].value = 0;
27683859Sml29623 	}
27693859Sml29623 
27703859Sml29623 	/*
27713859Sml29623 	 * Initialize 1G Statistics once the capability is established.
27723859Sml29623 	 */
27733859Sml29623 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
27743859Sml29623 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
27753859Sml29623 
27763859Sml29623 	/*
27773859Sml29623 	 * Initialise the link statistics.
27783859Sml29623 	 */
27793859Sml29623 	statsp->mac_stats.link_T4 = 0;
27803859Sml29623 	statsp->mac_stats.link_asmpause = 0;
27813859Sml29623 	statsp->mac_stats.link_pause = 0;
27823859Sml29623 	statsp->mac_stats.link_speed = 0;
27833859Sml29623 	statsp->mac_stats.link_duplex = 0;
27843859Sml29623 	statsp->mac_stats.link_up = 0;
27853859Sml29623 
27863859Sml29623 	/*
27873859Sml29623 	 * Switch off Auto-negotiation, 100M and full duplex.
27883859Sml29623 	 */
27893859Sml29623 	bmcr.value = 0;
27903859Sml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
27915125Sjoycey #if defined(__i386)
27925125Sjoycey 		(uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
27935125Sjoycey #else
27943859Sml29623 		(uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
27955125Sjoycey #endif
27963859Sml29623 		goto fail;
27973859Sml29623 
27983859Sml29623 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
27993859Sml29623 			(statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
28003859Sml29623 		bmcr.bits.loopback = 1;
28013859Sml29623 		bmcr.bits.enable_autoneg = 0;
28023859Sml29623 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
28033859Sml29623 			bmcr.bits.speed_1000_sel = 1;
28043859Sml29623 		bmcr.bits.duplex_mode = 1;
28053859Sml29623 		param_arr[param_autoneg].value = 0;
28063859Sml29623 	} else {
28073859Sml29623 		bmcr.bits.loopback = 0;
28083859Sml29623 	}
28093859Sml29623 
28103859Sml29623 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
28113859Sml29623 		(statsp->port_stats.lb_mode == nxge_lb_ext100) ||
28123859Sml29623 		(statsp->port_stats.lb_mode == nxge_lb_ext10)) {
28133859Sml29623 		param_arr[param_autoneg].value = 0;
28143859Sml29623 		bcm5464r_aux.value = 0;
28153859Sml29623 		bcm5464r_aux.bits.ext_lb = 1;
28163859Sml29623 		bcm5464r_aux.bits.write_1 = 1;
28173859Sml29623 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
28183859Sml29623 				BCM5464R_AUX_CTL, bcm5464r_aux.value))
28193859Sml29623 				!= NXGE_OK)
28203859Sml29623 			goto fail;
28213859Sml29623 	}
28223859Sml29623 
28233859Sml29623 	if (param_arr[param_autoneg].value) {
28243859Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
28253859Sml29623 				"Restarting Auto-negotiation."));
28263859Sml29623 		/*
28273859Sml29623 		 * Setup our Auto-negotiation advertisement register.
28283859Sml29623 		 */
28293859Sml29623 		anar.value = 0;
28303859Sml29623 		anar.bits.selector = 1;
28313859Sml29623 		anar.bits.cap_100T4 = param_arr[param_anar_100T4].value;
28323859Sml29623 		anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value;
28333859Sml29623 		anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value;
28343859Sml29623 		anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value;
28353859Sml29623 		anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value;
28363859Sml29623 		anar.bits.cap_asmpause = 0;
28373859Sml29623 		anar.bits.cap_pause = 0;
28383859Sml29623 		if (param_arr[param_anar_1000fdx].value ||
28393859Sml29623 			param_arr[param_anar_100fdx].value ||
28403859Sml29623 			param_arr[param_anar_10fdx].value) {
28413859Sml29623 			anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause;
28423859Sml29623 			anar.bits.cap_pause = statsp->mac_stats.cap_pause;
28433859Sml29623 		}
28443859Sml29623 
28453859Sml29623 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
28465125Sjoycey #if defined(__i386)
28475125Sjoycey 			(uint8_t)(uint32_t)(&mii_regs->anar), anar.value))
28485125Sjoycey #else
28493859Sml29623 			(uint8_t)(uint64_t)(&mii_regs->anar), anar.value))
28505125Sjoycey #endif
28513859Sml29623 				!= NXGE_OK)
28523859Sml29623 			goto fail;
28533859Sml29623 		if (bmsr.bits.extend_status) {
28543859Sml29623 			gcr.value = 0;
28553859Sml29623 			gcr.bits.ms_mode_en =
28563859Sml29623 				param_arr[param_master_cfg_enable].value;
28573859Sml29623 			gcr.bits.master =
28583859Sml29623 				param_arr[param_master_cfg_value].value;
28593859Sml29623 			gcr.bits.link_1000fdx =
28603859Sml29623 				param_arr[param_anar_1000fdx].value;
28613859Sml29623 			gcr.bits.link_1000hdx =
28623859Sml29623 				param_arr[param_anar_1000hdx].value;
28633859Sml29623 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
28645125Sjoycey #if defined(__i386)
28655125Sjoycey 				(uint8_t)(uint32_t)(&mii_regs->gcr), gcr.value))
28665125Sjoycey #else
28673859Sml29623 				(uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value))
28685125Sjoycey #endif
28693859Sml29623 				!= NXGE_OK)
28703859Sml29623 				goto fail;
28713859Sml29623 		}
28723859Sml29623 
28733859Sml29623 		bmcr.bits.enable_autoneg = 1;
28743859Sml29623 		bmcr.bits.restart_autoneg = 1;
28753859Sml29623 
28763859Sml29623 	} else {
28773859Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
28783859Sml29623 		bmcr.bits.speed_1000_sel =
28793859Sml29623 			param_arr[param_anar_1000fdx].value |
28803859Sml29623 				param_arr[param_anar_1000hdx].value;
28813859Sml29623 		bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) &
28823859Sml29623 			(param_arr[param_anar_100fdx].value |
28833859Sml29623 				param_arr[param_anar_100hdx].value);
28843859Sml29623 		if (bmcr.bits.speed_1000_sel) {
28853859Sml29623 			statsp->mac_stats.link_speed = 1000;
28863859Sml29623 			gcr.value = 0;
28873859Sml29623 			gcr.bits.ms_mode_en =
28883859Sml29623 				param_arr[param_master_cfg_enable].value;
28893859Sml29623 			gcr.bits.master =
28903859Sml29623 				param_arr[param_master_cfg_value].value;
28913859Sml29623 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
28925125Sjoycey #if defined(__i386)
28935125Sjoycey 				(uint8_t)(uint32_t)(&mii_regs->gcr),
28945125Sjoycey #else
28953859Sml29623 				(uint8_t)(uint64_t)(&mii_regs->gcr),
28965125Sjoycey #endif
28973859Sml29623 				gcr.value))
28983859Sml29623 				!= NXGE_OK)
28993859Sml29623 				goto fail;
29003859Sml29623 			if (param_arr[param_anar_1000fdx].value) {
29013859Sml29623 				bmcr.bits.duplex_mode = 1;
29023859Sml29623 				statsp->mac_stats.link_duplex = 2;
29033859Sml29623 			} else
29043859Sml29623 				statsp->mac_stats.link_duplex = 1;
29053859Sml29623 		} else if (bmcr.bits.speed_sel) {
29063859Sml29623 			statsp->mac_stats.link_speed = 100;
29073859Sml29623 			if (param_arr[param_anar_100fdx].value) {
29083859Sml29623 				bmcr.bits.duplex_mode = 1;
29093859Sml29623 				statsp->mac_stats.link_duplex = 2;
29103859Sml29623 			} else
29113859Sml29623 				statsp->mac_stats.link_duplex = 1;
29123859Sml29623 		} else {
29133859Sml29623 			statsp->mac_stats.link_speed = 10;
29143859Sml29623 			if (param_arr[param_anar_10fdx].value) {
29153859Sml29623 				bmcr.bits.duplex_mode = 1;
29163859Sml29623 				statsp->mac_stats.link_duplex = 2;
29173859Sml29623 			} else
29183859Sml29623 				statsp->mac_stats.link_duplex = 1;
29193859Sml29623 		}
29203859Sml29623 		if (statsp->mac_stats.link_duplex != 1) {
29213859Sml29623 			statsp->mac_stats.link_asmpause =
29223859Sml29623 						statsp->mac_stats.cap_asmpause;
29233859Sml29623 			statsp->mac_stats.link_pause =
29243859Sml29623 						statsp->mac_stats.cap_pause;
29253859Sml29623 		}
29263859Sml29623 
29273859Sml29623 		if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
29283859Sml29623 			(statsp->port_stats.lb_mode == nxge_lb_ext100) ||
29293859Sml29623 			(statsp->port_stats.lb_mode == nxge_lb_ext10)) {
29303859Sml29623 			if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
29313859Sml29623 				/* BCM5464R 1000mbps external loopback mode */
29323859Sml29623 				gcr.value = 0;
29333859Sml29623 				gcr.bits.ms_mode_en = 1;
29343859Sml29623 				gcr.bits.master = 1;
29353859Sml29623 				if ((status = nxge_mii_write(nxgep, xcvr_portn,
29365125Sjoycey #if defined(__i386)
29375125Sjoycey 					(uint8_t)(uint32_t)(&mii_regs->gcr),
29385125Sjoycey #else
29393859Sml29623 					(uint8_t)(uint64_t)(&mii_regs->gcr),
29405125Sjoycey #endif
29413859Sml29623 					gcr.value))
29423859Sml29623 					!= NXGE_OK)
29433859Sml29623 					goto fail;
29443859Sml29623 				bmcr.value = 0;
29453859Sml29623 				bmcr.bits.speed_1000_sel = 1;
29463859Sml29623 				statsp->mac_stats.link_speed = 1000;
29473859Sml29623 			} else if (statsp->port_stats.lb_mode
29483859Sml29623 			    == nxge_lb_ext100) {
29493859Sml29623 				/* BCM5464R 100mbps external loopback mode */
29503859Sml29623 				bmcr.value = 0;
29513859Sml29623 				bmcr.bits.speed_sel = 1;
29523859Sml29623 				bmcr.bits.duplex_mode = 1;
29533859Sml29623 				statsp->mac_stats.link_speed = 100;
29543859Sml29623 			} else if (statsp->port_stats.lb_mode
29553859Sml29623 			    == nxge_lb_ext10) {
29563859Sml29623 				/* BCM5464R 10mbps external loopback mode */
29573859Sml29623 				bmcr.value = 0;
29583859Sml29623 				bmcr.bits.duplex_mode = 1;
29593859Sml29623 				statsp->mac_stats.link_speed = 10;
29603859Sml29623 			}
29613859Sml29623 		}
29623859Sml29623 	}
29633859Sml29623 
29643859Sml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
29655125Sjoycey #if defined(__i386)
29665125Sjoycey 			(uint8_t)(uint32_t)(&mii_regs->bmcr),
29675125Sjoycey #else
29683859Sml29623 			(uint8_t)(uint64_t)(&mii_regs->bmcr),
29695125Sjoycey #endif
29703859Sml29623 			bmcr.value)) != NXGE_OK)
29713859Sml29623 		goto fail;
29723859Sml29623 
29733859Sml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
29745125Sjoycey #if defined(__i386)
29755125Sjoycey 		(uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
29765125Sjoycey #else
29773859Sml29623 		(uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
29785125Sjoycey #endif
29793859Sml29623 		goto fail;
29803859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value));
29813859Sml29623 
29823859Sml29623 	/*
29833859Sml29623 	 * Initialize the xcvr status kept in the context structure.
29843859Sml29623 	 */
29853859Sml29623 	nxgep->soft_bmsr.value = 0;
29863859Sml29623 
29873859Sml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
29885125Sjoycey #if defined(__i386)
29895125Sjoycey 		(uint8_t)(uint32_t)(&mii_regs->bmsr),
29905125Sjoycey #else
29913859Sml29623 		(uint8_t)(uint64_t)(&mii_regs->bmsr),
29925125Sjoycey #endif
29933859Sml29623 			&nxgep->bmsr.value)) != NXGE_OK)
29943859Sml29623 		goto fail;
29953859Sml29623 
29963859Sml29623 	statsp->mac_stats.xcvr_inits++;
29973859Sml29623 	nxgep->bmsr.value = 0;
29983859Sml29623 
29993859Sml29623 fail:
30003859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
30013859Sml29623 			"<== nxge_mii_xcvr_init status 0x%x", status));
30023859Sml29623 	return (status);
30033859Sml29623 }
30043859Sml29623 
30055196Ssbehera nxge_status_t
30065196Ssbehera nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)
30075196Ssbehera {
30085196Ssbehera 	p_nxge_param_t	param_arr;
30095196Ssbehera 	p_nxge_stats_t	statsp;
30105196Ssbehera 	uint8_t		xcvr_portn;
30115196Ssbehera 	p_mii_regs_t	mii_regs;
30125196Ssbehera 	mii_bmcr_t	bmcr;
30135196Ssbehera 	mii_bmsr_t	bmsr;
30145196Ssbehera 	mii_gcr_t	gcr;
30155196Ssbehera 	mii_esr_t	esr;
30165196Ssbehera 	mii_aux_ctl_t	bcm5464r_aux;
30175196Ssbehera 	int		status = NXGE_OK;
30185196Ssbehera 
30195196Ssbehera 	uint_t delay;
30205196Ssbehera 
30215196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init"));
30225196Ssbehera 
30235196Ssbehera 	param_arr = nxgep->param_arr;
30245196Ssbehera 	statsp = nxgep->statsp;
30255196Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
30265196Ssbehera 
30275196Ssbehera 	mii_regs = NULL;
30285196Ssbehera 
30295196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
30305196Ssbehera 	    "nxge_mii_xcvr_fiber_init: "
30315196Ssbehera 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
30325196Ssbehera 
30335196Ssbehera 	/*
30345196Ssbehera 	 * Reset the transceiver.
30355196Ssbehera 	 */
30365196Ssbehera 	delay = 0;
30375196Ssbehera 	bmcr.value = 0;
30385196Ssbehera 	bmcr.bits.reset = 1;
30395196Ssbehera 
30405196Ssbehera #if defined(__i386)
30415196Ssbehera 
30425196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
30435196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
30445196Ssbehera 		goto fail;
30455196Ssbehera #else
30465196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
30475196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
30485196Ssbehera 		goto fail;
30495196Ssbehera #endif
30505196Ssbehera 	do {
30515196Ssbehera 		drv_usecwait(500);
30525196Ssbehera #if defined(__i386)
30535196Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
30545196Ssbehera 		    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value))
30555196Ssbehera 		    != NXGE_OK)
30565196Ssbehera 			goto fail;
30575196Ssbehera #else
30585196Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
30595196Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value))
30605196Ssbehera 		    != NXGE_OK)
30615196Ssbehera 			goto fail;
30625196Ssbehera #endif
30635196Ssbehera 		delay++;
30645196Ssbehera 	} while ((bmcr.bits.reset) && (delay < 1000));
30655196Ssbehera 	if (delay == 1000) {
30665196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
30675196Ssbehera 		goto fail;
30685196Ssbehera 	}
30695196Ssbehera 
30705196Ssbehera #if defined(__i386)
30715196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
30725196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
30735196Ssbehera 		goto fail;
30745196Ssbehera #else
30755196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
30765196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
30775196Ssbehera 		goto fail;
30785196Ssbehera #endif
30795196Ssbehera 
30805196Ssbehera 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
30815196Ssbehera 	param_arr[param_anar_100T4].value = 0;
30825196Ssbehera 	param_arr[param_anar_100fdx].value = 0;
30835196Ssbehera 	param_arr[param_anar_100hdx].value = 0;
30845196Ssbehera 	param_arr[param_anar_10fdx].value = 0;
30855196Ssbehera 	param_arr[param_anar_10hdx].value = 0;
30865196Ssbehera 
30875196Ssbehera 	/*
30885196Ssbehera 	 * Initialize the xcvr statistics.
30895196Ssbehera 	 */
30905196Ssbehera 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
30915196Ssbehera 	statsp->mac_stats.cap_100T4 = 0;
30925196Ssbehera 	statsp->mac_stats.cap_100fdx = 0;
30935196Ssbehera 	statsp->mac_stats.cap_100hdx = 0;
30945196Ssbehera 	statsp->mac_stats.cap_10fdx = 0;
30955196Ssbehera 	statsp->mac_stats.cap_10hdx = 0;
30965196Ssbehera 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
30975196Ssbehera 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
30985196Ssbehera 
30995196Ssbehera 	/*
31005196Ssbehera 	 * Initialize the xcvr advertised capability statistics.
31015196Ssbehera 	 */
31025196Ssbehera 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
31035196Ssbehera 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
31045196Ssbehera 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
31055196Ssbehera 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
31065196Ssbehera 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
31075196Ssbehera 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
31085196Ssbehera 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
31095196Ssbehera 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
31105196Ssbehera 	statsp->mac_stats.adv_cap_asmpause =
31115196Ssbehera 	    param_arr[param_anar_asmpause].value;
31125196Ssbehera 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
31135196Ssbehera 
31145196Ssbehera 	/*
31155196Ssbehera 	 * Check for extended status just in case we're
31165196Ssbehera 	 * running a Gigibit phy.
31175196Ssbehera 	 */
31185196Ssbehera 	if (bmsr.bits.extend_status) {
31195196Ssbehera #if defined(__i386)
31205196Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
31215196Ssbehera 		    (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) !=
31225196Ssbehera 		    NXGE_OK)
31235196Ssbehera 			goto fail;
31245196Ssbehera #else
31255196Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
31265196Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) !=
31275196Ssbehera 		    NXGE_OK)
31285196Ssbehera 			goto fail;
31295196Ssbehera #endif
31305196Ssbehera 		param_arr[param_anar_1000fdx].value &=
31315196Ssbehera 		    esr.bits.link_1000fdx;
31325196Ssbehera 		param_arr[param_anar_1000hdx].value = 0;
31335196Ssbehera 
31345196Ssbehera 		statsp->mac_stats.cap_1000fdx =
31355196Ssbehera 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
31365196Ssbehera 		statsp->mac_stats.cap_1000hdx = 0;
31375196Ssbehera 	} else {
31385196Ssbehera 		param_arr[param_anar_1000fdx].value = 0;
31395196Ssbehera 		param_arr[param_anar_1000hdx].value = 0;
31405196Ssbehera 	}
31415196Ssbehera 
31425196Ssbehera 	/*
31435196Ssbehera 	 * Initialize 1G Statistics once the capability is established.
31445196Ssbehera 	 */
31455196Ssbehera 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
31465196Ssbehera 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
31475196Ssbehera 
31485196Ssbehera 	/*
31495196Ssbehera 	 * Initialize the link statistics.
31505196Ssbehera 	 */
31515196Ssbehera 	statsp->mac_stats.link_T4 = 0;
31525196Ssbehera 	statsp->mac_stats.link_asmpause = 0;
31535196Ssbehera 	statsp->mac_stats.link_pause = 0;
31545196Ssbehera 	statsp->mac_stats.link_speed = 0;
31555196Ssbehera 	statsp->mac_stats.link_duplex = 0;
31565196Ssbehera 	statsp->mac_stats.link_up = 0;
31575196Ssbehera 
31585196Ssbehera 	/*
31595196Ssbehera 	 * Switch off Auto-negotiation, 100M and full duplex.
31605196Ssbehera 	 */
31615196Ssbehera 	bmcr.value = 0;
31625196Ssbehera #if defined(__i386)
31635196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
31645196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
31655196Ssbehera 		goto fail;
31665196Ssbehera #else
31675196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
31685196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
31695196Ssbehera 		goto fail;
31705196Ssbehera #endif
31715196Ssbehera 
31725196Ssbehera 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
31735196Ssbehera 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
31745196Ssbehera 		bmcr.bits.loopback = 1;
31755196Ssbehera 		bmcr.bits.enable_autoneg = 0;
31765196Ssbehera 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
31775196Ssbehera 			bmcr.bits.speed_1000_sel = 1;
31785196Ssbehera 		bmcr.bits.duplex_mode = 1;
31795196Ssbehera 		param_arr[param_autoneg].value = 0;
31805196Ssbehera 	} else {
31815196Ssbehera 		bmcr.bits.loopback = 0;
31825196Ssbehera 	}
31835196Ssbehera 
31845196Ssbehera 	if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
31855196Ssbehera 		param_arr[param_autoneg].value = 0;
31865196Ssbehera 		bcm5464r_aux.value = 0;
31875196Ssbehera 		bcm5464r_aux.bits.ext_lb = 1;
31885196Ssbehera 		bcm5464r_aux.bits.write_1 = 1;
31895196Ssbehera 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
31905196Ssbehera 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
31915196Ssbehera 			goto fail;
31925196Ssbehera 	}
31935196Ssbehera 
31945196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
31955196Ssbehera 	bmcr.bits.speed_1000_sel = 1;
31965196Ssbehera 	bmcr.bits.speed_sel = 0;
31975196Ssbehera 	bmcr.bits.duplex_mode = 1;
31985196Ssbehera 	statsp->mac_stats.link_speed = 1000;
31995196Ssbehera 	statsp->mac_stats.link_duplex = 2;
32005196Ssbehera 
32015196Ssbehera 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) {
32025196Ssbehera 		/* BCM5464R 1000mbps external loopback mode */
32035196Ssbehera 		gcr.value = 0;
32045196Ssbehera 		gcr.bits.ms_mode_en = 1;
32055196Ssbehera 		gcr.bits.master = 1;
32065196Ssbehera #if defined(__i386)
32075196Ssbehera 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
32085196Ssbehera 		    (uint8_t)(uint32_t)(&mii_regs->gcr),
32095196Ssbehera 		    gcr.value)) != NXGE_OK)
32105196Ssbehera 			goto fail;
32115196Ssbehera #else
32125196Ssbehera 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
32135196Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->gcr),
32145196Ssbehera 		    gcr.value)) != NXGE_OK)
32155196Ssbehera 			goto fail;
32165196Ssbehera #endif
32175196Ssbehera 		bmcr.value = 0;
32185196Ssbehera 		bmcr.bits.speed_1000_sel = 1;
32195196Ssbehera 		statsp->mac_stats.link_speed = 1000;
32205196Ssbehera 	}
32215196Ssbehera 
32225196Ssbehera #if defined(__i386)
32235196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
32245196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
32255196Ssbehera 	    bmcr.value)) != NXGE_OK)
32265196Ssbehera 		goto fail;
32275196Ssbehera #else
32285196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
32295196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
32305196Ssbehera 	    bmcr.value)) != NXGE_OK)
32315196Ssbehera 		goto fail;
32325196Ssbehera #endif
32335196Ssbehera 
32345196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
32355196Ssbehera 	    "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x",
32365196Ssbehera 	    bmcr.value));
32375196Ssbehera 
32385196Ssbehera #if defined(__i386)
32395196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
32405196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
32415196Ssbehera 		goto fail;
32425196Ssbehera #else
32435196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
32445196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
32455196Ssbehera 		goto fail;
32465196Ssbehera #endif
32475196Ssbehera 
32485196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
32495196Ssbehera 	    "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value));
32505196Ssbehera 
32515196Ssbehera 	/*
32525196Ssbehera 	 * Initialize the xcvr status kept in the context structure.
32535196Ssbehera 	 */
32545196Ssbehera 	nxgep->soft_bmsr.value = 0;
32555196Ssbehera #if defined(__i386)
32565196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
32575196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmsr),
32585196Ssbehera 	    &nxgep->bmsr.value)) != NXGE_OK)
32595196Ssbehera 		goto fail;
32605196Ssbehera #else
32615196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
32625196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
32635196Ssbehera 	    &nxgep->bmsr.value)) != NXGE_OK)
32645196Ssbehera 		goto fail;
32655196Ssbehera #endif
32665196Ssbehera 
32675196Ssbehera 	statsp->mac_stats.xcvr_inits++;
32685196Ssbehera 	nxgep->bmsr.value = 0;
32695196Ssbehera 
32705196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
32715196Ssbehera 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
32725196Ssbehera 	return (status);
32735196Ssbehera 
32745196Ssbehera fail:
32755196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
32765196Ssbehera 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
32775196Ssbehera 	return (status);
32785196Ssbehera }
32795196Ssbehera 
32803859Sml29623 /* Read from a MII compliant register */
32813859Sml29623 
32823859Sml29623 nxge_status_t
32833859Sml29623 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
32843859Sml29623 		uint16_t *value)
32853859Sml29623 {
32863859Sml29623 	npi_status_t rs = NPI_SUCCESS;
32873859Sml29623 
32883859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>"
32893859Sml29623 			"xcvr_reg<%d>", xcvr_portn, xcvr_reg));
32903859Sml29623 
32913859Sml29623 	MUTEX_ENTER(&nxge_mii_lock);
32923859Sml29623 
32935196Ssbehera 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
32945196Ssbehera 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
32953859Sml29623 		if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle,
32963859Sml29623 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
32973859Sml29623 			goto fail;
32984977Sraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
32994977Sraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
33003859Sml29623 		if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle,
33013859Sml29623 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
33023859Sml29623 			goto fail;
33033859Sml29623 	} else
33043859Sml29623 		goto fail;
33053859Sml29623 
33063859Sml29623 	MUTEX_EXIT(&nxge_mii_lock);
33073859Sml29623 
33083859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>"
33093859Sml29623 			"xcvr_reg<%d> value=0x%x",
33103859Sml29623 			xcvr_portn, xcvr_reg, *value));
33113859Sml29623 	return (NXGE_OK);
33123859Sml29623 fail:
33133859Sml29623 	MUTEX_EXIT(&nxge_mii_lock);
33143859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
33153859Sml29623 			"nxge_mii_read: Failed to read mii on xcvr %d",
33163859Sml29623 			xcvr_portn));
33173859Sml29623 
33183859Sml29623 	return (NXGE_ERROR | rs);
33193859Sml29623 }
33203859Sml29623 
33213859Sml29623 /* Write to a MII compliant Register */
33223859Sml29623 
33233859Sml29623 nxge_status_t
33243859Sml29623 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
33253859Sml29623 		uint16_t value)
33263859Sml29623 {
33273859Sml29623 	npi_status_t rs = NPI_SUCCESS;
33283859Sml29623 
33293859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>"
33303859Sml29623 			"xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg,
33313859Sml29623 			value));
33323859Sml29623 
33333859Sml29623 	MUTEX_ENTER(&nxge_mii_lock);
33343859Sml29623 
33355196Ssbehera 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
33365196Ssbehera 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
33373859Sml29623 		if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle,
33383859Sml29623 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
33393859Sml29623 			goto fail;
33404977Sraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
33414977Sraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
33423859Sml29623 		if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle,
33433859Sml29623 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
33443859Sml29623 			goto fail;
33453859Sml29623 	} else
33463859Sml29623 		goto fail;
33473859Sml29623 
33483859Sml29623 	MUTEX_EXIT(&nxge_mii_lock);
33493859Sml29623 
33503859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>"
33513859Sml29623 			"xcvr_reg<%d>", xcvr_portn, xcvr_reg));
33523859Sml29623 	return (NXGE_OK);
33533859Sml29623 fail:
33543859Sml29623 	MUTEX_EXIT(&nxge_mii_lock);
33553859Sml29623 
33563859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
33573859Sml29623 			"nxge_mii_write: Failed to write mii on xcvr %d",
33583859Sml29623 			xcvr_portn));
33593859Sml29623 
33603859Sml29623 	return (NXGE_ERROR | rs);
33613859Sml29623 }
33623859Sml29623 
33633859Sml29623 /* Perform read from Clause45 serdes / transceiver device */
33643859Sml29623 
33653859Sml29623 nxge_status_t
33663859Sml29623 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
33673859Sml29623 		uint16_t xcvr_reg, uint16_t *value)
33683859Sml29623 {
33693859Sml29623 	npi_status_t rs = NPI_SUCCESS;
33703859Sml29623 
33713859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>",
33723859Sml29623 			xcvr_portn));
33733859Sml29623 
33743859Sml29623 	MUTEX_ENTER(&nxge_mdio_lock);
33753859Sml29623 
33763859Sml29623 	if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle,
33773859Sml29623 			xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
33783859Sml29623 		goto fail;
33793859Sml29623 
33803859Sml29623 	MUTEX_EXIT(&nxge_mdio_lock);
33813859Sml29623 
33823859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>",
33833859Sml29623 			xcvr_portn));
33843859Sml29623 	return (NXGE_OK);
33853859Sml29623 fail:
33863859Sml29623 	MUTEX_EXIT(&nxge_mdio_lock);
33873859Sml29623 
33883859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
33893859Sml29623 			"nxge_mdio_read: Failed to read mdio on xcvr %d",
33903859Sml29623 			xcvr_portn));
33913859Sml29623 
33923859Sml29623 	return (NXGE_ERROR | rs);
33933859Sml29623 }
33943859Sml29623 
33953859Sml29623 /* Perform write to Clause45 serdes / transceiver device */
33963859Sml29623 
33973859Sml29623 nxge_status_t
33983859Sml29623 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
33993859Sml29623 		uint16_t xcvr_reg, uint16_t value)
34003859Sml29623 {
34013859Sml29623 	npi_status_t rs = NPI_SUCCESS;
34023859Sml29623 
34033859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>",
34043859Sml29623 			xcvr_portn));
34053859Sml29623 
34063859Sml29623 	MUTEX_ENTER(&nxge_mdio_lock);
34073859Sml29623 
34083859Sml29623 	if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle,
34093859Sml29623 			xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
34103859Sml29623 		goto fail;
34113859Sml29623 
34123859Sml29623 	MUTEX_EXIT(&nxge_mdio_lock);
34133859Sml29623 
34143859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>",
34153859Sml29623 			xcvr_portn));
34163859Sml29623 	return (NXGE_OK);
34173859Sml29623 fail:
34183859Sml29623 	MUTEX_EXIT(&nxge_mdio_lock);
34193859Sml29623 
34203859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
34213859Sml29623 			"nxge_mdio_write: Failed to write mdio on xcvr %d",
34223859Sml29623 			xcvr_portn));
34233859Sml29623 
34243859Sml29623 	return (NXGE_ERROR | rs);
34253859Sml29623 }
34263859Sml29623 
34273859Sml29623 
34283859Sml29623 /* Check MII to see if there is any link status change */
34293859Sml29623 
34303859Sml29623 nxge_status_t
34313859Sml29623 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints,
34323859Sml29623 		nxge_link_state_t *link_up)
34333859Sml29623 {
34343859Sml29623 	p_nxge_param_t	param_arr;
34353859Sml29623 	p_nxge_stats_t	statsp;
34363859Sml29623 	p_mii_regs_t	mii_regs;
34373859Sml29623 	p_mii_bmsr_t	soft_bmsr;
34383859Sml29623 	mii_anar_t	anar;
34393859Sml29623 	mii_anlpar_t	anlpar;
34403859Sml29623 	mii_anar_t	an_common;
34413859Sml29623 	mii_aner_t	aner;
34423859Sml29623 	mii_gsr_t	gsr;
34433859Sml29623 	nxge_status_t	status = NXGE_OK;
34443859Sml29623 
34453859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check"));
34463859Sml29623 
34473859Sml29623 	mii_regs = NULL;
34483859Sml29623 	param_arr = nxgep->param_arr;
34493859Sml29623 	statsp = nxgep->statsp;
34503859Sml29623 	soft_bmsr = &nxgep->soft_bmsr;
34513859Sml29623 	*link_up = LINK_NO_CHANGE;
34523859Sml29623 
34535196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
34545196Ssbehera 	    "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x",
34555196Ssbehera 	    bmsr.value, bmsr_ints.value));
34565196Ssbehera 
34573859Sml29623 	if (bmsr_ints.bits.link_status) {
34585196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
34595196Ssbehera 		    "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x",
34605196Ssbehera 		    bmsr.value, bmsr_ints.value));
34613859Sml29623 		if (bmsr.bits.link_status) {
34623859Sml29623 			soft_bmsr->bits.link_status = 1;
34635196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
34645196Ssbehera 		    "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int "
34655196Ssbehera 		    "0x%x", bmsr.value, bmsr_ints.value));
34663859Sml29623 		} else {
34673859Sml29623 			statsp->mac_stats.link_up = 0;
34683859Sml29623 			soft_bmsr->bits.link_status = 0;
34693859Sml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
34703859Sml29623 					"Link down cable problem"));
34713859Sml29623 			*link_up = LINK_IS_DOWN;
34723859Sml29623 		}
34733859Sml29623 	}
34743859Sml29623 
34755196Ssbehera 	if (nxgep->mac.portmode == PORT_1G_COPPER &&
34765196Ssbehera 	    param_arr[param_autoneg].value) {
34773859Sml29623 		if (bmsr_ints.bits.auto_neg_complete) {
34783859Sml29623 			if (bmsr.bits.auto_neg_complete)
34793859Sml29623 				soft_bmsr->bits.auto_neg_complete = 1;
34803859Sml29623 			else
34813859Sml29623 				soft_bmsr->bits.auto_neg_complete = 0;
34823859Sml29623 		}
34833859Sml29623 		if (soft_bmsr->bits.link_status == 0) {
34843859Sml29623 			statsp->mac_stats.link_T4 = 0;
34853859Sml29623 			statsp->mac_stats.link_speed = 0;
34863859Sml29623 			statsp->mac_stats.link_duplex = 0;
34873859Sml29623 			statsp->mac_stats.link_asmpause = 0;
34883859Sml29623 			statsp->mac_stats.link_pause = 0;
34893859Sml29623 			statsp->mac_stats.lp_cap_autoneg = 0;
34903859Sml29623 			statsp->mac_stats.lp_cap_100T4 = 0;
34913859Sml29623 			statsp->mac_stats.lp_cap_1000fdx = 0;
34923859Sml29623 			statsp->mac_stats.lp_cap_1000hdx = 0;
34933859Sml29623 			statsp->mac_stats.lp_cap_100fdx = 0;
34943859Sml29623 			statsp->mac_stats.lp_cap_100hdx = 0;
34953859Sml29623 			statsp->mac_stats.lp_cap_10fdx = 0;
34963859Sml29623 			statsp->mac_stats.lp_cap_10hdx = 0;
34973859Sml29623 			statsp->mac_stats.lp_cap_10gfdx = 0;
34983859Sml29623 			statsp->mac_stats.lp_cap_10ghdx = 0;
34993859Sml29623 			statsp->mac_stats.lp_cap_asmpause = 0;
35003859Sml29623 			statsp->mac_stats.lp_cap_pause = 0;
35013859Sml29623 		}
35023859Sml29623 	} else
35033859Sml29623 		soft_bmsr->bits.auto_neg_complete = 1;
35043859Sml29623 
35053859Sml29623 	if ((bmsr_ints.bits.link_status ||
35063859Sml29623 		bmsr_ints.bits.auto_neg_complete) &&
35073859Sml29623 		soft_bmsr->bits.link_status &&
35083859Sml29623 		soft_bmsr->bits.auto_neg_complete) {
35093859Sml29623 		statsp->mac_stats.link_up = 1;
35105196Ssbehera 
35115196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
35125196Ssbehera 		    "==> nxge_mii_check "
35135196Ssbehera 		    "(auto negotiation complete or link up) "
35145196Ssbehera 		    "soft bmsr 0x%x bmsr_int 0x%x",
35155196Ssbehera 		    bmsr.value, bmsr_ints.value));
35165196Ssbehera 
35175196Ssbehera 		if (nxgep->mac.portmode == PORT_1G_COPPER &&
35185196Ssbehera 		    param_arr[param_autoneg].value) {
35193859Sml29623 			if ((status = nxge_mii_read(nxgep,
35203859Sml29623 				statsp->mac_stats.xcvr_portn,
35215125Sjoycey #if defined(__i386)
35225125Sjoycey 				(uint8_t)(uint32_t)(&mii_regs->anar),
35235125Sjoycey #else
35243859Sml29623 				(uint8_t)(uint64_t)(&mii_regs->anar),
35255125Sjoycey #endif
35263859Sml29623 					&anar.value)) != NXGE_OK)
35273859Sml29623 				goto fail;
35283859Sml29623 			if ((status = nxge_mii_read(nxgep,
35293859Sml29623 				statsp->mac_stats.xcvr_portn,
35305125Sjoycey #if defined(__i386)
35315125Sjoycey 				(uint8_t)(uint32_t)(&mii_regs->anlpar),
35325125Sjoycey #else
35333859Sml29623 				(uint8_t)(uint64_t)(&mii_regs->anlpar),
35345125Sjoycey #endif
35353859Sml29623 					&anlpar.value)) != NXGE_OK)
35363859Sml29623 				goto fail;
35373859Sml29623 			if ((status = nxge_mii_read(nxgep,
35383859Sml29623 				statsp->mac_stats.xcvr_portn,
35395125Sjoycey #if defined(__i386)
35405125Sjoycey 				(uint8_t)(uint32_t)(&mii_regs->aner),
35415125Sjoycey #else
35423859Sml29623 				(uint8_t)(uint64_t)(&mii_regs->aner),
35435125Sjoycey #endif
35443859Sml29623 					&aner.value)) != NXGE_OK)
35453859Sml29623 				goto fail;
35463859Sml29623 			statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able;
35473859Sml29623 			statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4;
35483859Sml29623 			statsp->mac_stats.lp_cap_100fdx =
35493859Sml29623 							anlpar.bits.cap_100fdx;
35503859Sml29623 			statsp->mac_stats.lp_cap_100hdx =
35513859Sml29623 							anlpar.bits.cap_100hdx;
35523859Sml29623 			statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx;
35533859Sml29623 			statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx;
35543859Sml29623 			statsp->mac_stats.lp_cap_asmpause =
35553859Sml29623 						anlpar.bits.cap_asmpause;
35563859Sml29623 			statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause;
35573859Sml29623 			an_common.value = anar.value & anlpar.value;
35583859Sml29623 			if (param_arr[param_anar_1000fdx].value ||
35593859Sml29623 				param_arr[param_anar_1000hdx].value) {
35603859Sml29623 				if ((status = nxge_mii_read(nxgep,
35613859Sml29623 					statsp->mac_stats.xcvr_portn,
35625125Sjoycey #if defined(__i386)
35635125Sjoycey 					(uint8_t)(uint32_t)(&mii_regs->gsr),
35645125Sjoycey #else
35653859Sml29623 					(uint8_t)(uint64_t)(&mii_regs->gsr),
35665125Sjoycey #endif
35673859Sml29623 						&gsr.value))
35683859Sml29623 						!= NXGE_OK)
35693859Sml29623 					goto fail;
35703859Sml29623 				statsp->mac_stats.lp_cap_1000fdx =
35713859Sml29623 					gsr.bits.link_1000fdx;
35723859Sml29623 				statsp->mac_stats.lp_cap_1000hdx =
35733859Sml29623 					gsr.bits.link_1000hdx;
35743859Sml29623 				if (param_arr[param_anar_1000fdx].value &&
35753859Sml29623 					gsr.bits.link_1000fdx) {
35763859Sml29623 					statsp->mac_stats.link_speed = 1000;
35773859Sml29623 					statsp->mac_stats.link_duplex = 2;
35783859Sml29623 				} else if (
35793859Sml29623 					param_arr[param_anar_1000hdx].value &&
35803859Sml29623 						gsr.bits.link_1000hdx) {
35813859Sml29623 					statsp->mac_stats.link_speed = 1000;
35823859Sml29623 					statsp->mac_stats.link_duplex = 1;
35833859Sml29623 				}
35843859Sml29623 			}
35853859Sml29623 			if ((an_common.value != 0) &&
35863859Sml29623 					!(statsp->mac_stats.link_speed)) {
35873859Sml29623 				if (an_common.bits.cap_100T4) {
35883859Sml29623 					statsp->mac_stats.link_T4 = 1;
35893859Sml29623 					statsp->mac_stats.link_speed = 100;
35903859Sml29623 					statsp->mac_stats.link_duplex = 1;
35913859Sml29623 				} else if (an_common.bits.cap_100fdx) {
35923859Sml29623 					statsp->mac_stats.link_speed = 100;
35933859Sml29623 					statsp->mac_stats.link_duplex = 2;
35943859Sml29623 				} else if (an_common.bits.cap_100hdx) {
35953859Sml29623 					statsp->mac_stats.link_speed = 100;
35963859Sml29623 					statsp->mac_stats.link_duplex = 1;
35973859Sml29623 				} else if (an_common.bits.cap_10fdx) {
35983859Sml29623 					statsp->mac_stats.link_speed = 10;
35993859Sml29623 					statsp->mac_stats.link_duplex = 2;
36003859Sml29623 				} else if (an_common.bits.cap_10hdx) {
36013859Sml29623 					statsp->mac_stats.link_speed = 10;
36023859Sml29623 					statsp->mac_stats.link_duplex = 1;
36033859Sml29623 				} else {
36043859Sml29623 					goto fail;
36053859Sml29623 				}
36063859Sml29623 			}
36073859Sml29623 			if (statsp->mac_stats.link_duplex != 1) {
36083859Sml29623 				statsp->mac_stats.link_asmpause =
36093859Sml29623 					an_common.bits.cap_asmpause;
36103859Sml29623 				if (statsp->mac_stats.link_asmpause)
36113859Sml29623 				if ((statsp->mac_stats.cap_pause == 0) &&
36123859Sml29623 						(statsp->mac_stats.lp_cap_pause
36133859Sml29623 						== 1))
36143859Sml29623 						statsp->mac_stats.link_pause
36153859Sml29623 						= 0;
36163859Sml29623 					else
36173859Sml29623 						statsp->mac_stats.link_pause
36183859Sml29623 						= 1;
36193859Sml29623 				else
36203859Sml29623 					statsp->mac_stats.link_pause =
36213859Sml29623 						an_common.bits.cap_pause;
36223859Sml29623 			}
36235196Ssbehera 		} else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
36245196Ssbehera 			statsp->mac_stats.link_speed = 1000;
36255196Ssbehera 			statsp->mac_stats.link_duplex = 2;
36263859Sml29623 		}
36273859Sml29623 		*link_up = LINK_IS_UP;
36283859Sml29623 	}
36293859Sml29623 
36303859Sml29623 	if (nxgep->link_notify) {
36313859Sml29623 		*link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP :
36323859Sml29623 				LINK_IS_DOWN);
36333859Sml29623 		nxgep->link_notify = B_FALSE;
36343859Sml29623 	}
36353859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check"));
36363859Sml29623 	return (NXGE_OK);
36373859Sml29623 fail:
36383859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
36393859Sml29623 			"nxge_mii_check: Unable to check MII"));
36403859Sml29623 	return (status);
36413859Sml29623 }
36423859Sml29623 
36434977Sraghus /* Check PCS to see if there is any link status change */
36444977Sraghus nxge_status_t
36454977Sraghus nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up)
36464977Sraghus {
36474977Sraghus 	p_nxge_stats_t	statsp;
36484977Sraghus 	nxge_status_t	status = NXGE_OK;
36494977Sraghus 	boolean_t	linkup;
36504977Sraghus 
36514977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check"));
36524977Sraghus 
36534977Sraghus 	statsp = nxgep->statsp;
36544977Sraghus 	*link_up = LINK_NO_CHANGE;
36554977Sraghus 
36564977Sraghus 	(void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup);
36574977Sraghus 	if (linkup) {
36584977Sraghus 		if (nxgep->link_notify ||
36594977Sraghus 		    nxgep->statsp->mac_stats.link_up == 0) {
36604977Sraghus 			statsp->mac_stats.link_up = 1;
36614977Sraghus 			statsp->mac_stats.link_speed = 1000;
36624977Sraghus 			statsp->mac_stats.link_duplex = 2;
36634977Sraghus 			*link_up = LINK_IS_UP;
36644977Sraghus 			nxgep->link_notify = B_FALSE;
36654977Sraghus 		}
36664977Sraghus 	} else {
36674977Sraghus 		if (nxgep->link_notify ||
36684977Sraghus 		    nxgep->statsp->mac_stats.link_up == 1) {
36694977Sraghus 			statsp->mac_stats.link_up = 0;
36704977Sraghus 			statsp->mac_stats.link_speed = 0;
36714977Sraghus 			statsp->mac_stats.link_duplex = 0;
36724977Sraghus 			*link_up = LINK_IS_DOWN;
36734977Sraghus 			nxgep->link_notify = B_FALSE;
36744977Sraghus 		}
36754977Sraghus 	}
36764977Sraghus 
36774977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check"));
36784977Sraghus 	return (NXGE_OK);
36794977Sraghus fail:
36804977Sraghus 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
36814977Sraghus 	    "nxge_pcs_check: Unable to check PCS"));
36824977Sraghus 	return (status);
36834977Sraghus }
36844977Sraghus 
36853859Sml29623 /* Add a multicast address entry into the HW hash table */
36863859Sml29623 
36873859Sml29623 nxge_status_t
36883859Sml29623 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
36893859Sml29623 {
36903859Sml29623 	uint32_t mchash;
36913859Sml29623 	p_hash_filter_t hash_filter;
36923859Sml29623 	uint16_t hash_bit;
36933859Sml29623 	boolean_t rx_init = B_FALSE;
36943859Sml29623 	uint_t j;
36953859Sml29623 	nxge_status_t status = NXGE_OK;
36963859Sml29623 
36973859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr"));
36983859Sml29623 
36993859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
37003859Sml29623 	mchash = crc32_mchash(addrp);
37013859Sml29623 	if (nxgep->hash_filter == NULL) {
37023859Sml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
37033859Sml29623 			"Allocating hash filter storage."));
37043859Sml29623 		nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t),
37053859Sml29623 					KM_SLEEP);
37063859Sml29623 	}
37073859Sml29623 	hash_filter = nxgep->hash_filter;
37083859Sml29623 	j = mchash / HASH_REG_WIDTH;
37093859Sml29623 	hash_bit = (1 << (mchash % HASH_REG_WIDTH));
37103859Sml29623 	hash_filter->hash_filter_regs[j] |= hash_bit;
37113859Sml29623 	hash_filter->hash_bit_ref_cnt[mchash]++;
37123859Sml29623 	if (hash_filter->hash_bit_ref_cnt[mchash] == 1) {
37133859Sml29623 		hash_filter->hash_ref_cnt++;
37143859Sml29623 		rx_init = B_TRUE;
37153859Sml29623 	}
37163859Sml29623 	if (rx_init) {
37173859Sml29623 		if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
37183859Sml29623 			goto fail;
37193859Sml29623 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
37203859Sml29623 			goto fail;
37213859Sml29623 	}
37223859Sml29623 
37233859Sml29623 	RW_EXIT(&nxgep->filter_lock);
37243859Sml29623 
37253859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr"));
37263859Sml29623 
37273859Sml29623 	return (NXGE_OK);
37283859Sml29623 fail:
37293859Sml29623 	RW_EXIT(&nxgep->filter_lock);
37303859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: "
37313859Sml29623 					"Unable to add multicast address"));
37323859Sml29623 	return (status);
37333859Sml29623 }
37343859Sml29623 
37353859Sml29623 /* Remove a multicast address entry from the HW hash table */
37363859Sml29623 
37373859Sml29623 nxge_status_t
37383859Sml29623 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
37393859Sml29623 {
37403859Sml29623 	uint32_t mchash;
37413859Sml29623 	p_hash_filter_t hash_filter;
37423859Sml29623 	uint16_t hash_bit;
37433859Sml29623 	boolean_t rx_init = B_FALSE;
37443859Sml29623 	uint_t j;
37453859Sml29623 	nxge_status_t status = NXGE_OK;
37463859Sml29623 
37473859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr"));
37483859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
37493859Sml29623 	mchash = crc32_mchash(addrp);
37503859Sml29623 	if (nxgep->hash_filter == NULL) {
37513859Sml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
37523859Sml29623 			"Hash filter already de_allocated."));
37533859Sml29623 		RW_EXIT(&nxgep->filter_lock);
37543859Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
37553859Sml29623 		return (NXGE_OK);
37563859Sml29623 	}
37573859Sml29623 	hash_filter = nxgep->hash_filter;
37583859Sml29623 	hash_filter->hash_bit_ref_cnt[mchash]--;
37593859Sml29623 	if (hash_filter->hash_bit_ref_cnt[mchash] == 0) {
37603859Sml29623 		j = mchash / HASH_REG_WIDTH;
37613859Sml29623 		hash_bit = (1 << (mchash % HASH_REG_WIDTH));
37623859Sml29623 		hash_filter->hash_filter_regs[j] &= ~hash_bit;
37633859Sml29623 		hash_filter->hash_ref_cnt--;
37643859Sml29623 		rx_init = B_TRUE;
37653859Sml29623 	}
37663859Sml29623 	if (hash_filter->hash_ref_cnt == 0) {
37673859Sml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
37683859Sml29623 			"De-allocating hash filter storage."));
37693859Sml29623 		KMEM_FREE(hash_filter, sizeof (hash_filter_t));
37703859Sml29623 		nxgep->hash_filter = NULL;
37713859Sml29623 	}
37723859Sml29623 
37733859Sml29623 	if (rx_init) {
37743859Sml29623 		if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
37753859Sml29623 			goto fail;
37763859Sml29623 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
37773859Sml29623 			goto fail;
37783859Sml29623 	}
37793859Sml29623 	RW_EXIT(&nxgep->filter_lock);
37803859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
37813859Sml29623 
37823859Sml29623 	return (NXGE_OK);
37833859Sml29623 fail:
37843859Sml29623 	RW_EXIT(&nxgep->filter_lock);
37853859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: "
37863859Sml29623 			"Unable to remove multicast address"));
37873859Sml29623 
37883859Sml29623 	return (status);
37893859Sml29623 }
37903859Sml29623 
37913859Sml29623 /* Set MAC address into MAC address HW registers */
37923859Sml29623 
37933859Sml29623 nxge_status_t
37943859Sml29623 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp)
37953859Sml29623 {
37963859Sml29623 	nxge_status_t status = NXGE_OK;
37973859Sml29623 
37983859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr"));
37993859Sml29623 
38003859Sml29623 	MUTEX_ENTER(&nxgep->ouraddr_lock);
38013859Sml29623 	/*
38023859Sml29623 	 * Exit if the address is same as ouraddr or multicast or broadcast
38033859Sml29623 	 */
38043859Sml29623 	if (((addrp->ether_addr_octet[0] & 01) == 1) ||
38053859Sml29623 		(ether_cmp(addrp, &etherbroadcastaddr) == 0) ||
38063859Sml29623 		(ether_cmp(addrp, &nxgep->ouraddr) == 0)) {
38073859Sml29623 		goto nxge_set_mac_addr_exit;
38083859Sml29623 	}
38093859Sml29623 	nxgep->ouraddr = *addrp;
38103859Sml29623 	/*
38113859Sml29623 	 * Set new interface local address and re-init device.
38123859Sml29623 	 * This is destructive to any other streams attached
38133859Sml29623 	 * to this device.
38143859Sml29623 	 */
38153859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
38163859Sml29623 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
38173859Sml29623 		goto fail;
38183859Sml29623 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
38193859Sml29623 		goto fail;
38203859Sml29623 
38213859Sml29623 	RW_EXIT(&nxgep->filter_lock);
38223859Sml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
38233859Sml29623 	goto nxge_set_mac_addr_end;
38243859Sml29623 nxge_set_mac_addr_exit:
38253859Sml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
38263859Sml29623 nxge_set_mac_addr_end:
38273859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr"));
38283859Sml29623 
38293859Sml29623 	return (NXGE_OK);
38303859Sml29623 fail:
38313859Sml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
38323859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: "
38333859Sml29623 			"Unable to set mac address"));
38343859Sml29623 	return (status);
38353859Sml29623 }
38363859Sml29623 
38374693Stm144005 static
38384693Stm144005 check_link_state_t
38394693Stm144005 nxge_check_link_stop(
38404693Stm144005 	nxge_t *nxge)
38414693Stm144005 {
38424693Stm144005 	/* If the poll has been cancelled, return STOP. */
38434693Stm144005 	MUTEX_ENTER(&nxge->poll_lock);
38444693Stm144005 	if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) {
38454693Stm144005 		nxge->poll_state = LINK_MONITOR_STOP;
38464693Stm144005 		nxge->nxge_link_poll_timerid = 0;
38474693Stm144005 		cv_broadcast(&nxge->poll_cv);
38484693Stm144005 		MUTEX_EXIT(&nxge->poll_lock);
38494693Stm144005 
38504693Stm144005 		NXGE_DEBUG_MSG((nxge, MAC_CTL,
38514693Stm144005 		    "nxge_check_%s_link(port<%d>) stopped.",
38524693Stm144005 		    nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii",
38534693Stm144005 		    nxge->mac.portnum));
38544693Stm144005 		return (CHECK_LINK_STOP);
38554693Stm144005 	}
38564693Stm144005 	MUTEX_EXIT(&nxge->poll_lock);
38574693Stm144005 
38584693Stm144005 	return (CHECK_LINK_RESCHEDULE);
38594693Stm144005 }
38604693Stm144005 
38613859Sml29623 /* Check status of MII (MIF or PCS) link */
38623859Sml29623 
38634732Sdavemq static nxge_status_t
38643859Sml29623 nxge_check_mii_link(p_nxge_t nxgep)
38653859Sml29623 {
38663859Sml29623 	mii_bmsr_t bmsr_ints, bmsr_data;
38673859Sml29623 	mii_anlpar_t anlpar;
38683859Sml29623 	mii_gsr_t gsr;
38693859Sml29623 	p_mii_regs_t mii_regs;
38703859Sml29623 	nxge_status_t status = NXGE_OK;
38713859Sml29623 	uint8_t portn;
38723859Sml29623 	nxge_link_state_t link_up;
38733859Sml29623 
38744693Stm144005 	if (nxgep->nxge_magic != NXGE_MAGIC)
38754693Stm144005 		return (NXGE_ERROR);
38764693Stm144005 
38774693Stm144005 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
38784693Stm144005 		return (NXGE_OK);
38794693Stm144005 
38803859Sml29623 	portn = nxgep->mac.portnum;
38813859Sml29623 
38823859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>",
38834693Stm144005 	    portn));
38843859Sml29623 
38853859Sml29623 	mii_regs = NULL;
38863859Sml29623 
38873859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
38883859Sml29623 
38893859Sml29623 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
38903859Sml29623 		goto nxge_check_mii_link_exit;
38913859Sml29623 
38924977Sraghus 	switch (nxgep->mac.portmode) {
38934977Sraghus 	default:
38945196Ssbehera 		bmsr_data.value = 0;
38953859Sml29623 		if ((status = nxge_mii_read(nxgep,
38964977Sraghus 		    nxgep->statsp->mac_stats.xcvr_portn,
38975125Sjoycey #if defined(__i386)
38985125Sjoycey 		    (uint8_t)(uint32_t)(&mii_regs->bmsr),
38995125Sjoycey #else
39004977Sraghus 		    (uint8_t)(uint64_t)(&mii_regs->bmsr),
39015125Sjoycey #endif
39024977Sraghus 		    &bmsr_data.value)) != NXGE_OK) {
39033859Sml29623 			goto fail;
39043859Sml29623 		}
39054977Sraghus 
39065196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
39075196Ssbehera 		    "==> nxge_check_mii_link port<0x%x> "
39085196Ssbehera 		    "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ",
39095196Ssbehera 		    xcvr_portn, bmsr_data.value, nxgep->bmsr.value));
39105196Ssbehera 
39114977Sraghus 		if (nxgep->param_arr[param_autoneg].value) {
39124977Sraghus 			if ((status = nxge_mii_read(nxgep,
39134977Sraghus 				nxgep->statsp->mac_stats.xcvr_portn,
39145125Sjoycey #if defined(__i386)
39155125Sjoycey 				(uint8_t)(uint32_t)(&mii_regs->gsr),
39165125Sjoycey #else
39174977Sraghus 				(uint8_t)(uint64_t)(&mii_regs->gsr),
39185125Sjoycey #endif
39194977Sraghus 				&gsr.value)) != NXGE_OK)
39204977Sraghus 				goto fail;
39214977Sraghus 			if ((status = nxge_mii_read(nxgep,
39224977Sraghus 				nxgep->statsp->mac_stats.xcvr_portn,
39235125Sjoycey #if defined(__i386)
39245125Sjoycey 				(uint8_t)(uint32_t)(&mii_regs->anlpar),
39255125Sjoycey #else
39264977Sraghus 				(uint8_t)(uint64_t)(&mii_regs->anlpar),
39275125Sjoycey #endif
39284977Sraghus 				&anlpar.value)) != NXGE_OK)
39294977Sraghus 				goto fail;
39305196Ssbehera 			if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) {
39315196Ssbehera 
39325196Ssbehera 				if (nxgep->statsp->mac_stats.link_up &&
39335196Ssbehera 				    ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^
39345196Ssbehera 				    gsr.bits.link_1000fdx) ||
39355196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_1000hdx ^
39365196Ssbehera 				    gsr.bits.link_1000hdx) ||
39375196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100T4 ^
39385196Ssbehera 				    anlpar.bits.cap_100T4) ||
39395196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100fdx ^
39405196Ssbehera 				    anlpar.bits.cap_100fdx) ||
39415196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100hdx ^
39425196Ssbehera 				    anlpar.bits.cap_100hdx) ||
39435196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_10fdx ^
39445196Ssbehera 				    anlpar.bits.cap_10fdx) ||
39455196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_10hdx ^
39465196Ssbehera 				    anlpar.bits.cap_10hdx))) {
39475196Ssbehera 					bmsr_data.bits.link_status = 0;
39485196Ssbehera 				}
39494977Sraghus 			}
39504977Sraghus 		}
39514977Sraghus 
39524977Sraghus 		/* Workaround for link down issue */
39534977Sraghus 		if (bmsr_data.value == 0) {
39544977Sraghus 			cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
39554977Sraghus 			goto nxge_check_mii_link_exit;
39564977Sraghus 		}
39574977Sraghus 
39585196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
39595196Ssbehera 		    "==> nxge_check_mii_link port<0x%x> :"
39605196Ssbehera 		    "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x",
39615196Ssbehera 		    xcvr_portn, nxgep->bmsr.value, bmsr_data.value));
39625196Ssbehera 
39634977Sraghus 		bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value;
39644977Sraghus 		nxgep->bmsr.value = bmsr_data.value;
39655196Ssbehera 
39665196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
39675196Ssbehera 		    "==> nxge_check_mii_link port<0x%x> CALLING "
39685196Ssbehera 		    "bmsr_data 0x%x bmsr_ints.value 0x%x",
39695196Ssbehera 		    xcvr_portn, bmsr_data.value, bmsr_ints.value));
39705196Ssbehera 
39714977Sraghus 		if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints,
39724977Sraghus 		    &link_up)) != NXGE_OK) {
39734977Sraghus 			goto fail;
39744977Sraghus 		}
39754977Sraghus 		break;
39764977Sraghus 
39774977Sraghus 	case PORT_1G_SERDES:
39784977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
39794977Sraghus 		    "==> nxge_check_mii_link port<%d> (SERDES)", portn));
39804977Sraghus 		if ((status = nxge_pcs_check(nxgep, portn, &link_up))
39814977Sraghus 		    != NXGE_OK) {
39824977Sraghus 			goto fail;
39834977Sraghus 		}
39844977Sraghus 		break;
39853859Sml29623 	}
39863859Sml29623 
39873859Sml29623 nxge_check_mii_link_exit:
39883859Sml29623 	RW_EXIT(&nxgep->filter_lock);
39893859Sml29623 	if (link_up == LINK_IS_UP) {
39903859Sml29623 		nxge_link_is_up(nxgep);
39913859Sml29623 	} else if (link_up == LINK_IS_DOWN) {
39923859Sml29623 		nxge_link_is_down(nxgep);
39933859Sml29623 	}
39943859Sml29623 
39953859Sml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
39963859Sml29623 
39973859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>",
39984977Sraghus 				portn));
39993859Sml29623 	return (NXGE_OK);
40003859Sml29623 
40013859Sml29623 fail:
40023859Sml29623 	RW_EXIT(&nxgep->filter_lock);
40033859Sml29623 
40043859Sml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
40053859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
40064977Sraghus 			"nxge_check_mii_link: Failed to check link port<%d>",
40074977Sraghus 			portn));
40083859Sml29623 	return (status);
40093859Sml29623 }
40103859Sml29623 
40113859Sml29623 
40123859Sml29623 /*ARGSUSED*/
40134732Sdavemq static nxge_status_t
40143859Sml29623 nxge_check_10g_link(p_nxge_t nxgep)
40153859Sml29623 {
40163859Sml29623 	uint8_t		portn;
40173859Sml29623 	nxge_status_t	status = NXGE_OK;
40185422Ssbehera 	boolean_t	link_up;
40194977Sraghus 	uint32_t	val;
40204977Sraghus 	npi_status_t	rs;
40213859Sml29623 
40224693Stm144005 	if (nxgep->nxge_magic != NXGE_MAGIC)
40234693Stm144005 		return (NXGE_ERROR);
40244693Stm144005 
40254693Stm144005 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
40264693Stm144005 		return (NXGE_OK);
40274693Stm144005 
40283859Sml29623 	portn = nxgep->mac.portnum;
40295196Ssbehera 	val = 0;
40305196Ssbehera 	rs = NPI_SUCCESS;
40313859Sml29623 
40323859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
40334693Stm144005 	    portn));
40343859Sml29623 
40354977Sraghus 	switch (nxgep->mac.portmode) {
40364977Sraghus 	default:
40374977Sraghus 		status = nxge_check_bcm8704_link(nxgep, &link_up);
40384977Sraghus 		if (status != NXGE_OK)
40394977Sraghus 			goto fail;
40404977Sraghus 		break;
40414977Sraghus 	case PORT_10G_SERDES:
40424977Sraghus 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
40435422Ssbehera 		    XPCS_REG_STATUS, &val);
40444977Sraghus 		if (rs != 0)
40454977Sraghus 			goto fail;
40464977Sraghus 
40474977Sraghus 		link_up = B_FALSE;
40485422Ssbehera 		if (val & XPCS_STATUS_LANE_ALIGN) {
40495422Ssbehera 			link_up = B_TRUE;
40504977Sraghus 		}
40514977Sraghus 
40524977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
40534977Sraghus 		    "==> nxge_check_10g_link port<%d> "
40545422Ssbehera 		    "XPCS_REG_STATUS2 0x%x link_up %d",
40555422Ssbehera 		    portn, val, link_up));
40565422Ssbehera 
40574977Sraghus 		break;
40584977Sraghus 	}
40593859Sml29623 
40603859Sml29623 	if (link_up) {
40613859Sml29623 		if (nxgep->link_notify ||
40623859Sml29623 			nxgep->statsp->mac_stats.link_up == 0) {
40633859Sml29623 			if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
40643859Sml29623 				goto fail;
40653859Sml29623 			nxgep->statsp->mac_stats.link_up = 1;
40663859Sml29623 			nxgep->statsp->mac_stats.link_speed = 10000;
40673859Sml29623 			nxgep->statsp->mac_stats.link_duplex = 2;
40683859Sml29623 
40693859Sml29623 			nxge_link_is_up(nxgep);
40703859Sml29623 			nxgep->link_notify = B_FALSE;
40713859Sml29623 		}
40723859Sml29623 	} else {
40733859Sml29623 		if (nxgep->link_notify ||
40743859Sml29623 			nxgep->statsp->mac_stats.link_up == 1) {
40753859Sml29623 			if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
40763859Sml29623 				goto fail;
40773859Sml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
40784977Sraghus 					"Link down cable problem"));
40793859Sml29623 			nxgep->statsp->mac_stats.link_up = 0;
40803859Sml29623 			nxgep->statsp->mac_stats.link_speed = 0;
40813859Sml29623 			nxgep->statsp->mac_stats.link_duplex = 0;
40823859Sml29623 
40833859Sml29623 			nxge_link_is_down(nxgep);
40843859Sml29623 			nxgep->link_notify = B_FALSE;
40853859Sml29623 		}
40863859Sml29623 	}
40873859Sml29623 
40883859Sml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
40893859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
40904693Stm144005 	    portn));
40913859Sml29623 	return (NXGE_OK);
40923859Sml29623 
40933859Sml29623 fail:
40944693Stm144005 	(void) nxge_check_link_stop(nxgep);
40954693Stm144005 
40963859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
40974693Stm144005 	    "nxge_check_10g_link: Failed to check link port<%d>",
40984693Stm144005 	    portn));
40993859Sml29623 	return (status);
41003859Sml29623 }
41013859Sml29623 
41023859Sml29623 
41033859Sml29623 /* Declare link down */
41043859Sml29623 
41053859Sml29623 void
41063859Sml29623 nxge_link_is_down(p_nxge_t nxgep)
41073859Sml29623 {
41084732Sdavemq 	p_nxge_stats_t statsp;
41094732Sdavemq 	char link_stat_msg[64];
41104732Sdavemq 
41113859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
41123859Sml29623 
41134732Sdavemq 	statsp = nxgep->statsp;
41144732Sdavemq 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down",
41154732Sdavemq 	    statsp->mac_stats.xcvr_portn);
41164732Sdavemq 
41174732Sdavemq 	if (nxge_no_msg == B_FALSE) {
41184732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
41194732Sdavemq 	}
41204732Sdavemq 
41213859Sml29623 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
41223859Sml29623 
41233859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
41243859Sml29623 }
41253859Sml29623 
41263859Sml29623 /* Declare link up */
41273859Sml29623 
41283859Sml29623 void
41293859Sml29623 nxge_link_is_up(p_nxge_t nxgep)
41303859Sml29623 {
41314732Sdavemq 	p_nxge_stats_t statsp;
41324732Sdavemq 	char link_stat_msg[64];
41333859Sml29623 	uint32_t val;
41343859Sml29623 
41353859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
41363859Sml29623 
41374732Sdavemq 	statsp = nxgep->statsp;
41384732Sdavemq 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ",
41394732Sdavemq 	    statsp->mac_stats.xcvr_portn,
41404732Sdavemq 	    statsp->mac_stats.link_speed);
41414732Sdavemq 
41424732Sdavemq 	if (statsp->mac_stats.link_T4)
41434732Sdavemq 		(void) strcat(link_stat_msg, "T4");
41444732Sdavemq 	else if (statsp->mac_stats.link_duplex == 2)
41454732Sdavemq 		(void) strcat(link_stat_msg, "full duplex");
41464732Sdavemq 	else
41474732Sdavemq 		(void) strcat(link_stat_msg, "half duplex");
41484732Sdavemq 
41493859Sml29623 	(void) nxge_xif_init(nxgep);
41503859Sml29623 
41513859Sml29623 	/* Clean up symbol errors incurred during link transition */
41524977Sraghus 	if ((nxgep->mac.portmode == PORT_10G_FIBER) ||
41534977Sraghus 	    (nxgep->mac.portmode == PORT_10G_SERDES)) {
41543859Sml29623 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
41553859Sml29623 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
41563859Sml29623 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
41573859Sml29623 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
41583859Sml29623 	}
41593859Sml29623 
41604732Sdavemq 	if (nxge_no_msg == B_FALSE) {
41614732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
41624732Sdavemq 	}
41634732Sdavemq 
41643859Sml29623 	mac_link_update(nxgep->mach, LINK_STATE_UP);
41653859Sml29623 
41663859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
41673859Sml29623 }
41683859Sml29623 
41693859Sml29623 /*
41703859Sml29623  * Calculate the bit in the multicast address filter
41713859Sml29623  * that selects the given * address.
41723859Sml29623  * Note: For GEM, the last 8-bits are used.
41733859Sml29623  */
41743859Sml29623 uint32_t
41753859Sml29623 crc32_mchash(p_ether_addr_t addr)
41763859Sml29623 {
41773859Sml29623 	uint8_t *cp;
41783859Sml29623 	uint32_t crc;
41793859Sml29623 	uint32_t c;
41803859Sml29623 	int byte;
41813859Sml29623 	int bit;
41823859Sml29623 
41833859Sml29623 	cp = (uint8_t *)addr;
41843859Sml29623 	crc = (uint32_t)0xffffffff;
41853859Sml29623 	for (byte = 0; byte < 6; byte++) {
41863859Sml29623 		c = (uint32_t)cp[byte];
41873859Sml29623 		for (bit = 0; bit < 8; bit++) {
41883859Sml29623 			if ((c & 0x1) ^ (crc & 0x1))
41893859Sml29623 				crc = (crc >> 1)^0xedb88320;
41903859Sml29623 			else
41913859Sml29623 				crc = (crc >> 1);
41923859Sml29623 			c >>= 1;
41933859Sml29623 		}
41943859Sml29623 	}
41953859Sml29623 	return ((~crc) >> (32 - HASH_BITS));
41963859Sml29623 }
41973859Sml29623 
41983859Sml29623 /* Reset serdes */
41993859Sml29623 
42003859Sml29623 nxge_status_t
42013859Sml29623 nxge_serdes_reset(p_nxge_t nxgep)
42023859Sml29623 {
42033859Sml29623 	npi_handle_t		handle;
42043859Sml29623 
42053859Sml29623 	handle = nxgep->npi_handle;
42063859Sml29623 
42073859Sml29623 	ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1);
42083859Sml29623 	drv_usecwait(500);
42093859Sml29623 	ESR_REG_WR(handle, ESR_CONFIG_REG, 0);
42103859Sml29623 
42113859Sml29623 	return (NXGE_OK);
42123859Sml29623 }
42133859Sml29623 
42143859Sml29623 /* Monitor link status using interrupt or polling */
42153859Sml29623 
42163859Sml29623 nxge_status_t
42173859Sml29623 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable)
42183859Sml29623 {
42193859Sml29623 	nxge_status_t status = NXGE_OK;
42203859Sml29623 
42213859Sml29623 	/*
42224693Stm144005 	 * Return immediately if this is an imaginary XMAC port.
42234693Stm144005 	 * (At least, we don't have 4-port XMAC cards yet.)
42243859Sml29623 	 */
42254977Sraghus 	if ((nxgep->mac.portmode == PORT_10G_FIBER ||
42264977Sraghus 	    nxgep->mac.portmode == PORT_10G_SERDES) &&
42274977Sraghus 	    (nxgep->mac.portnum > 1))
42283859Sml29623 		return (NXGE_OK);
42293859Sml29623 
42303859Sml29623 	if (nxgep->statsp == NULL) {
42313859Sml29623 		/* stats has not been allocated. */
42323859Sml29623 		return (NXGE_OK);
42333859Sml29623 	}
42343859Sml29623 	/* Don't check link if we're not in internal loopback mode */
42353859Sml29623 	if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal)
42363859Sml29623 		return (NXGE_OK);
42373859Sml29623 
42383859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
42394693Stm144005 	    "==> nxge_link_monitor port<%d> enable=%d",
42404693Stm144005 	    nxgep->mac.portnum, enable));
42413859Sml29623 	if (enable == LINK_MONITOR_START) {
42423859Sml29623 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
42433859Sml29623 			if ((status = nxge_link_intr(nxgep, LINK_INTR_START))
42444693Stm144005 			    != NXGE_OK)
42453859Sml29623 				goto fail;
42463859Sml29623 		} else {
42474693Stm144005 			timeout_id_t timerid;
42484693Stm144005 
42494693Stm144005 			if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
42504693Stm144005 				return (NXGE_OK);
42514693Stm144005 
42524732Sdavemq 			if (nxgep->xcvr.check_link) {
42534732Sdavemq 				timerid = timeout(
42544732Sdavemq 				    (fptrv_t)(nxgep->xcvr.check_link),
42554693Stm144005 				    nxgep,
42564693Stm144005 				    drv_usectohz(LINK_MONITOR_PERIOD));
42574732Sdavemq 				MUTEX_ENTER(&nxgep->poll_lock);
42584732Sdavemq 				nxgep->nxge_link_poll_timerid = timerid;
42594732Sdavemq 				MUTEX_EXIT(&nxgep->poll_lock);
42604732Sdavemq 			} else {
42614693Stm144005 				return (NXGE_ERROR);
42623859Sml29623 			}
42633859Sml29623 		}
42643859Sml29623 	} else {
42653859Sml29623 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
42663859Sml29623 			if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP))
42674693Stm144005 			    != NXGE_OK)
42683859Sml29623 				goto fail;
42693859Sml29623 		} else {
42704693Stm144005 			clock_t rv;
42714693Stm144005 
42724693Stm144005 			MUTEX_ENTER(&nxgep->poll_lock);
42734693Stm144005 
42744693Stm144005 			/* If <timerid> == 0, the link monitor has */
42754693Stm144005 			/* never been started, or just now stopped. */
42764693Stm144005 			if (nxgep->nxge_link_poll_timerid == 0) {
42774693Stm144005 				MUTEX_EXIT(&nxgep->poll_lock);
42784693Stm144005 				return (NXGE_OK);
42794693Stm144005 			}
42804693Stm144005 
42814693Stm144005 			nxgep->poll_state = LINK_MONITOR_STOPPING;
42824693Stm144005 			rv = cv_timedwait(&nxgep->poll_cv,
42834693Stm144005 			    &nxgep->poll_lock,
42844693Stm144005 			    ddi_get_lbolt() +
42854693Stm144005 			    drv_usectohz(LM_WAIT_MULTIPLIER *
42864693Stm144005 			    LINK_MONITOR_PERIOD));
42874693Stm144005 			if (rv == -1) {
42884693Stm144005 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
42894693Stm144005 				    "==> stopping port %d: "
42904693Stm144005 				    "cv_timedwait(%d) timed out",
42914693Stm144005 				    nxgep->mac.portnum, nxgep->poll_state));
42924693Stm144005 				nxgep->poll_state = LINK_MONITOR_STOP;
42933859Sml29623 				nxgep->nxge_link_poll_timerid = 0;
42943859Sml29623 			}
42954693Stm144005 
42964693Stm144005 			MUTEX_EXIT(&nxgep->poll_lock);
42973859Sml29623 		}
42983859Sml29623 	}
42993859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
43004693Stm144005 	    "<== nxge_link_monitor port<%d> enable=%d",
43014693Stm144005 	    nxgep->mac.portnum, enable));
43023859Sml29623 	return (NXGE_OK);
43033859Sml29623 fail:
43043859Sml29623 	return (status);
43053859Sml29623 }
43063859Sml29623 
43073859Sml29623 /* Set promiscous mode */
43083859Sml29623 
43093859Sml29623 nxge_status_t
43103859Sml29623 nxge_set_promisc(p_nxge_t nxgep, boolean_t on)
43113859Sml29623 {
43123859Sml29623 	nxge_status_t status = NXGE_OK;
43133859Sml29623 
43144732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on));
43153859Sml29623 
43163859Sml29623 	nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
43173859Sml29623 
43183859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
43193859Sml29623 
43203859Sml29623 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) {
43213859Sml29623 		goto fail;
43223859Sml29623 	}
43233859Sml29623 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) {
43243859Sml29623 		goto fail;
43253859Sml29623 	}
43263859Sml29623 
43273859Sml29623 	RW_EXIT(&nxgep->filter_lock);
43283859Sml29623 
43293859Sml29623 	if (on)
43303859Sml29623 		nxgep->statsp->mac_stats.promisc = B_TRUE;
43313859Sml29623 	else
43323859Sml29623 		nxgep->statsp->mac_stats.promisc = B_FALSE;
43333859Sml29623 
43343859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc"));
43353859Sml29623 
43363859Sml29623 	return (NXGE_OK);
43373859Sml29623 fail:
43383859Sml29623 	RW_EXIT(&nxgep->filter_lock);
43393859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
43404732Sdavemq 	    "Unable to set promisc (%d)", on));
43413859Sml29623 
43423859Sml29623 	return (status);
43433859Sml29623 }
43443859Sml29623 
43453859Sml29623 /*ARGSUSED*/
43463859Sml29623 uint_t
43473859Sml29623 nxge_mif_intr(void *arg1, void *arg2)
43483859Sml29623 {
43493859Sml29623 #ifdef	NXGE_DEBUG
43503859Sml29623 	p_nxge_t		nxgep = (p_nxge_t)arg2;
43513859Sml29623 #endif
43523859Sml29623 #if NXGE_MIF
43533859Sml29623 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
43543859Sml29623 	uint32_t		status;
43553859Sml29623 	npi_handle_t		handle;
43563859Sml29623 	uint8_t			portn;
43573859Sml29623 	p_nxge_stats_t		statsp;
43583859Sml29623 #endif
43593859Sml29623 
43603859Sml29623 #ifdef	NXGE_MIF
43613859Sml29623 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
43623859Sml29623 		nxgep = ldvp->nxgep;
43633859Sml29623 	}
43643859Sml29623 	nxgep = ldvp->nxgep;
43653859Sml29623 #endif
43663859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr"));
43673859Sml29623 
43683859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
43693859Sml29623 	return (DDI_INTR_CLAIMED);
43703859Sml29623 
43713859Sml29623 mif_intr_fail:
43723859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
43733859Sml29623 	return (DDI_INTR_UNCLAIMED);
43743859Sml29623 }
43753859Sml29623 
43763859Sml29623 /*ARGSUSED*/
43773859Sml29623 uint_t
43783859Sml29623 nxge_mac_intr(void *arg1, void *arg2)
43793859Sml29623 {
43803859Sml29623 	p_nxge_t		nxgep = (p_nxge_t)arg2;
43813859Sml29623 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
43823859Sml29623 	p_nxge_ldg_t		ldgp;
43833859Sml29623 	uint32_t		status;
43843859Sml29623 	npi_handle_t		handle;
43853859Sml29623 	uint8_t			portn;
43863859Sml29623 	p_nxge_stats_t		statsp;
43873859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
43883859Sml29623 
43893859Sml29623 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
43903859Sml29623 		nxgep = ldvp->nxgep;
43913859Sml29623 	}
43923859Sml29623 
43933859Sml29623 	ldgp = ldvp->ldgp;
43943859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
43954732Sdavemq 	    "group %d", ldgp->ldg));
43963859Sml29623 
43973859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
43983859Sml29623 	/*
43993859Sml29623 	 * This interrupt handler is for a specific
44003859Sml29623 	 * mac port.
44013859Sml29623 	 */
44023859Sml29623 	statsp = (p_nxge_stats_t)nxgep->statsp;
44033859Sml29623 	portn = nxgep->mac.portnum;
44043859Sml29623 
44053859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
44064732Sdavemq 	    "==> nxge_mac_intr: reading mac stats: port<%d>", portn));
44073859Sml29623 
44083859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
44093859Sml29623 		rs = npi_xmac_tx_get_istatus(handle, portn,
44103859Sml29623 					(xmac_tx_iconfig_t *)&status);
44113859Sml29623 		if (rs != NPI_SUCCESS)
44123859Sml29623 			goto npi_fail;
44133859Sml29623 		if (status & ICFG_XMAC_TX_ALL) {
44143859Sml29623 			if (status & ICFG_XMAC_TX_UNDERRUN) {
44153859Sml29623 				statsp->xmac_stats.tx_underflow_err++;
44163859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
44173859Sml29623 					NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
44183859Sml29623 			}
44193859Sml29623 			if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
44203859Sml29623 				statsp->xmac_stats.tx_maxpktsize_err++;
44215523Syc148097 				/*
44225523Syc148097 				 * Do not send FMA ereport because this
44235523Syc148097 				 * error does not indicate HW failure.
44245523Syc148097 				 */
44253859Sml29623 			}
44263859Sml29623 			if (status & ICFG_XMAC_TX_OVERFLOW) {
44273859Sml29623 				statsp->xmac_stats.tx_overflow_err++;
44283859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
44293859Sml29623 					NXGE_FM_EREPORT_TXMAC_OVERFLOW);
44303859Sml29623 			}
44313859Sml29623 			if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
44323859Sml29623 				statsp->xmac_stats.tx_fifo_xfr_err++;
44333859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
44343859Sml29623 					NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR);
44353859Sml29623 			}
44363859Sml29623 			if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
44373859Sml29623 				statsp->xmac_stats.tx_byte_cnt +=
44383859Sml29623 							XTXMAC_BYTE_CNT_MASK;
44393859Sml29623 			}
44403859Sml29623 			if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
44413859Sml29623 				statsp->xmac_stats.tx_frame_cnt +=
44423859Sml29623 							XTXMAC_FRM_CNT_MASK;
44433859Sml29623 			}
44443859Sml29623 		}
44453859Sml29623 
44463859Sml29623 		rs = npi_xmac_rx_get_istatus(handle, portn,
44473859Sml29623 					(xmac_rx_iconfig_t *)&status);
44483859Sml29623 		if (rs != NPI_SUCCESS)
44493859Sml29623 			goto npi_fail;
44503859Sml29623 		if (status & ICFG_XMAC_RX_ALL) {
44513859Sml29623 			if (status & ICFG_XMAC_RX_OVERFLOW)
44523859Sml29623 				statsp->xmac_stats.rx_overflow_err++;
44533859Sml29623 			if (status & ICFG_XMAC_RX_UNDERFLOW) {
44543859Sml29623 				statsp->xmac_stats.rx_underflow_err++;
44553859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
44563859Sml29623 					NXGE_FM_EREPORT_RXMAC_UNDERFLOW);
44573859Sml29623 			}
44585523Syc148097 			/*
44595523Syc148097 			 * Do not send FMA ereport for the following 3 errors
44605523Syc148097 			 * because they do not indicate HW failures.
44615523Syc148097 			 */
44623859Sml29623 			if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
44633859Sml29623 				statsp->xmac_stats.rx_crc_err_cnt +=
44643859Sml29623 							XRXMAC_CRC_ER_CNT_MASK;
44653859Sml29623 			}
44663859Sml29623 			if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
44673859Sml29623 				statsp->xmac_stats.rx_len_err_cnt +=
44683859Sml29623 							MAC_LEN_ER_CNT_MASK;
44693859Sml29623 			}
44703859Sml29623 			if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
44713859Sml29623 				statsp->xmac_stats.rx_viol_err_cnt +=
44723859Sml29623 							XRXMAC_CD_VIO_CNT_MASK;
44733859Sml29623 			}
44743859Sml29623 			if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
44753859Sml29623 				statsp->xmac_stats.rx_byte_cnt +=
44763859Sml29623 							XRXMAC_BT_CNT_MASK;
44773859Sml29623 			}
44783859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
44793859Sml29623 				statsp->xmac_stats.rx_hist1_cnt +=
44803859Sml29623 							XRXMAC_HIST_CNT1_MASK;
44813859Sml29623 			}
44823859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
44833859Sml29623 				statsp->xmac_stats.rx_hist2_cnt +=
44843859Sml29623 							XRXMAC_HIST_CNT2_MASK;
44853859Sml29623 			}
44863859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
44873859Sml29623 				statsp->xmac_stats.rx_hist3_cnt +=
44883859Sml29623 							XRXMAC_HIST_CNT3_MASK;
44893859Sml29623 			}
44903859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
44913859Sml29623 				statsp->xmac_stats.rx_hist4_cnt +=
44923859Sml29623 							XRXMAC_HIST_CNT4_MASK;
44933859Sml29623 			}
44943859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
44953859Sml29623 				statsp->xmac_stats.rx_hist5_cnt +=
44963859Sml29623 							XRXMAC_HIST_CNT5_MASK;
44973859Sml29623 			}
44983859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
44993859Sml29623 				statsp->xmac_stats.rx_hist6_cnt +=
45003859Sml29623 							XRXMAC_HIST_CNT6_MASK;
45013859Sml29623 			}
45023859Sml29623 			if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
45033859Sml29623 				statsp->xmac_stats.rx_broadcast_cnt +=
45043859Sml29623 							XRXMAC_BC_FRM_CNT_MASK;
45053859Sml29623 			}
45063859Sml29623 			if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
45073859Sml29623 				statsp->xmac_stats.rx_mult_cnt +=
45083859Sml29623 							XRXMAC_MC_FRM_CNT_MASK;
45093859Sml29623 			}
45105523Syc148097 			/*
45115523Syc148097 			 * Do not send FMA ereport for the following 3 errors
45125523Syc148097 			 * because they do not indicate HW failures.
45135523Syc148097 			 */
45143859Sml29623 			if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
45153859Sml29623 				statsp->xmac_stats.rx_frag_cnt +=
45163859Sml29623 							XRXMAC_FRAG_CNT_MASK;
45173859Sml29623 			}
45183859Sml29623 			if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
45193859Sml29623 				statsp->xmac_stats.rx_frame_align_err_cnt +=
45203859Sml29623 							XRXMAC_AL_ER_CNT_MASK;
45213859Sml29623 			}
45223859Sml29623 			if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
45233859Sml29623 				statsp->xmac_stats.rx_linkfault_err_cnt +=
45243859Sml29623 							XMAC_LINK_FLT_CNT_MASK;
45253859Sml29623 			}
45263859Sml29623 			if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
45273859Sml29623 				statsp->xmac_stats.rx_remotefault_err++;
45283859Sml29623 			}
45293859Sml29623 			if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
45303859Sml29623 				statsp->xmac_stats.rx_localfault_err++;
45313859Sml29623 			}
45323859Sml29623 		}
45333859Sml29623 
45343859Sml29623 		rs = npi_xmac_ctl_get_istatus(handle, portn,
45353859Sml29623 						(xmac_ctl_iconfig_t *)&status);
45363859Sml29623 		if (rs != NPI_SUCCESS)
45373859Sml29623 			goto npi_fail;
45383859Sml29623 		if (status & ICFG_XMAC_CTRL_ALL) {
45393859Sml29623 			if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
45403859Sml29623 				statsp->xmac_stats.rx_pause_cnt++;
45413859Sml29623 			if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
45423859Sml29623 				statsp->xmac_stats.tx_pause_state++;
45433859Sml29623 			if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE)
45443859Sml29623 				statsp->xmac_stats.tx_nopause_state++;
45453859Sml29623 		}
45463859Sml29623 	} else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
45473859Sml29623 		rs = npi_bmac_tx_get_istatus(handle, portn,
45483859Sml29623 						(bmac_tx_iconfig_t *)&status);
45493859Sml29623 		if (rs != NPI_SUCCESS)
45503859Sml29623 			goto npi_fail;
45513859Sml29623 		if (status & ICFG_BMAC_TX_ALL) {
45523859Sml29623 			if (status & ICFG_BMAC_TX_UNDERFLOW) {
45533859Sml29623 				statsp->bmac_stats.tx_underrun_err++;
45543859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
45553859Sml29623 					NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
45563859Sml29623 			}
45573859Sml29623 			if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
45583859Sml29623 				statsp->bmac_stats.tx_max_pkt_err++;
45593859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
45603859Sml29623 					NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
45613859Sml29623 			}
45623859Sml29623 			if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
45633859Sml29623 				statsp->bmac_stats.tx_byte_cnt +=
45643859Sml29623 							BTXMAC_BYTE_CNT_MASK;
45653859Sml29623 			}
45663859Sml29623 			if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
45673859Sml29623 				statsp->bmac_stats.tx_frame_cnt +=
45683859Sml29623 							BTXMAC_FRM_CNT_MASK;
45693859Sml29623 			}
45703859Sml29623 		}
45713859Sml29623 
45723859Sml29623 		rs = npi_bmac_rx_get_istatus(handle, portn,
45733859Sml29623 						(bmac_rx_iconfig_t *)&status);
45743859Sml29623 		if (rs != NPI_SUCCESS)
45753859Sml29623 			goto npi_fail;
45763859Sml29623 		if (status & ICFG_BMAC_RX_ALL) {
45773859Sml29623 			if (status & ICFG_BMAC_RX_OVERFLOW) {
45783859Sml29623 				statsp->bmac_stats.rx_overflow_err++;
45793859Sml29623 			}
45803859Sml29623 			if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
45813859Sml29623 				statsp->bmac_stats.rx_frame_cnt +=
45823859Sml29623 							RXMAC_FRM_CNT_MASK;
45833859Sml29623 			}
45843859Sml29623 			if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
45853859Sml29623 				statsp->bmac_stats.rx_crc_err_cnt +=
45863859Sml29623 							BMAC_CRC_ER_CNT_MASK;
45873859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
45883859Sml29623 					NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
45893859Sml29623 			}
45903859Sml29623 			if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
45913859Sml29623 				statsp->bmac_stats.rx_len_err_cnt +=
45923859Sml29623 							MAC_LEN_ER_CNT_MASK;
45933859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
45943859Sml29623 				NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
45953859Sml29623 			}
45963859Sml29623 			if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP)
45973859Sml29623 				statsp->bmac_stats.rx_viol_err_cnt +=
45983859Sml29623 							BMAC_CD_VIO_CNT_MASK;
45993859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
46003859Sml29623 					NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
46013859Sml29623 			}
46023859Sml29623 			if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
46033859Sml29623 				statsp->bmac_stats.rx_byte_cnt +=
46043859Sml29623 							BRXMAC_BYTE_CNT_MASK;
46053859Sml29623 			}
46063859Sml29623 			if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
46073859Sml29623 				statsp->bmac_stats.rx_align_err_cnt +=
46083859Sml29623 							BMAC_AL_ER_CNT_MASK;
46093859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
46103859Sml29623 					NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
46113859Sml29623 			}
46123859Sml29623 
46133859Sml29623 			rs = npi_bmac_ctl_get_istatus(handle, portn,
46143859Sml29623 						(bmac_ctl_iconfig_t *)&status);
46153859Sml29623 			if (rs != NPI_SUCCESS)
46163859Sml29623 				goto npi_fail;
46173859Sml29623 
46183859Sml29623 			if (status & ICFG_BMAC_CTL_ALL) {
46193859Sml29623 				if (status & ICFG_BMAC_CTL_RCVPAUSE)
46203859Sml29623 					statsp->bmac_stats.rx_pause_cnt++;
46213859Sml29623 				if (status & ICFG_BMAC_CTL_INPAUSE_ST)
46223859Sml29623 					statsp->bmac_stats.tx_pause_state++;
46233859Sml29623 				if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST)
46243859Sml29623 					statsp->bmac_stats.tx_nopause_state++;
46253859Sml29623 			}
46263859Sml29623 		}
46273859Sml29623 
46283859Sml29623 	if (ldgp->nldvs == 1) {
46293859Sml29623 		(void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
46303859Sml29623 			B_TRUE, ldgp->ldg_timer);
46313859Sml29623 	}
46323859Sml29623 
46333859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
46343859Sml29623 	return (DDI_INTR_CLAIMED);
46353859Sml29623 
46363859Sml29623 npi_fail:
46373859Sml29623 	NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
46383859Sml29623 	return (DDI_INTR_UNCLAIMED);
46393859Sml29623 }
46403859Sml29623 
46413859Sml29623 nxge_status_t
46423859Sml29623 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up)
46433859Sml29623 {
46443859Sml29623 	uint8_t		phy_port_addr;
46453859Sml29623 	nxge_status_t	status = NXGE_OK;
46463859Sml29623 	boolean_t	rx_sig_ok;
46473859Sml29623 	boolean_t	pcs_blk_lock;
46483859Sml29623 	boolean_t	link_align;
46493859Sml29623 	uint16_t	val1, val2, val3;
46503859Sml29623 #ifdef	NXGE_DEBUG_SYMBOL_ERR
46513859Sml29623 	uint16_t	val_debug;
46523859Sml29623 	uint16_t	val;
46533859Sml29623 #endif
46543859Sml29623 
46553859Sml29623 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
46563859Sml29623 
46573859Sml29623 #ifdef	NXGE_DEBUG_SYMBOL_ERR
46583859Sml29623 	/* Check Device 3 Register Device 3 0xC809 */
46593859Sml29623 	(void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug);
46603859Sml29623 	if ((val_debug & ~0x200) != 0) {
46613859Sml29623 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n",
46623859Sml29623 				nxgep->mac.portnum, val_debug);
46633859Sml29623 		(void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18,
46643859Sml29623 				&val_debug);
46653859Sml29623 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n",
46663859Sml29623 				nxgep->mac.portnum, val_debug);
46673859Sml29623 	}
46683859Sml29623 
46693859Sml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
46703859Sml29623 					XPCS_REG_DESCWERR_COUNTER, &val);
46713859Sml29623 	if (val != 0)
46723859Sml29623 		cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val);
46733859Sml29623 
46743859Sml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
46753859Sml29623 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
46763859Sml29623 	if (val != 0)
46773859Sml29623 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val);
46783859Sml29623 
46793859Sml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
46803859Sml29623 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
46813859Sml29623 	if (val != 0)
46823859Sml29623 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val);
46833859Sml29623 #endif
46843859Sml29623 
46853859Sml29623 	/* Check from BCM8704 if 10G link is up or down */
46863859Sml29623 
46873859Sml29623 	/* Check Device 1 Register 0xA bit0 */
46883859Sml29623 	status = nxge_mdio_read(nxgep, phy_port_addr,
46893859Sml29623 			BCM8704_PMA_PMD_DEV_ADDR,
46903859Sml29623 			BCM8704_PMD_RECEIVE_SIG_DETECT,
46913859Sml29623 			&val1);
46923859Sml29623 	if (status != NXGE_OK)
46933859Sml29623 		goto fail;
46943859Sml29623 	rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE);
46953859Sml29623 
46963859Sml29623 	/* Check Device 3 Register 0x20 bit0 */
46973859Sml29623 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
46983859Sml29623 			BCM8704_PCS_DEV_ADDR,
46993859Sml29623 			BCM8704_10GBASE_R_PCS_STATUS_REG,
47003859Sml29623 			&val2)) != NPI_SUCCESS)
47013859Sml29623 		goto fail;
47023859Sml29623 	pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE);
47033859Sml29623 
47043859Sml29623 	/* Check Device 4 Register 0x18 bit12 */
47053859Sml29623 	status = nxge_mdio_read(nxgep, phy_port_addr,
47063859Sml29623 			BCM8704_PHYXS_ADDR,
47073859Sml29623 			BCM8704_PHYXS_XGXS_LANE_STATUS_REG,
47083859Sml29623 			&val3);
47093859Sml29623 	if (status != NXGE_OK)
47103859Sml29623 		goto fail;
47113859Sml29623 	link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC |
47123859Sml29623 				XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
47133859Sml29623 				XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE;
47143859Sml29623 
47153859Sml29623 #ifdef	NXGE_DEBUG_ALIGN_ERR
47163859Sml29623 	/* Temp workaround for link down issue */
47173859Sml29623 	if (pcs_blk_lock == B_FALSE) {
47183859Sml29623 		if (val2 != 0x4) {
47193859Sml29623 			pcs_blk_lock = B_TRUE;
47203859Sml29623 			cmn_err(CE_NOTE,
47213859Sml29623 				"!LINK DEBUG: port%d PHY Dev3 "
47223859Sml29623 				"Reg 0x20 = 0x%x\n",
47233859Sml29623 				nxgep->mac.portnum, val2);
47243859Sml29623 		}
47253859Sml29623 	}
47263859Sml29623 
47273859Sml29623 	if (link_align == B_FALSE) {
47283859Sml29623 		if (val3 != 0x140f) {
47293859Sml29623 			link_align = B_TRUE;
47303859Sml29623 			cmn_err(CE_NOTE,
47313859Sml29623 				"!LINK DEBUG: port%d PHY Dev4 "
47323859Sml29623 				"Reg 0x18 = 0x%x\n",
47333859Sml29623 				nxgep->mac.portnum, val3);
47343859Sml29623 		}
47353859Sml29623 	}
47363859Sml29623 
47373859Sml29623 	if (rx_sig_ok == B_FALSE) {
47383859Sml29623 		if ((val2 == 0) || (val3 == 0)) {
47393859Sml29623 			rx_sig_ok = B_TRUE;
47403859Sml29623 			cmn_err(CE_NOTE,
47413859Sml29623 				"!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
47423859Sml29623 				nxgep->mac.portnum);
47433859Sml29623 		}
47443859Sml29623 	}
47453859Sml29623 #endif
47463859Sml29623 
47473859Sml29623 	*link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) &&
47483859Sml29623 			(link_align == B_TRUE)) ? B_TRUE : B_FALSE;
47493859Sml29623 
47503859Sml29623 	return (NXGE_OK);
47513859Sml29623 fail:
47523859Sml29623 	return (status);
47533859Sml29623 }
47543859Sml29623 
47553859Sml29623 nxge_status_t
47563859Sml29623 nxge_10g_link_led_on(p_nxge_t nxgep)
47573859Sml29623 {
47583859Sml29623 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
47594732Sdavemq 	    != NPI_SUCCESS)
47603859Sml29623 		return (NXGE_ERROR);
47613859Sml29623 	else
47623859Sml29623 		return (NXGE_OK);
47633859Sml29623 }
47643859Sml29623 
47653859Sml29623 nxge_status_t
47663859Sml29623 nxge_10g_link_led_off(p_nxge_t nxgep)
47673859Sml29623 {
47683859Sml29623 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
47694732Sdavemq 	    != NPI_SUCCESS)
47703859Sml29623 		return (NXGE_ERROR);
47713859Sml29623 	else
47723859Sml29623 		return (NXGE_OK);
47733859Sml29623 }
47744185Sspeer 
47754732Sdavemq /* Check if the given id read using the given MDIO Clause is supported */
47764732Sdavemq 
47774732Sdavemq static boolean_t
47784732Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type)
47794732Sdavemq {
47804732Sdavemq 	int		i;
47814732Sdavemq 	int		cl45_arr_len = NUM_CLAUSE_45_IDS;
47824732Sdavemq 	int		cl22_arr_len = NUM_CLAUSE_22_IDS;
47834732Sdavemq 	boolean_t	found = B_FALSE;
47844732Sdavemq 
47854732Sdavemq 	switch (type) {
47864732Sdavemq 	case CLAUSE_45_TYPE:
47874732Sdavemq 		for (i = 0; i < cl45_arr_len; i++) {
47884782Ssbehera 			if ((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) ==
47894782Ssbehera 			    (id & BCM_PHY_ID_MASK)) {
47904732Sdavemq 				found = B_TRUE;
47914732Sdavemq 				break;
47924732Sdavemq 			}
47934732Sdavemq 		}
47944732Sdavemq 		break;
47954732Sdavemq 	case CLAUSE_22_TYPE:
47964732Sdavemq 		for (i = 0; i < cl22_arr_len; i++) {
47974782Ssbehera 			if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) ==
47984782Ssbehera 			    (id & BCM_PHY_ID_MASK)) {
47994732Sdavemq 				found = B_TRUE;
48004732Sdavemq 				break;
48014732Sdavemq 			}
48024732Sdavemq 		}
48034732Sdavemq 		break;
48044732Sdavemq 	default:
48054732Sdavemq 		break;
48064732Sdavemq 	}
48074732Sdavemq 
48084732Sdavemq 	return (found);
48094732Sdavemq }
48104732Sdavemq 
48114977Sraghus static uint32_t
48124977Sraghus nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port)
48134977Sraghus {
48144977Sraghus 	uint16_t	val1 = 0;
48154977Sraghus 	uint16_t	val2 = 0;
48164977Sraghus 	uint32_t	pma_pmd_dev_id = 0;
48174977Sraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
48184977Sraghus 
48194977Sraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
48204977Sraghus 	    NXGE_DEV_ID_REG_1, &val1);
48214977Sraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
48224977Sraghus 	    NXGE_DEV_ID_REG_2, &val2);
48234977Sraghus 
48244977Sraghus 	pma_pmd_dev_id = val1;
48254977Sraghus 	pma_pmd_dev_id = (pma_pmd_dev_id << 16);
48264977Sraghus 	pma_pmd_dev_id |= val2;
48274977Sraghus 
48284977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD "
48294977Sraghus 	    "devid[0x%llx]", phy_port, pma_pmd_dev_id));
48304977Sraghus 
48314977Sraghus 	return (pma_pmd_dev_id);
48324977Sraghus }
48334977Sraghus 
48344977Sraghus static uint32_t
48354977Sraghus nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port)
48364977Sraghus {
48374977Sraghus 	uint16_t	val1 = 0;
48384977Sraghus 	uint16_t	val2 = 0;
48394977Sraghus 	uint32_t	pcs_dev_id = 0;
48404977Sraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
48414977Sraghus 
48424977Sraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
48434977Sraghus 	    NXGE_DEV_ID_REG_1, &val1);
48444977Sraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
48454977Sraghus 	    NXGE_DEV_ID_REG_2, &val2);
48464977Sraghus 
48474977Sraghus 	pcs_dev_id = val1;
48484977Sraghus 	pcs_dev_id = (pcs_dev_id << 16);
48494977Sraghus 	pcs_dev_id |= val2;
48504977Sraghus 
48514977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
48524977Sraghus 	    "devid[0x%llx]", phy_port, pcs_dev_id));
48534977Sraghus 
48544977Sraghus 	return (pcs_dev_id);
48554977Sraghus }
48564977Sraghus 
48574977Sraghus static uint32_t
48584977Sraghus nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port)
48594977Sraghus {
48604977Sraghus 	uint16_t	val1 = 0;
48614977Sraghus 	uint16_t	val2 = 0;
48624977Sraghus 	uint32_t	phy_id = 0;
48634977Sraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
48644977Sraghus 	npi_status_t	npi_status = NPI_SUCCESS;
48654977Sraghus 
48664977Sraghus 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1,
48674977Sraghus 	    &val1);
48684977Sraghus 	if (npi_status != NPI_SUCCESS) {
48694977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
48704977Sraghus 		    "clause 22 read to reg 2 failed!!!"));
48714977Sraghus 		goto exit;
48724977Sraghus 	}
48734977Sraghus 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2,
48744977Sraghus 	    &val2);
48754977Sraghus 	if (npi_status != 0) {
48764977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
48774977Sraghus 		    "clause 22 read to reg 3 failed!!!"));
48784977Sraghus 		goto exit;
48794977Sraghus 	}
48804977Sraghus 	phy_id = val1;
48814977Sraghus 	phy_id = (phy_id << 16);
48824977Sraghus 	phy_id |= val2;
48834977Sraghus 
48844977Sraghus exit:
48854977Sraghus 
48864977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]",
48874977Sraghus 	    phy_port, phy_id));
48884977Sraghus 
48894977Sraghus 	return (phy_id);
48904977Sraghus }
48914977Sraghus 
48924732Sdavemq /*
48934732Sdavemq  * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO
48944732Sdavemq  * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO
48954732Sdavemq  * read. Then use the values obtained to determine the phy type of each port
48964732Sdavemq  * and the Neptune type.
48974732Sdavemq  */
48984732Sdavemq 
48994732Sdavemq nxge_status_t
49004732Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p)
49014732Sdavemq {
49024732Sdavemq 	int		i, j, k, l;
49034732Sdavemq 	uint32_t	pma_pmd_dev_id = 0;
49044732Sdavemq 	uint32_t	pcs_dev_id = 0;
49054732Sdavemq 	uint32_t	phy_id = 0;
49064782Ssbehera 	uint32_t	port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE];
49074782Ssbehera 	uint32_t	port_pcs_dev_id[NXGE_PORTS_NEPTUNE];
49084782Ssbehera 	uint32_t	port_phy_id[NXGE_PORTS_NEPTUNE];
49094732Sdavemq 	uint8_t		pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS];
49104732Sdavemq 	uint8_t		pcs_dev_fd[NXGE_MAX_PHY_PORTS];
49114732Sdavemq 	uint8_t		phy_fd[NXGE_MAX_PHY_PORTS];
49124732Sdavemq 	uint8_t		port_fd[NXGE_MAX_PHY_PORTS];
49134732Sdavemq 	uint8_t		total_port_fd, total_phy_fd;
49144732Sdavemq 	nxge_status_t	status = NXGE_OK;
49154732Sdavemq 	int		prt_id = -1;
49164732Sdavemq 
49174732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: "));
49184732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
49194732Sdavemq 	    "==> nxge_scan_ports_phy: nxge niu_type[0x%x]",
49204732Sdavemq 	    nxgep->niu_type));
49214732Sdavemq 
49224732Sdavemq 	j = k = l = 0;
49234732Sdavemq 	total_port_fd = total_phy_fd = 0;
49244732Sdavemq 	/*
49254732Sdavemq 	 * Clause 45 and Clause 22 port/phy addresses 0 through 7 are reserved
49264732Sdavemq 	 * for on chip serdes usages.
49274732Sdavemq 	 */
49284732Sdavemq 	for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) {
49294977Sraghus 
49304977Sraghus 		pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i);
49314732Sdavemq 
49324732Sdavemq 		if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) {
49334732Sdavemq 			pma_pmd_dev_fd[i] = 1;
49344732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
49354732Sdavemq 			    "PMA/PMD dev found", i));
49364782Ssbehera 			if (j < NXGE_PORTS_NEPTUNE) {
49374782Ssbehera 				port_pma_pmd_dev_id[j] = pma_pmd_dev_id &
49384782Ssbehera 				    BCM_PHY_ID_MASK;
49394732Sdavemq 				j++;
49404732Sdavemq 			}
49414732Sdavemq 		} else {
49424732Sdavemq 			pma_pmd_dev_fd[i] = 0;
49434732Sdavemq 		}
49444732Sdavemq 
49454977Sraghus 		pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i);
49464732Sdavemq 
49474732Sdavemq 		if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) {
49484732Sdavemq 			pcs_dev_fd[i] = 1;
49494732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
49504732Sdavemq 			    "dev found", i));
49514782Ssbehera 			if (k < NXGE_PORTS_NEPTUNE) {
49524782Ssbehera 				port_pcs_dev_id[k] = pcs_dev_id &
49534782Ssbehera 				    BCM_PHY_ID_MASK;
49544732Sdavemq 				k++;
49554732Sdavemq 			}
49564732Sdavemq 		} else {
49574732Sdavemq 			pcs_dev_fd[i] = 0;
49584732Sdavemq 		}
49594732Sdavemq 
49604732Sdavemq 		if (pcs_dev_fd[i] || pma_pmd_dev_fd[i])
49614732Sdavemq 			port_fd[i] = 1;
49624732Sdavemq 		else
49634732Sdavemq 			port_fd[i] = 0;
49644732Sdavemq 		total_port_fd += port_fd[i];
49654732Sdavemq 
49664977Sraghus 		phy_id = nxge_get_cl22_phy_id(nxgep, i);
49674732Sdavemq 
49684732Sdavemq 		if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
49694732Sdavemq 			phy_fd[i] = 1;
49704732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID"
49714732Sdavemq 			    "found", i));
49724782Ssbehera 			if (l < NXGE_PORTS_NEPTUNE) {
49734782Ssbehera 				port_phy_id[l] = phy_id & BCM_PHY_ID_MASK;
49744732Sdavemq 				l++;
49754732Sdavemq 			}
49764732Sdavemq 		} else {
49774732Sdavemq 			phy_fd[i] = 0;
49784732Sdavemq 		}
49794732Sdavemq 		total_phy_fd += phy_fd[i];
49804732Sdavemq 	}
49814732Sdavemq 
49824732Sdavemq 	switch (total_port_fd) {
49834732Sdavemq 	case 2:
49844732Sdavemq 		switch (total_phy_fd) {
49854732Sdavemq 		case 2:
49864977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
49874977Sraghus 			    "Unsupported neptune type 1"));
49884977Sraghus 			goto error_exit;
49894732Sdavemq 		case 1:
49904732Sdavemq 			/* TODO - 2 10G, 1 1G */
49914732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
49924732Sdavemq 			    "Unsupported neptune type 2 10G, 1 1G"));
49934732Sdavemq 			goto error_exit;
49944732Sdavemq 		case 0:
49954732Sdavemq 			/* 2 10G */
49964782Ssbehera 			if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
49974782Ssbehera 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
49984782Ssbehera 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
49994782Ssbehera 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) {
50004977Sraghus 
50014977Sraghus 				/*
50024977Sraghus 				 * Check the first phy port address against
50034977Sraghus 				 * the known phy start addresses to determine
50044977Sraghus 				 * the platform type.
50054977Sraghus 				 */
50064977Sraghus 				for (i = NXGE_EXT_PHY_PORT_ST;
50074977Sraghus 				    i < NXGE_MAX_PHY_PORTS; i++) {
50084977Sraghus 					if (port_fd[i] == 1)
50094977Sraghus 						break;
50104977Sraghus 				}
50114977Sraghus 				if (i == BCM8704_NEPTUNE_PORT_ADDR_BASE) {
50124977Sraghus 					hw_p->niu_type = NEPTUNE_2_10GF;
50134977Sraghus 					hw_p->platform_type =
50144977Sraghus 					    P_NEPTUNE_ATLAS_2PORT;
50154977Sraghus 				} else {
50164977Sraghus 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
50174977Sraghus 					    "Unsupported neptune type 2 - 1"));
50184977Sraghus 					goto error_exit;
50194977Sraghus 				}
50204732Sdavemq 				hw_p->niu_type = NEPTUNE_2_10GF;
50214732Sdavemq 			} else {
50224732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
50234732Sdavemq 				    "Unsupported neptune type 2"));
50244732Sdavemq 				goto error_exit;
50254732Sdavemq 			}
50264732Sdavemq 			break;
50274732Sdavemq 		case 4:
50284732Sdavemq 			/* Maramba with 2 XAUI */
50294782Ssbehera 			if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
50304782Ssbehera 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
50314782Ssbehera 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
50324782Ssbehera 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) &&
50334782Ssbehera 			    ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
50344782Ssbehera 			    (port_phy_id[1] == PHY_BCM5464R_FAMILY) &&
50354782Ssbehera 			    (port_phy_id[2] == PHY_BCM5464R_FAMILY) &&
50364782Ssbehera 			    (port_phy_id[3] == PHY_BCM5464R_FAMILY))) {
50374732Sdavemq 
50384732Sdavemq 				/*
50394732Sdavemq 				 * Check the first phy port address against
50404732Sdavemq 				 * the known phy start addresses to determine
50414732Sdavemq 				 * the platform type.
50424732Sdavemq 				 */
50434732Sdavemq 				for (i = NXGE_EXT_PHY_PORT_ST;
50444732Sdavemq 				    i < NXGE_MAX_PHY_PORTS; i++) {
50454732Sdavemq 					if (phy_fd[i] == 1)
50464732Sdavemq 						break;
50474732Sdavemq 				}
50484732Sdavemq 				if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) {
50494732Sdavemq 					hw_p->platform_type =
50504732Sdavemq 					    P_NEPTUNE_MARAMBA_P0;
50514732Sdavemq 				} else if (i ==
50524732Sdavemq 				    BCM5464_MARAMBA_P1_PORT_ADDR_BASE) {
50534732Sdavemq 					hw_p->platform_type =
50544732Sdavemq 					    P_NEPTUNE_MARAMBA_P1;
50554732Sdavemq 				} else {
50564732Sdavemq 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
50574732Sdavemq 					    "Unknown port %d...Cannot "
50584732Sdavemq 					    "determine platform type", i));
50594977Sraghus 					goto error_exit;
50604732Sdavemq 				}
50614977Sraghus 				hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
50624977Sraghus 
50634732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
50644732Sdavemq 				    "Maramba with 2 XAUI"));
50654732Sdavemq 			} else {
50664732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
50674732Sdavemq 				    "Unsupported neptune type 3"));
50684732Sdavemq 				goto error_exit;
50694732Sdavemq 			}
50704732Sdavemq 			break;
50714732Sdavemq 		default:
50724732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
50734732Sdavemq 			    "Unsupported neptune type 5"));
50744732Sdavemq 			goto error_exit;
50754732Sdavemq 		}
50764782Ssbehera 		break;
50774732Sdavemq 	case 1:
50784732Sdavemq 		switch (total_phy_fd) {
50794732Sdavemq 		case 3:
50804977Sraghus 			/*
50814977Sraghus 			 * TODO 3 1G, 1 10G mode.
50824977Sraghus 			 * Differentiate between 1_1G_1_10G_2_1G and
50834977Sraghus 			 * 1_10G_3_1G
50844977Sraghus 			 */
50854977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
50864977Sraghus 			    "Unsupported neptune type 7"));
50874977Sraghus 			goto error_exit;
50884732Sdavemq 		case 2:
50894732Sdavemq 			/*
50904732Sdavemq 			 * TODO 2 1G, 1 10G mode.
50914732Sdavemq 			 * Differentiate between 1_1G_1_10G_1_1G and
50924732Sdavemq 			 * 1_10G_2_1G
50934732Sdavemq 			 */
50944732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
50954732Sdavemq 			    "Unsupported neptune type 8"));
50964732Sdavemq 			goto error_exit;
50974732Sdavemq 		case 1:
50984732Sdavemq 			/*
50994732Sdavemq 			 * TODO 1 1G, 1 10G mode.
51004732Sdavemq 			 * Differentiate between 1_1G_1_10G and
51014732Sdavemq 			 * 1_10G_1_1G
51024732Sdavemq 			 */
51034732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51044732Sdavemq 			    "Unsupported neptune type 9"));
51054732Sdavemq 			goto error_exit;
51064732Sdavemq 		case 0:
51074732Sdavemq 			/* TODO 1 10G mode */
51084732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51094732Sdavemq 			    "Unsupported neptune type 10"));
51104732Sdavemq 			goto error_exit;
51114732Sdavemq 		case 4:
51124732Sdavemq 			/* Maramba with 1 XAUI */
51134782Ssbehera 			if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) ||
51144782Ssbehera 			    (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY)) {
51154732Sdavemq 
51164732Sdavemq 				/*
51174732Sdavemq 				 * Check the first phy port address against
51184732Sdavemq 				 * the known phy start addresses to determine
51194732Sdavemq 				 * the platform type.
51204732Sdavemq 				 */
51214732Sdavemq 				for (i = NXGE_EXT_PHY_PORT_ST;
51224732Sdavemq 				    i < NXGE_MAX_PHY_PORTS; i++) {
51234732Sdavemq 					if (phy_fd[i] == 1)
51244732Sdavemq 						break;
51254732Sdavemq 				}
51264732Sdavemq 
51274732Sdavemq 				if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) {
51284732Sdavemq 					hw_p->platform_type =
51294732Sdavemq 					    P_NEPTUNE_MARAMBA_P0;
51304732Sdavemq 				} else if (i ==
51314732Sdavemq 				    BCM5464_MARAMBA_P1_PORT_ADDR_BASE) {
51324732Sdavemq 					hw_p->platform_type =
51334732Sdavemq 					    P_NEPTUNE_MARAMBA_P1;
51344732Sdavemq 				} else {
51354732Sdavemq 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
51364732Sdavemq 					    "Unknown port %d...Cannot "
51374732Sdavemq 					    "determine platform type", i));
51384977Sraghus 					goto error_exit;
51394977Sraghus 				}
51404977Sraghus 
51414977Sraghus 				/* The 10G port is BCM8704 */
51424977Sraghus 				for (i = NXGE_EXT_PHY_PORT_ST;
51434977Sraghus 				    i < NXGE_MAX_PHY_PORTS; i++) {
51444977Sraghus 					if (port_fd[i] == 1) {
51454977Sraghus 						prt_id = i;
51464977Sraghus 						break;
51474977Sraghus 					}
51484977Sraghus 				}
51494977Sraghus 
51504977Sraghus 				prt_id %= BCM8704_MARAMBA_PORT_ADDR_BASE;
51514977Sraghus 				if (prt_id == 0) {
51524977Sraghus 					hw_p->niu_type = NEPTUNE_1_10GF_3_1GC;
51534977Sraghus 				} else if (prt_id == 1) {
51544977Sraghus 					hw_p->niu_type =
51554977Sraghus 					    NEPTUNE_1_1GC_1_10GF_2_1GC;
51564977Sraghus 				} else {
51574977Sraghus 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51584977Sraghus 					    "Unsupported neptune type 11"));
51594977Sraghus 					goto error_exit;
51604732Sdavemq 				}
51614732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51624732Sdavemq 				    "Maramba with 1 XAUI"));
51634732Sdavemq 			} else {
51644732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51654732Sdavemq 				    "Unsupported neptune type 12"));
51664732Sdavemq 				goto error_exit;
51674732Sdavemq 			}
51684732Sdavemq 			break;
51694732Sdavemq 		default:
51704732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51714732Sdavemq 			    "Unsupported neptune type 13"));
51724732Sdavemq 			goto error_exit;
51734732Sdavemq 		}
51744732Sdavemq 		break;
51754732Sdavemq 	case 0:
51764732Sdavemq 		switch (total_phy_fd) {
51774732Sdavemq 		case 4:
51784782Ssbehera 			if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
51794782Ssbehera 			    (port_phy_id[1] == PHY_BCM5464R_FAMILY) &&
51804782Ssbehera 			    (port_phy_id[2] == PHY_BCM5464R_FAMILY) &&
51814782Ssbehera 			    (port_phy_id[3] == PHY_BCM5464R_FAMILY)) {
51824732Sdavemq 
51834732Sdavemq 				/*
51844732Sdavemq 				 * Check the first phy port address against
51854732Sdavemq 				 * the known phy start addresses to determine
51864732Sdavemq 				 * the platform type.
51874732Sdavemq 				 */
51884732Sdavemq 				for (i = NXGE_EXT_PHY_PORT_ST;
51894732Sdavemq 				    i < NXGE_MAX_PHY_PORTS; i++) {
51904732Sdavemq 					if (phy_fd[i] == 1)
51914732Sdavemq 						break;
51924732Sdavemq 				}
51934732Sdavemq 
51944732Sdavemq 				if (i == BCM5464_MARAMBA_P1_PORT_ADDR_BASE) {
51954732Sdavemq 					hw_p->platform_type =
51964732Sdavemq 					    P_NEPTUNE_MARAMBA_P1;
51974977Sraghus 				} else if (i ==
51984977Sraghus 				    BCM5464_NEPTUNE_PORT_ADDR_BASE) {
51994977Sraghus 					hw_p->platform_type =
52004977Sraghus 					    P_NEPTUNE_ATLAS_4PORT;
52014977Sraghus 				} else {
52024977Sraghus 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52034977Sraghus 					    "Unknown port %d...Cannot "
52044977Sraghus 					    "determine platform type", i));
52054977Sraghus 					goto error_exit;
52064732Sdavemq 				}
52074977Sraghus 				hw_p->niu_type = NEPTUNE_4_1GC;
52084732Sdavemq 			} else {
52094732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
52104732Sdavemq 				    "Unsupported neptune type 14"));
52114732Sdavemq 				goto error_exit;
52124732Sdavemq 			}
52134732Sdavemq 			break;
52144732Sdavemq 		case 3:
52154732Sdavemq 			/* TODO 3 1G mode */
52164732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
52174732Sdavemq 			    "Unsupported neptune type 15"));
52184732Sdavemq 			goto error_exit;
52194732Sdavemq 		case 2:
52204732Sdavemq 			/* TODO 2 1G mode */
52214732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
52224732Sdavemq 			    "Unsupported neptune type 16"));
52234732Sdavemq 			goto error_exit;
52244732Sdavemq 		case 1:
52254732Sdavemq 			/* TODO 1 1G mode */
52264732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
52274732Sdavemq 			    "Unsupported neptune type 17"));
52284732Sdavemq 			goto error_exit;
52294732Sdavemq 		default:
52304732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
52314732Sdavemq 			    "Unsupported neptune type 18, total phy fd %d",
52324732Sdavemq 			    total_phy_fd));
52334732Sdavemq 			goto error_exit;
52344732Sdavemq 		}
52354732Sdavemq 		break;
52364732Sdavemq 	default:
52374732Sdavemq 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
52384732Sdavemq 		    "Unsupported neptune type 19"));
52394732Sdavemq 		goto error_exit;
52404732Sdavemq 	}
52414732Sdavemq 
52424732Sdavemq scan_exit:
52434732Sdavemq 
52444732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, "
52454732Sdavemq 	    "niu type [0x%x]\n", hw_p->niu_type));
52464732Sdavemq 	return (status);
52474732Sdavemq 
52484732Sdavemq error_exit:
52494732Sdavemq 	return (NXGE_ERROR);
52504732Sdavemq }
52514732Sdavemq 
52524185Sspeer boolean_t
52534185Sspeer nxge_is_valid_local_mac(ether_addr_st mac_addr)
52544185Sspeer {
52554185Sspeer 	if ((mac_addr.ether_addr_octet[0] & 0x01) ||
52564185Sspeer 	    (ether_cmp(&mac_addr, &etherbroadcastaddr) == 0) ||
52574185Sspeer 	    (ether_cmp(&mac_addr, &etherzeroaddr) == 0))
52584185Sspeer 		return (B_FALSE);
52594185Sspeer 	else
52604185Sspeer 		return (B_TRUE);
52614185Sspeer }
52624732Sdavemq 
52634732Sdavemq static void
52644732Sdavemq nxge_bcm5464_link_led_off(p_nxge_t nxgep) {
52654732Sdavemq 
52664732Sdavemq 	npi_status_t rs = NPI_SUCCESS;
52674732Sdavemq 	uint8_t xcvr_portn;
52684732Sdavemq 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
52694732Sdavemq 
52704732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off"));
52714732Sdavemq 
52724732Sdavemq 	if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) {
52734732Sdavemq 		xcvr_portn = BCM5464_MARAMBA_P1_PORT_ADDR_BASE;
52744732Sdavemq 	} else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) {
52754732Sdavemq 		xcvr_portn = BCM5464_MARAMBA_P0_PORT_ADDR_BASE;
52764732Sdavemq 	}
52774732Sdavemq 	/*
52784732Sdavemq 	 * For Altas 4-1G copper, Xcvr port numbers are
52794732Sdavemq 	 * swapped with ethernet port number. This is
52804732Sdavemq 	 * designed for better signal integrity in routing.
52814732Sdavemq 	 */
52824732Sdavemq 	switch (portn) {
52834732Sdavemq 	case 0:
52844732Sdavemq 		xcvr_portn += 3;
52854732Sdavemq 		break;
52864732Sdavemq 	case 1:
52874732Sdavemq 		xcvr_portn += 2;
52884732Sdavemq 		break;
52894732Sdavemq 	case 2:
52904732Sdavemq 		xcvr_portn += 1;
52914732Sdavemq 		break;
52924732Sdavemq 	case 3:
52934732Sdavemq 	default:
52944732Sdavemq 		break;
52954732Sdavemq 	}
52964732Sdavemq 
52974732Sdavemq 	MUTEX_ENTER(&nxge_mii_lock);
52984732Sdavemq 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
52994732Sdavemq 	    xcvr_portn, BCM5464R_MISC, 0xb4ee);
53004732Sdavemq 	if (rs != NPI_SUCCESS) {
53014732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
53024732Sdavemq 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
53034732Sdavemq 		    "returned error 0x[%x]", rs));
53044732Sdavemq 		MUTEX_EXIT(&nxge_mii_lock);
53054732Sdavemq 		return;
53064732Sdavemq 	}
53074732Sdavemq 
53084732Sdavemq 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
53094732Sdavemq 	    xcvr_portn, BCM5464R_MISC, 0xb8ee);
53104732Sdavemq 	if (rs != NPI_SUCCESS) {
53114732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
53124732Sdavemq 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
53134732Sdavemq 		    "returned error 0x[%x]", rs));
53144732Sdavemq 		MUTEX_EXIT(&nxge_mii_lock);
53154732Sdavemq 		return;
53164732Sdavemq 	}
53174732Sdavemq 
53184732Sdavemq 	MUTEX_EXIT(&nxge_mii_lock);
53194732Sdavemq }
53205196Ssbehera 
53215196Ssbehera static nxge_status_t
53225196Ssbehera nxge_mii_get_link_mode(p_nxge_t nxgep)
53235196Ssbehera {
53245196Ssbehera 	p_nxge_stats_t	statsp;
53255196Ssbehera 	uint8_t		xcvr_portn;
53265196Ssbehera 	p_mii_regs_t	mii_regs;
53275196Ssbehera 	mii_mode_control_stat_t	mode;
53285196Ssbehera 	int		status = NXGE_OK;
53295196Ssbehera 
53305196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode"));
53315196Ssbehera 
53325196Ssbehera 	statsp = nxgep->statsp;
53335196Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
53345196Ssbehera 	mii_regs = NULL;
53355196Ssbehera 	mode.value = 0;
53365203Ssbehera 	mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
53375196Ssbehera #if defined(__i386)
53385196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
53395196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->shadow),
53405196Ssbehera 	    mode.value)) != NXGE_OK) {
53415196Ssbehera 		goto fail;
53425196Ssbehera #else
53435196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
53445196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow),
53455196Ssbehera 	    mode.value)) != NXGE_OK) {
53465196Ssbehera 		goto fail;
53475196Ssbehera #endif
53485196Ssbehera 	}
53495196Ssbehera #if defined(__i386)
53505196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
53515196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->shadow),
53525196Ssbehera 	    &mode.value)) != NXGE_OK) {
53535196Ssbehera 		goto fail;
53545196Ssbehera 	}
53555196Ssbehera #else
53565196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
53575196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow),
53585196Ssbehera 	    &mode.value)) != NXGE_OK) {
53595196Ssbehera 		goto fail;
53605196Ssbehera 	}
53615196Ssbehera #endif
53625196Ssbehera 
53635196Ssbehera 	if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) {
53645196Ssbehera 		nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
53655196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
53665196Ssbehera 		    "nxge_mii_get_link_mode: fiber mode"));
53675196Ssbehera 	}
53685196Ssbehera 
53695196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
53705196Ssbehera 	    "nxge_mii_get_link_mode: "
53715196Ssbehera 	    "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x",
53725203Ssbehera 	    NXGE_MII_MODE_CONTROL_REG, xcvr_portn,
53735196Ssbehera 	    mode.value, nxgep->mac.portmode));
53745196Ssbehera 
53755196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
53765196Ssbehera 	    "<== nxge_mii_get_link_mode"));
53775196Ssbehera 	return (status);
53785196Ssbehera fail:
53795196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
53805196Ssbehera 	    "<== nxge_mii_get_link_mode (failed)"));
53815196Ssbehera 	return (NXGE_ERROR);
53825196Ssbehera }
53835196Ssbehera 
53845196Ssbehera #ifdef NXGE_DEBUG
53855196Ssbehera static void
53865196Ssbehera nxge_mii_dump(p_nxge_t nxgep)
53875196Ssbehera {
53885196Ssbehera 	p_nxge_stats_t	statsp;
53895196Ssbehera 	uint8_t		xcvr_portn;
53905196Ssbehera 	p_mii_regs_t	mii_regs;
53915196Ssbehera 	mii_bmcr_t	bmcr;
53925196Ssbehera 	mii_bmsr_t	bmsr;
53935196Ssbehera 	mii_idr1_t	idr1;
53945196Ssbehera 	mii_idr2_t	idr2;
53955196Ssbehera 	mii_mode_control_stat_t	mode;
53965196Ssbehera 
53975196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump"));
53985196Ssbehera 
53995196Ssbehera 	param_arr = nxgep->param_arr;
54005196Ssbehera 	statsp = nxgep->statsp;
54015196Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
54025196Ssbehera 
54035196Ssbehera 	mii_regs = NULL;
54045196Ssbehera 
54055196Ssbehera #if defined(__i386)
54065196Ssbehera 	(void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
54075196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value);
54085196Ssbehera #else
54095196Ssbehera 	(void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
54105196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value);
54115196Ssbehera #endif
54125196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54135196Ssbehera 	    "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x",
54145196Ssbehera 	    xcvr_portn, bmcr.value));
54155196Ssbehera 
54165196Ssbehera #if defined(__i386)
54175196Ssbehera 	(void) nxge_mii_read(nxgep,
54185196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
54195196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value);
54205196Ssbehera #else
54215196Ssbehera 	(void) nxge_mii_read(nxgep,
54225196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
54235196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value);
54245196Ssbehera #endif
54255196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54265196Ssbehera 	    "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x",
54275196Ssbehera 	    xcvr_portn, bmsr.value));
54285196Ssbehera 
54295196Ssbehera #if defined(__i386)
54305196Ssbehera 	(void) nxge_mii_read(nxgep,
54315196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
54325196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value);
54335196Ssbehera #else
54345196Ssbehera 	(void) nxge_mii_read(nxgep,
54355196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
54365196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value);
54375196Ssbehera #endif
54385196Ssbehera 
54395196Ssbehera 
54405196Ssbehera #if defined(__i386)
54415196Ssbehera 	(void) nxge_mii_read(nxgep,
54425196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
54435196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value);
54445196Ssbehera #else
54455196Ssbehera 	(void) nxge_mii_read(nxgep,
54465196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
54475196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value);
54485196Ssbehera #endif
54495196Ssbehera 
54505196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54515196Ssbehera 	    "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x",
54525196Ssbehera 	    xcvr_portn, idr1.value));
54535196Ssbehera 
54545196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54555196Ssbehera 	    "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x",
54565196Ssbehera 	    xcvr_portn, idr2.value));
54575196Ssbehera 
54585196Ssbehera 	mode.value = 0;
54595203Ssbehera 	mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
54605196Ssbehera 
54615196Ssbehera #if defined(__i386)
54625196Ssbehera 	(void) nxge_mii_write(nxgep, xcvr_portn,
54635196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value);
54645196Ssbehera 
54655196Ssbehera 	(void) nxge_mii_read(nxgep, xcvr_portn,
54665196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value);
54675196Ssbehera #else
54685196Ssbehera 	(void) nxge_mii_write(nxgep, xcvr_portn,
54695196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value);
54705196Ssbehera 
54715196Ssbehera 	(void) nxge_mii_read(nxgep, xcvr_portn,
54725196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value);
54735196Ssbehera #endif
54745196Ssbehera 
54755196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54765196Ssbehera 	    "nxge_mii_dump: mode control xcvr 0x%x value 0x%x",
54775196Ssbehera 	    xcvr_portn, mode.value));
54785196Ssbehera }
54795196Ssbehera #endif
5480