xref: /onnv-gate/usr/src/uts/common/io/nxge/nxge_mac.c (revision 12452:80e5df69a097)
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 /*
2212103SSantwona.Behera@Sun.COM  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
233859Sml29623  */
243859Sml29623 
253859Sml29623 #include <sys/nxge/nxge_impl.h>
263859Sml29623 #include <sys/nxge/nxge_mac.h>
276495Sspeer #include <sys/nxge/nxge_hio.h>
283859Sml29623 
294693Stm144005 #define	LINK_MONITOR_PERIOD	(1000 * 1000)
304693Stm144005 #define	LM_WAIT_MULTIPLIER	8
314693Stm144005 
326075Ssbehera #define	SERDES_RDY_WT_INTERVAL	50
336075Ssbehera #define	MAX_SERDES_RDY_RETRIES	10
346075Ssbehera 
356835Syc148097 #define	TN1010_SPEED_1G		1
366835Syc148097 #define	TN1010_SPEED_10G	0
376835Syc148097 #define	TN1010_AN_IN_PROG	0	/* Auto negotiation in progress */
386835Syc148097 #define	TN1010_AN_COMPLETE	1
396835Syc148097 #define	TN1010_AN_RSVD		2
406835Syc148097 #define	TN1010_AN_FAILED	3
416835Syc148097 
423859Sml29623 extern uint32_t nxge_no_link_notify;
434732Sdavemq extern boolean_t nxge_no_msg;
443859Sml29623 extern uint32_t nxge_lb_dbg;
456028Ssbehera extern uint32_t nxge_jumbo_mtu;
463859Sml29623 
474693Stm144005 typedef enum {
484693Stm144005 	CHECK_LINK_RESCHEDULE,
494693Stm144005 	CHECK_LINK_STOP
504693Stm144005 } check_link_state_t;
514693Stm144005 
524693Stm144005 static check_link_state_t nxge_check_link_stop(nxge_t *);
534693Stm144005 
543859Sml29623 /*
553859Sml29623  * Ethernet broadcast address definition.
563859Sml29623  */
573859Sml29623 static ether_addr_st etherbroadcastaddr =
583859Sml29623 				{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
594732Sdavemq /*
604732Sdavemq  * Ethernet zero address definition.
614732Sdavemq  */
624185Sspeer static ether_addr_st etherzeroaddr =
634185Sspeer 				{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
644732Sdavemq /*
654732Sdavemq  * Supported chip types
664732Sdavemq  */
676604Ssbehera static uint32_t nxge_supported_cl45_ids[] = {
686604Ssbehera 	BCM8704_DEV_ID,
696604Ssbehera 	MARVELL_88X_201X_DEV_ID,
706835Syc148097 	BCM8706_DEV_ID,
716835Syc148097 	TN1010_DEV_ID
726604Ssbehera };
736604Ssbehera 
746909Sml29623 static uint32_t nxge_supported_cl22_ids[] = {
756909Sml29623     BCM5464R_PHY_ID,
766909Sml29623     BCM5482_PHY_ID
776909Sml29623 };
784732Sdavemq 
794732Sdavemq #define	NUM_CLAUSE_45_IDS	(sizeof (nxge_supported_cl45_ids) /	\
804732Sdavemq 				sizeof (uint32_t))
814732Sdavemq #define	NUM_CLAUSE_22_IDS	(sizeof (nxge_supported_cl22_ids) /	\
824732Sdavemq 				sizeof (uint32_t))
834732Sdavemq /*
844732Sdavemq  * static functions
854732Sdavemq  */
864977Sraghus static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int);
874977Sraghus static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int);
884977Sraghus static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int);
894732Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t);
9012103SSantwona.Behera@Sun.COM static boolean_t nxge_hswap_phy_present(p_nxge_t, uint8_t);
915572Ssbehera static boolean_t nxge_is_phy_present(p_nxge_t, int, uint32_t, uint32_t);
924732Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t);
9311304SJanie.Lu@Sun.COM static nxge_status_t nxge_n2_kt_serdes_init(p_nxge_t);
944732Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t);
954732Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t);
964732Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t);
974732Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t);
984732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t);
994732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t);
1004732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t);
1014732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t);
1024732Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t);
1034732Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t);
1044732Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t);
1055572Ssbehera static nxge_status_t nxge_BCM8704_xcvr_init(p_nxge_t);
1065572Ssbehera static nxge_status_t nxge_BCM8706_xcvr_init(p_nxge_t);
1074732Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t);
1084732Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t);
1096835Syc148097 static nxge_status_t nxge_check_mrvl88x2011_link(p_nxge_t, boolean_t *);
1106604Ssbehera static nxge_status_t nxge_mrvl88x2011_xcvr_init(p_nxge_t);
11112103SSantwona.Behera@Sun.COM static nxge_status_t nxge_check_nlp2020_link(p_nxge_t, boolean_t *);
11212103SSantwona.Behera@Sun.COM static nxge_status_t nxge_nlp2020_xcvr_init(p_nxge_t);
11312103SSantwona.Behera@Sun.COM static int nxge_nlp2020_i2c_read(p_nxge_t, uint8_t, uint16_t, uint16_t,
11412103SSantwona.Behera@Sun.COM 	    uint8_t *);
11512103SSantwona.Behera@Sun.COM static boolean_t nxge_is_nlp2020_phy(p_nxge_t);
11612103SSantwona.Behera@Sun.COM static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t);
11712103SSantwona.Behera@Sun.COM static nxge_status_t nxge_set_nlp2020_param(p_nxge_t);
1186835Syc148097 static nxge_status_t nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
1196835Syc148097 	uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui);
1206835Syc148097 static nxge_status_t nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed);
1216835Syc148097 static nxge_status_t nxge_set_tn1010_param(p_nxge_t nxgep);
1226835Syc148097 static nxge_status_t nxge_tn1010_check(p_nxge_t nxgep,
1236835Syc148097 	nxge_link_state_t *link_up);
1246835Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep);
1256835Syc148097 static nxge_status_t nxge_tn1010_xcvr_init(p_nxge_t nxgep);
1266835Syc148097 
1276835Syc148097 nxge_status_t nxge_mac_init(p_nxge_t);
1286835Syc148097 static nxge_status_t nxge_mii_get_link_mode(p_nxge_t);
1296835Syc148097 
1306835Syc148097 #ifdef NXGE_DEBUG
1316835Syc148097 static void nxge_mii_dump(p_nxge_t);
1326835Syc148097 static nxge_status_t nxge_tn1010_reset(p_nxge_t nxgep);
1336835Syc148097 static void nxge_dump_tn1010_status_regs(p_nxge_t nxgep);
1346835Syc148097 #endif
1354732Sdavemq 
1364732Sdavemq /*
1374732Sdavemq  * xcvr tables for supported transceivers
1384732Sdavemq  */
1394732Sdavemq 
1406835Syc148097 /*
1416835Syc148097  * nxge_n2_10G_table is for 10G fiber or serdes on N2-NIU systems.
1426835Syc148097  * The Teranetics TN1010 based copper XAUI card can also be used
1436835Syc148097  * on N2-NIU systems in 10G mode, but it uses its own table
1446835Syc148097  * nxge_n2_10G_tn1010_table below.
1456835Syc148097  */
1464977Sraghus static nxge_xcvr_table_t nxge_n2_10G_table = {
1474732Sdavemq 	nxge_n2_serdes_init,
1484732Sdavemq 	nxge_10G_xcvr_init,
1494732Sdavemq 	nxge_10G_link_intr_stop,
1504732Sdavemq 	nxge_10G_link_intr_start,
1514732Sdavemq 	nxge_check_10g_link,
1525572Ssbehera 	PCS_XCVR
1534732Sdavemq };
1544732Sdavemq 
1556835Syc148097 /*
1566835Syc148097  * For the Teranetics TN1010 based copper XAUI card
1576835Syc148097  */
1586835Syc148097 static nxge_xcvr_table_t nxge_n2_10G_tn1010_table = {
1596835Syc148097 	nxge_n2_serdes_init,		/* Handle both 1G and 10G */
1606835Syc148097 	nxge_tn1010_xcvr_init,		/* Handle both 1G and 10G */
1616835Syc148097 	nxge_10G_link_intr_stop,
1626835Syc148097 	nxge_10G_link_intr_start,
1636835Syc148097 	nxge_check_tn1010_link,		/* Will figure out speed */
1646835Syc148097 	XPCS_XCVR
1656835Syc148097 };
1666835Syc148097 
1674977Sraghus static nxge_xcvr_table_t nxge_n2_1G_table = {
1684977Sraghus 	nxge_n2_serdes_init,
1694977Sraghus 	nxge_1G_xcvr_init,
1704977Sraghus 	nxge_1G_fiber_link_intr_stop,
1714977Sraghus 	nxge_1G_fiber_link_intr_start,
1724977Sraghus 	nxge_check_mii_link,
1735572Ssbehera 	PCS_XCVR
1744977Sraghus };
1754977Sraghus 
1766835Syc148097 static nxge_xcvr_table_t nxge_n2_1G_tn1010_table = {
1776835Syc148097 	nxge_n2_serdes_init,
1786835Syc148097 	nxge_tn1010_xcvr_init,
1796835Syc148097 	nxge_1G_fiber_link_intr_stop,	/* TN1010 is a Cu PHY, but it uses */
1806835Syc148097 	nxge_1G_fiber_link_intr_start,	/* PCS for 1G, so call fiber func */
1816835Syc148097 	nxge_check_tn1010_link,
1826835Syc148097 	PCS_XCVR
1836835Syc148097 };
1846835Syc148097 
1856835Syc148097 static nxge_xcvr_table_t nxge_10G_tn1010_table = {
1866835Syc148097 	nxge_neptune_10G_serdes_init,
1876835Syc148097 	nxge_tn1010_xcvr_init,
1886835Syc148097 	nxge_10G_link_intr_stop,
1896835Syc148097 	nxge_10G_link_intr_start,
1906835Syc148097 	nxge_check_tn1010_link,
1916835Syc148097 	XPCS_XCVR
1926835Syc148097 };
1936835Syc148097 
1946835Syc148097 static nxge_xcvr_table_t nxge_1G_tn1010_table = {
1956835Syc148097 	nxge_1G_serdes_init,
1966835Syc148097 	nxge_tn1010_xcvr_init,
1976835Syc148097 	nxge_1G_fiber_link_intr_stop,
1986835Syc148097 	nxge_1G_fiber_link_intr_start,
1996835Syc148097 	nxge_check_tn1010_link,
2006835Syc148097 	PCS_XCVR
2016835Syc148097 };
2026835Syc148097 
2034732Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = {
2044732Sdavemq 	nxge_neptune_10G_serdes_init,
2054732Sdavemq 	nxge_10G_xcvr_init,
2064732Sdavemq 	nxge_10G_link_intr_stop,
2074732Sdavemq 	nxge_10G_link_intr_start,
2084732Sdavemq 	nxge_check_10g_link,
2095572Ssbehera 	PCS_XCVR
2104732Sdavemq };
2114732Sdavemq 
2124732Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = {
2134732Sdavemq 	NULL,
2144732Sdavemq 	nxge_1G_xcvr_init,
2154732Sdavemq 	nxge_1G_copper_link_intr_stop,
2164732Sdavemq 	nxge_1G_copper_link_intr_start,
2174732Sdavemq 	nxge_check_mii_link,
2185572Ssbehera 	INT_MII_XCVR
2194732Sdavemq };
2204732Sdavemq 
2216835Syc148097 /* This table is for Neptune portmode == PORT_1G_SERDES cases */
2224732Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = {
2234732Sdavemq 	nxge_1G_serdes_init,
2244732Sdavemq 	nxge_1G_xcvr_init,
2254732Sdavemq 	nxge_1G_fiber_link_intr_stop,
2264732Sdavemq 	nxge_1G_fiber_link_intr_start,
2274732Sdavemq 	nxge_check_mii_link,
2285572Ssbehera 	PCS_XCVR
2294732Sdavemq };
2304732Sdavemq 
2314732Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = {
2324732Sdavemq 	nxge_neptune_10G_serdes_init,
2334732Sdavemq 	NULL,
2344732Sdavemq 	NULL,
2354732Sdavemq 	NULL,
2364977Sraghus 	NULL,
2375572Ssbehera 	PCS_XCVR
2384732Sdavemq };
2393859Sml29623 
2406835Syc148097 /*
2416835Syc148097  * NXGE_PORT_TN1010 is defined as,
2426835Syc148097  *      NXGE_PORT_SPD_NONE | (NXGE_PHY_TN1010 << NXGE_PHY_SHIFT)
2436835Syc148097  *	= 0 | 5 << 16 = 0x50000
2446835Syc148097  *
2456835Syc148097  * So NEPTUNE_2_TN1010 =
2466835Syc148097  *      (NXGE_PORT_TN1010 |
2476835Syc148097  *      (NXGE_PORT_TN1010 << 4) |
2486835Syc148097  *      (NXGE_PORT_NONE << 8) |
2496835Syc148097  *      (NXGE_PORT_NONE << 12)),
2506835Syc148097  *      = 0x50000 | (0x50000 << 4)
2516835Syc148097  *	= 0x550000
2526835Syc148097  *
2536835Syc148097  * This function partitions nxgep->nxge_hw_p->niu_type (which may have
2546835Syc148097  * value NEPTUNE_2_TN1010) and checks if a port has type = NXGE_PORT_TN1010
2556835Syc148097  * = 0x50000
2566835Syc148097  */
nxge_is_tn1010_phy(p_nxge_t nxgep)2576835Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep)
2586835Syc148097 {
2596835Syc148097 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2606835Syc148097 
2616835Syc148097 	if (((nxgep->nxge_hw_p->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn))
2626835Syc148097 	    & NXGE_PHY_MASK) == NXGE_PORT_TN1010) {
2636835Syc148097 		return (B_TRUE);
2646835Syc148097 	} else {
2656835Syc148097 		return (B_FALSE);
2666835Syc148097 	}
2676835Syc148097 }
2686835Syc148097 
2696835Syc148097 
2706835Syc148097 /*
2716835Syc148097  * Figure out nxgep->mac.portmode from nxge.conf, OBP's device properties,
2726835Syc148097  * serial EEPROM or VPD if possible.  Note that not all systems could get
2736835Syc148097  * the portmode information by calling this function.  For example, the
2746835Syc148097  * Maramba system figures out the portmode information by calling function
2756835Syc148097  * nxge_setup_xcvr_table.
2766835Syc148097  */
2774977Sraghus nxge_status_t
nxge_get_xcvr_type(p_nxge_t nxgep)2784977Sraghus nxge_get_xcvr_type(p_nxge_t nxgep)
2794977Sraghus {
2804977Sraghus 	nxge_status_t status = NXGE_OK;
2814977Sraghus 	char *phy_type;
2824977Sraghus 	char *prop_val;
2836835Syc148097 	uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2849599Stc99174@train 	uint32_t	val;
2859599Stc99174@train 	npi_status_t	rs;
2869599Stc99174@train 
2879599Stc99174@train 	/* For Opus NEM, skip xcvr checking if 10G Serdes link is up */
2889599Stc99174@train 	if (nxgep->mac.portmode == PORT_10G_SERDES &&
2899599Stc99174@train 	    nxgep->statsp->mac_stats.link_up) {
2909599Stc99174@train 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
2919599Stc99174@train 		return (status);
2929599Stc99174@train 	}
2934977Sraghus 
2944977Sraghus 	nxgep->mac.portmode = 0;
2955572Ssbehera 	nxgep->xcvr_addr = 0;
2965572Ssbehera 
2975572Ssbehera 	/*
2985572Ssbehera 	 * First check for hot swappable phy property.
2995572Ssbehera 	 */
3005572Ssbehera 	if (nxgep->hot_swappable_phy == B_TRUE) {
3015572Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3025572Ssbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3035572Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable"));
3045572Ssbehera 	} else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip,
3055572Ssbehera 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3065572Ssbehera 	    "hot-swappable-phy") == 1) {
3075572Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3085572Ssbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3095572Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, ".conf: Hot Swappable"));
3105572Ssbehera 	} else if (nxgep->niu_type == N2_NIU &&
3115572Ssbehera 	    ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0,
3125572Ssbehera 	    "hot-swappable-phy") == 1) {
3135572Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3145572Ssbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3155572Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable"));
3165572Ssbehera 	}
3175572Ssbehera 
3185572Ssbehera 	/*
3195572Ssbehera 	 * MDIO polling support for Monza RTM card, Goa NEM card
3205572Ssbehera 	 */
3215572Ssbehera 	if (nxgep->mac.portmode == PORT_HSP_MODE) {
3225572Ssbehera 		nxgep->hot_swappable_phy = B_TRUE;
32310577SMichael.Speer@Sun.COM 		if (portn > 1) {
32410577SMichael.Speer@Sun.COM 			return (NXGE_ERROR);
32510577SMichael.Speer@Sun.COM 		}
32610577SMichael.Speer@Sun.COM 
32712103SSantwona.Behera@Sun.COM 		if (nxge_hswap_phy_present(nxgep, portn))
3285572Ssbehera 			goto found_phy;
3295572Ssbehera 
3305572Ssbehera 		nxgep->phy_absent = B_TRUE;
3319599Stc99174@train 
3329599Stc99174@train 		/* Check Serdes link to detect Opus NEM */
3339599Stc99174@train 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
3349599Stc99174@train 		    XPCS_REG_STATUS, &val);
3359599Stc99174@train 
3369599Stc99174@train 		if (rs == 0 && val & XPCS_STATUS_LANE_ALIGN) {
3379599Stc99174@train 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3389599Stc99174@train 			nxgep->mac.portmode = PORT_10G_SERDES;
3399599Stc99174@train 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3409599Stc99174@train 			    "HSP 10G Serdes FOUND!!"));
3419599Stc99174@train 		}
3425572Ssbehera 		goto check_phy_done;
3435572Ssbehera found_phy:
3445572Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3455572Ssbehera 		nxgep->mac.portmode = PORT_10G_FIBER;
3465572Ssbehera 		nxgep->phy_absent = B_FALSE;
3475572Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr "
3485572Ssbehera 		    "found for hot swappable phy"));
3495572Ssbehera check_phy_done:
3505572Ssbehera 		return (status);
3515572Ssbehera 	}
3525572Ssbehera 
3536835Syc148097 	/* Get phy-type property (May have been set by nxge.conf) */
3544977Sraghus 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip,
3554977Sraghus 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3564977Sraghus 	    "phy-type", &prop_val)) == DDI_PROP_SUCCESS) {
3574977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3584977Sraghus 		    "found  conf file: phy-type %s", prop_val));
3594977Sraghus 		if (strcmp("xgsd", prop_val) == 0) {
3604977Sraghus 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3614977Sraghus 			nxgep->mac.portmode = PORT_10G_SERDES;
3624977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3634977Sraghus 			    "found: 10G Serdes"));
3644977Sraghus 		} else if (strcmp("gsd", prop_val) == 0) {
3654977Sraghus 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3664977Sraghus 			nxgep->mac.portmode = PORT_1G_SERDES;
3674977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes"));
3684977Sraghus 		} else if (strcmp("mif", prop_val) == 0) {
3694977Sraghus 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
3704977Sraghus 			nxgep->mac.portmode = PORT_1G_COPPER;
3714977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
3724977Sraghus 		} else if (strcmp("pcs", prop_val) == 0) {
3734977Sraghus 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3744977Sraghus 			nxgep->mac.portmode = PORT_1G_FIBER;
3754977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr"));
3766075Ssbehera 		} else if (strcmp("xgf", prop_val) == 0) {
3776835Syc148097 			/*
3786835Syc148097 			 * Before OBP supports new phy-type property
3796835Syc148097 			 * value "xgc", the 10G copper XAUI may carry
3806835Syc148097 			 * "xgf" instead of "xgc". If the OBP is
3816835Syc148097 			 * upgraded to a newer version which supports
3826835Syc148097 			 * "xgc", then the TN1010 related code in this
3836835Syc148097 			 * "xgf" case will not be used anymore.
3846835Syc148097 			 */
3856835Syc148097 			if (nxge_is_tn1010_phy(nxgep)) {
3866835Syc148097 				if ((status = nxge_set_tn1010_param(nxgep))
3876835Syc148097 				    != NXGE_OK) {
3886835Syc148097 					return (status);
3896835Syc148097 				}
3906835Syc148097 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
3916835Syc148097 			} else {  /* For Fiber XAUI */
3926835Syc148097 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3936835Syc148097 				nxgep->mac.portmode = PORT_10G_FIBER;
3946835Syc148097 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3956835Syc148097 				    "10G Fiber Xcvr"));
3966835Syc148097 			}
3976835Syc148097 		} else if (strcmp("xgc", prop_val) == 0) {
3986835Syc148097 			if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK)
3996835Syc148097 				return (status);
4006835Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
4014977Sraghus 		}
4024977Sraghus 
4034977Sraghus 		(void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip,
4044977Sraghus 		    "phy-type", prop_val);
4054977Sraghus 		ddi_prop_free(prop_val);
4064977Sraghus 
4074977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
4084977Sraghus 		    "Got phy type [0x%x] from conf file",
4094977Sraghus 		    nxgep->mac.portmode));
4104977Sraghus 
4114977Sraghus 		return (NXGE_OK);
4124977Sraghus 	}
4135572Ssbehera 
4145572Ssbehera 	/* Get phy-type property from OBP */
4154977Sraghus 	if (nxgep->niu_type == N2_NIU) {
4164977Sraghus 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
4174977Sraghus 		    "phy-type", &prop_val) == DDI_PROP_SUCCESS) {
4184977Sraghus 			if (strcmp("xgf", prop_val) == 0) {
4196835Syc148097 				/*
4206835Syc148097 				 * Before OBP supports new phy-type property
4216835Syc148097 				 * value "xgc", the 10G copper XAUI may carry
4226835Syc148097 				 * "xgf" instead of "xgc". If the OBP is
4236835Syc148097 				 * upgraded to a newer version which supports
4246835Syc148097 				 * "xgc", then the TN1010 related code in this
4256835Syc148097 				 * "xgf" case will not be used anymore.
4266835Syc148097 				 */
4276835Syc148097 				if (nxge_is_tn1010_phy(nxgep)) {
4286835Syc148097 					if ((status =
4296835Syc148097 					    nxge_set_tn1010_param(nxgep))
4306835Syc148097 					    != NXGE_OK) {
4316835Syc148097 						return (status);
4326835Syc148097 					}
4336835Syc148097 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4346835Syc148097 					    "TN1010 Xcvr"));
43512103SSantwona.Behera@Sun.COM 				} else if (nxge_is_nlp2020_phy(nxgep)) {
43612103SSantwona.Behera@Sun.COM 					if ((status =
43712103SSantwona.Behera@Sun.COM 					    nxge_set_nlp2020_param(nxgep))
43812103SSantwona.Behera@Sun.COM 					    != NXGE_OK) {
43912103SSantwona.Behera@Sun.COM 						return (status);
44012103SSantwona.Behera@Sun.COM 					}
44112103SSantwona.Behera@Sun.COM 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
44212103SSantwona.Behera@Sun.COM 					    "NLP2020 Xcvr"));
44312103SSantwona.Behera@Sun.COM 				} else { /* For Fiber XAUI */
4446835Syc148097 					nxgep->statsp->mac_stats.xcvr_inuse
4456835Syc148097 					    = XPCS_XCVR;
4466835Syc148097 					nxgep->mac.portmode = PORT_10G_FIBER;
4476835Syc148097 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4486835Syc148097 					    "10G Fiber Xcvr"));
4496835Syc148097 				}
4504977Sraghus 			} else if (strcmp("mif", prop_val) == 0) {
4514977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse =
4524977Sraghus 				    INT_MII_XCVR;
4534977Sraghus 				nxgep->mac.portmode = PORT_1G_COPPER;
4544977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4554977Sraghus 				    "1G Copper Xcvr"));
4564977Sraghus 			} else if (strcmp("pcs", prop_val) == 0) {
4574977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
4584977Sraghus 				nxgep->mac.portmode = PORT_1G_FIBER;
4594977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4604977Sraghus 				    "1G Fiber Xcvr"));
4614977Sraghus 			} else if (strcmp("xgc", prop_val) == 0) {
4626835Syc148097 				status = nxge_set_tn1010_param(nxgep);
4636835Syc148097 				if (status != NXGE_OK)
4646835Syc148097 					return (status);
4656835Syc148097 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
4664977Sraghus 			} else if (strcmp("xgsd", prop_val) == 0) {
4674977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
4684977Sraghus 				nxgep->mac.portmode = PORT_10G_SERDES;
4694977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4704977Sraghus 				    "OBP: 10G Serdes"));
4714977Sraghus 			} else if (strcmp("gsd", prop_val) == 0) {
4724977Sraghus 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
4734977Sraghus 				nxgep->mac.portmode = PORT_1G_SERDES;
4744977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4754977Sraghus 				    "OBP: 1G Serdes"));
4764977Sraghus 			} else {
4774977Sraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4784977Sraghus 				    "Unknown phy-type: %s", prop_val));
4794977Sraghus 				ddi_prop_free(prop_val);
4804977Sraghus 				return (NXGE_ERROR);
4814977Sraghus 			}
4824977Sraghus 			status = NXGE_OK;
4834977Sraghus 			(void) ddi_prop_update_string(DDI_DEV_T_NONE,
4844977Sraghus 			    nxgep->dip, "phy-type", prop_val);
4854977Sraghus 			ddi_prop_free(prop_val);
4864977Sraghus 
4874977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
4884977Sraghus 			    "Got phy type [0x%x] from OBP",
4894977Sraghus 			    nxgep->mac.portmode));
4904977Sraghus 
4914977Sraghus 			return (status);
4924977Sraghus 		} else {
4934977Sraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4944977Sraghus 			    "Exiting...phy-type property not found"));
4954977Sraghus 			return (NXGE_ERROR);
4964977Sraghus 		}
4974977Sraghus 	}
4984977Sraghus 
4994977Sraghus 
5004977Sraghus 	if (!nxgep->vpd_info.present) {
5014977Sraghus 		return (NXGE_OK);
5024977Sraghus 	}
5034977Sraghus 
5044977Sraghus 	if (!nxgep->vpd_info.ver_valid) {
5054977Sraghus 		goto read_seeprom;
5064977Sraghus 	}
5074977Sraghus 
5084977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5094977Sraghus 	    "Reading phy type from expansion ROM"));
5104977Sraghus 	/*
5114977Sraghus 	 * Try to read the phy type from the vpd data read off the
5124977Sraghus 	 * expansion ROM.
5134977Sraghus 	 */
5144977Sraghus 	phy_type = nxgep->vpd_info.phy_type;
5154977Sraghus 
5165196Ssbehera 	if (strncmp(phy_type, "mif", 3) == 0) {
5174977Sraghus 		nxgep->mac.portmode = PORT_1G_COPPER;
5184977Sraghus 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
5195196Ssbehera 	} else if (strncmp(phy_type, "xgf", 3) == 0) {
5204977Sraghus 		nxgep->mac.portmode = PORT_10G_FIBER;
5214977Sraghus 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
5225196Ssbehera 	} else if (strncmp(phy_type, "pcs", 3) == 0) {
5234977Sraghus 		nxgep->mac.portmode = PORT_1G_FIBER;
5244977Sraghus 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
5255196Ssbehera 	} else if (strncmp(phy_type, "xgc", 3) == 0) {
5266835Syc148097 		status = nxge_set_tn1010_param(nxgep);
5276835Syc148097 		if (status != NXGE_OK) {
5286835Syc148097 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5296835Syc148097 			    "nxge_get_xcvr_type: Failed to set TN1010 param"));
5306835Syc148097 			goto read_seeprom;
5316835Syc148097 		}
5325196Ssbehera 	} else if (strncmp(phy_type, "xgsd", 4) == 0) {
5335196Ssbehera 		nxgep->mac.portmode = PORT_10G_SERDES;
5345196Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
5355196Ssbehera 	} else if (strncmp(phy_type, "gsd", 3) == 0) {
5365196Ssbehera 		nxgep->mac.portmode = PORT_1G_SERDES;
5375196Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
5384977Sraghus 	} else {
5395196Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5404977Sraghus 		    "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
5414977Sraghus 		    phy_type[0], phy_type[1], phy_type[2]));
5424977Sraghus 		goto read_seeprom;
5434977Sraghus 	}
5444977Sraghus 
5454977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
5464977Sraghus 	    "Got phy type [0x%x] from VPD", nxgep->mac.portmode));
5474977Sraghus 
5484977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
5494977Sraghus 	return (status);
5504977Sraghus 
5514977Sraghus read_seeprom:
5524977Sraghus 	/*
5534977Sraghus 	 * read the phy type from the SEEPROM - NCR registers
5544977Sraghus 	 */
5554977Sraghus 	status = nxge_espc_phy_type_get(nxgep);
5564977Sraghus 	if (status != NXGE_OK) {
5574977Sraghus 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5584977Sraghus 		    "Failed to get phy type"));
5594977Sraghus 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
5604977Sraghus 		    "[%s] invalid...please update", nxgep->vpd_info.ver));
5614977Sraghus 	}
5624977Sraghus 
5634977Sraghus 	return (status);
5644977Sraghus 
5654977Sraghus }
5664977Sraghus 
5674732Sdavemq /* Set up the PHY specific values. */
5684732Sdavemq 
5694732Sdavemq nxge_status_t
nxge_setup_xcvr_table(p_nxge_t nxgep)5704732Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep)
5714732Sdavemq {
5724732Sdavemq 	nxge_status_t	status = NXGE_OK;
5734732Sdavemq 	uint32_t	port_type;
5744732Sdavemq 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
5754977Sraghus 	uint32_t	pcs_id = 0;
5764977Sraghus 	uint32_t	pma_pmd_id = 0;
5774977Sraghus 	uint32_t	phy_id = 0;
5785572Ssbehera 	uint16_t	chip_id = 0;
5794732Sdavemq 
5804732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>",
5814732Sdavemq 	    portn));
5824732Sdavemq 
5834977Sraghus 	switch (nxgep->niu_type) {
5844977Sraghus 	case N2_NIU:
5854977Sraghus 		switch (nxgep->mac.portmode) {
5864977Sraghus 		case PORT_1G_FIBER:
5874977Sraghus 		case PORT_1G_SERDES:
5884977Sraghus 			nxgep->xcvr = nxge_n2_1G_table;
5895572Ssbehera 			nxgep->xcvr_addr = portn;
5904977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr",
5914977Sraghus 			    (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" :
5924977Sraghus 			    "Serdes"));
5934977Sraghus 			break;
5944977Sraghus 		case PORT_10G_FIBER:
59512103SSantwona.Behera@Sun.COM 		case PORT_10G_COPPER:
5964977Sraghus 		case PORT_10G_SERDES:
5974977Sraghus 			nxgep->xcvr = nxge_n2_10G_table;
5985572Ssbehera 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
5995572Ssbehera 				nxgep->xcvr_addr =
6005572Ssbehera 				    nxgep->nxge_hw_p->xcvr_addr[portn];
6015572Ssbehera 			}
6024977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr",
6034977Sraghus 			    (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" :
60412103SSantwona.Behera@Sun.COM 			    ((nxgep->mac.portmode == PORT_10G_COPPER) ?
60512103SSantwona.Behera@Sun.COM 			    "Copper" : "Serdes")));
6064977Sraghus 			break;
6076835Syc148097 		case PORT_1G_TN1010:
6086835Syc148097 			nxgep->xcvr = nxge_n2_1G_tn1010_table;
6096835Syc148097 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
6106835Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6116835Syc148097 			    "TN1010 Copper Xcvr in 1G"));
6126835Syc148097 			break;
6136835Syc148097 		case PORT_10G_TN1010:
6146835Syc148097 			nxgep->xcvr = nxge_n2_10G_tn1010_table;
6156835Syc148097 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
6166835Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6176835Syc148097 			    "TN1010 Copper Xcvr in 10G"));
6186835Syc148097 			break;
6195572Ssbehera 		case PORT_HSP_MODE:
6205572Ssbehera 			nxgep->xcvr = nxge_n2_10G_table;
6215572Ssbehera 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
6225572Ssbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot "
6235572Ssbehera 			    "Swappable Xcvr (not present)"));
6245572Ssbehera 			break;
6254977Sraghus 		default:
6264977Sraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6274977Sraghus 			    "<== nxge_setup_xcvr_table: "
6284977Sraghus 			    "Unable to determine NIU portmode"));
6294977Sraghus 			return (NXGE_ERROR);
6304977Sraghus 		}
6314977Sraghus 		break;
6324977Sraghus 	default:
6334977Sraghus 		if (nxgep->mac.portmode == 0) {
6344977Sraghus 			/*
6354977Sraghus 			 * Would be the case for platforms like Maramba
6364977Sraghus 			 * in which the phy type could not be got from conf
6374977Sraghus 			 * file, OBP, VPD or Serial PROM.
6384977Sraghus 			 */
6394977Sraghus 			if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6404977Sraghus 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6414977Sraghus 				    "<== nxge_setup_xcvr_table:"
6424977Sraghus 				    " Invalid Neptune type [0x%x]",
6434977Sraghus 				    nxgep->niu_type));
6444977Sraghus 				return (NXGE_ERROR);
6454977Sraghus 			}
6464977Sraghus 
6474977Sraghus 			port_type = nxgep->niu_type >>
6484977Sraghus 			    (NXGE_PORT_TYPE_SHIFT * portn);
6494977Sraghus 			port_type = port_type & (NXGE_PORT_TYPE_MASK);
6504977Sraghus 
6514977Sraghus 			switch (port_type) {
6524977Sraghus 
6534977Sraghus 			case NXGE_PORT_1G_COPPER:
6544977Sraghus 				nxgep->mac.portmode = PORT_1G_COPPER;
6554977Sraghus 				break;
6564977Sraghus 			case NXGE_PORT_10G_COPPER:
6574977Sraghus 				nxgep->mac.portmode = PORT_10G_COPPER;
6584977Sraghus 				break;
6594977Sraghus 			case NXGE_PORT_1G_FIBRE:
6604977Sraghus 				nxgep->mac.portmode = PORT_1G_FIBER;
6614977Sraghus 				break;
6624977Sraghus 			case NXGE_PORT_10G_FIBRE:
6634977Sraghus 				nxgep->mac.portmode = PORT_10G_FIBER;
6644977Sraghus 				break;
6654977Sraghus 			case NXGE_PORT_1G_SERDES:
6664977Sraghus 				nxgep->mac.portmode = PORT_1G_SERDES;
6674977Sraghus 				break;
6684977Sraghus 			case NXGE_PORT_10G_SERDES:
6694977Sraghus 				nxgep->mac.portmode = PORT_10G_SERDES;
6704977Sraghus 				break;
6716835Syc148097 			/* Ports 2 and 3 of Alonso or ARTM */
6724977Sraghus 			case NXGE_PORT_1G_RGMII_FIBER:
6734977Sraghus 				nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
6744977Sraghus 				break;
6756835Syc148097 			case NXGE_PORT_TN1010:
6766835Syc148097 				/*
6776835Syc148097 				 * If this port uses the TN1010 copper
6786835Syc148097 				 * PHY, then its speed is not known yet
6796835Syc148097 				 * because nxge_scan_ports_phy could only
6806835Syc148097 				 * figure out the vendor of the PHY but
6816835Syc148097 				 * not its speed. nxge_set_tn1010_param
6826835Syc148097 				 * will read the PHY speed and set
6836835Syc148097 				 * portmode accordingly.
6846835Syc148097 				 */
6856835Syc148097 				if ((status = nxge_set_tn1010_param(nxgep))
6866835Syc148097 				    != NXGE_OK) {
6876835Syc148097 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6886835Syc148097 					    "nxge_set_tn1010_param failed"));
6896835Syc148097 					return (status);
6906835Syc148097 				}
6916835Syc148097 				break;
6924977Sraghus 			default:
6934977Sraghus 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6944977Sraghus 				    "<== nxge_setup_xcvr_table: "
6954977Sraghus 				    "Unknown port-type: 0x%x", port_type));
6964977Sraghus 				return (NXGE_ERROR);
6974977Sraghus 			}
6984977Sraghus 		}
6994977Sraghus 
7006835Syc148097 		/*
7016835Syc148097 		 * Above switch has figured out nxge->mac.portmode, now set
7026835Syc148097 		 * nxgep->xcvr (the table) and nxgep->xcvr_addr according
7036835Syc148097 		 * to portmode.
7046835Syc148097 		 */
7054977Sraghus 		switch (nxgep->mac.portmode) {
7064977Sraghus 		case PORT_1G_COPPER:
7074977Sraghus 		case PORT_1G_RGMII_FIBER:
7084732Sdavemq 			nxgep->xcvr = nxge_1G_copper_table;
7095572Ssbehera 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
7104732Sdavemq 			/*
7114732Sdavemq 			 * For Altas 4-1G copper, Xcvr port numbers are
7124732Sdavemq 			 * swapped with ethernet port number. This is
7134977Sraghus 			 * designed for better signal integrity in
7144977Sraghus 			 * routing. This is also the case for the
7154977Sraghus 			 * on-board Neptune copper ports on the Maramba
7164977Sraghus 			 * platform.
7174732Sdavemq 			 */
7184977Sraghus 			switch (nxgep->platform_type) {
7194977Sraghus 			case P_NEPTUNE_ATLAS_4PORT:
7204977Sraghus 			case P_NEPTUNE_MARAMBA_P0:
7214977Sraghus 			case P_NEPTUNE_MARAMBA_P1:
7224977Sraghus 				switch (portn) {
7234977Sraghus 				case 0:
7245572Ssbehera 					nxgep->xcvr_addr += 3;
7254977Sraghus 					break;
7264977Sraghus 				case 1:
7275572Ssbehera 					nxgep->xcvr_addr += 1;
7284977Sraghus 					break;
7294977Sraghus 				case 2:
7305572Ssbehera 					nxgep->xcvr_addr -= 1;
7314977Sraghus 					break;
7324977Sraghus 				case 3:
7335572Ssbehera 					nxgep->xcvr_addr -= 3;
7344977Sraghus 					break;
7354977Sraghus 				default:
7364977Sraghus 					return (NXGE_ERROR);
7374977Sraghus 				}
7384732Sdavemq 				break;
7394732Sdavemq 			default:
7404977Sraghus 				break;
7414732Sdavemq 			}
7425196Ssbehera 
7434977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7444977Sraghus 			    (nxgep->mac.portmode == PORT_1G_COPPER) ?
7454977Sraghus 			    "Copper" : "RGMII Fiber"));
7464732Sdavemq 			break;
7476835Syc148097 
7484977Sraghus 		case PORT_10G_COPPER:
7494732Sdavemq 			nxgep->xcvr = nxge_10G_copper_table;
7504732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
7514732Sdavemq 			break;
7526835Syc148097 
7536835Syc148097 		case PORT_1G_TN1010:
7546835Syc148097 			nxgep->xcvr = nxge_1G_tn1010_table;
7556835Syc148097 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
7566835Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
7576835Syc148097 			    "1G TN1010 copper Xcvr"));
7586835Syc148097 			break;
7596835Syc148097 
7606835Syc148097 		case PORT_10G_TN1010:
7616835Syc148097 			nxgep->xcvr = nxge_10G_tn1010_table;
7626835Syc148097 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
7636835Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
7646835Syc148097 			    "10G TN1010 copper Xcvr"));
7656835Syc148097 			break;
7666835Syc148097 
7674977Sraghus 		case PORT_1G_FIBER:
7684977Sraghus 		case PORT_1G_SERDES:
7694732Sdavemq 			nxgep->xcvr = nxge_1G_fiber_table;
7705572Ssbehera 			nxgep->xcvr_addr = portn;
7714977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7724977Sraghus 			    (nxgep->mac.portmode == PORT_1G_FIBER) ?
7734977Sraghus 			    "Fiber" : "Serdes"));
7744732Sdavemq 			break;
7754977Sraghus 		case PORT_10G_FIBER:
7764977Sraghus 		case PORT_10G_SERDES:
7774732Sdavemq 			nxgep->xcvr = nxge_10G_fiber_table;
7785572Ssbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G xcvr "
7795572Ssbehera 			    "nxgep->nxge_hw_p->xcvr_addr[portn] = [%d] "
7805572Ssbehera 			    "nxgep->xcvr_addr = [%d]",
7815572Ssbehera 			    nxgep->nxge_hw_p->xcvr_addr[portn],
7825572Ssbehera 			    nxgep->xcvr_addr));
7835572Ssbehera 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
7845572Ssbehera 				nxgep->xcvr_addr =
7855572Ssbehera 				    nxgep->nxge_hw_p->xcvr_addr[portn];
7865572Ssbehera 			}
7874977Sraghus 			switch (nxgep->platform_type) {
7884977Sraghus 			case P_NEPTUNE_MARAMBA_P0:
7894977Sraghus 			case P_NEPTUNE_MARAMBA_P1:
7904732Sdavemq 				/*
7914732Sdavemq 				 * Switch off LED for corresponding copper
7924732Sdavemq 				 * port
7934732Sdavemq 				 */
7944732Sdavemq 				nxge_bcm5464_link_led_off(nxgep);
7954977Sraghus 				break;
7964977Sraghus 			default:
7974977Sraghus 				break;
7984732Sdavemq 			}
7994977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr",
8004977Sraghus 			    (nxgep->mac.portmode == PORT_10G_FIBER) ?
8014977Sraghus 			    "Fiber" : "Serdes"));
8024732Sdavemq 			break;
8035572Ssbehera 
8045572Ssbehera 		case PORT_HSP_MODE:
8055572Ssbehera 			nxgep->xcvr = nxge_10G_fiber_table;
8065572Ssbehera 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
8075572Ssbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Neptune 10G Hot "
8085572Ssbehera 			    "Swappable Xcvr (not present)"));
8095572Ssbehera 			break;
8104732Sdavemq 		default:
8114732Sdavemq 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8124732Sdavemq 			    "Unknown port-type: 0x%x", port_type));
8134732Sdavemq 			return (NXGE_ERROR);
8144732Sdavemq 		}
8154732Sdavemq 	}
8164732Sdavemq 
81712103SSantwona.Behera@Sun.COM 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
81812103SSantwona.Behera@Sun.COM 	    nxgep->mac.portmode == PORT_10G_COPPER) {
8196604Ssbehera 		uint32_t pma_pmd_id;
8206604Ssbehera 		pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep,
8216604Ssbehera 		    nxgep->xcvr_addr);
8226604Ssbehera 		if ((pma_pmd_id & BCM_PHY_ID_MASK) == MARVELL_88X201X_PHY_ID) {
8236604Ssbehera 			chip_id = MRVL88X201X_CHIP_ID;
8246604Ssbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8256604Ssbehera 			    "nxge_setup_xcvr_table: "
8266604Ssbehera 			    "Chip ID  MARVELL [0x%x] for 10G xcvr", chip_id));
82712103SSantwona.Behera@Sun.COM 		} else if ((pma_pmd_id & NLP2020_DEV_ID_MASK) ==
82812103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID) {
82912103SSantwona.Behera@Sun.COM 			chip_id = NLP2020_CHIP_ID;
83012103SSantwona.Behera@Sun.COM 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83112103SSantwona.Behera@Sun.COM 			    "nxge_setup_xcvr_table: "
83212103SSantwona.Behera@Sun.COM 			    "Chip ID  AEL2020 [0x%x] for 10G xcvr", chip_id));
8336604Ssbehera 		} else if ((status = nxge_mdio_read(nxgep, nxgep->xcvr_addr,
8345572Ssbehera 		    BCM8704_PCS_DEV_ADDR, BCM8704_CHIP_ID_REG,
8355572Ssbehera 		    &chip_id)) == NXGE_OK) {
8365572Ssbehera 
8375572Ssbehera 			switch (chip_id) {
8385572Ssbehera 			case BCM8704_CHIP_ID:
8395572Ssbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8405572Ssbehera 				    "nxge_setup_xcvr_table: "
8415572Ssbehera 				    "Chip ID 8704 [0x%x] for 10G xcvr",
8425572Ssbehera 				    chip_id));
8435572Ssbehera 				break;
8445572Ssbehera 			case BCM8706_CHIP_ID:
8455572Ssbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8465572Ssbehera 				    "nxge_setup_xcvr_table: "
8475572Ssbehera 				    "Chip ID 8706 [0x%x] for 10G xcvr",
8485572Ssbehera 				    chip_id));
8495572Ssbehera 				break;
8505572Ssbehera 			default:
8515572Ssbehera 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8525572Ssbehera 				    "nxge_setup_xcvr_table: "
8535572Ssbehera 				    "Unknown Chip ID [0x%x] for 10G xcvr",
8545572Ssbehera 				    chip_id));
8555572Ssbehera 				break;
8565572Ssbehera 			}
8575572Ssbehera 		}
8585572Ssbehera 	}
8595572Ssbehera 
8604732Sdavemq 	nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse;
8615572Ssbehera 	nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr_addr;
8625572Ssbehera 	nxgep->chip_id = chip_id;
8634977Sraghus 
8644977Sraghus 	/*
8654977Sraghus 	 * Get the actual device ID value returned by MDIO read.
8664977Sraghus 	 */
8674977Sraghus 	nxgep->statsp->mac_stats.xcvr_id = 0;
8684977Sraghus 
8695572Ssbehera 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr_addr);
8704977Sraghus 	if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) {
8714977Sraghus 		nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id;
8724977Sraghus 	} else {
8735572Ssbehera 		pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr_addr);
8744977Sraghus 		if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) {
8754977Sraghus 			nxgep->statsp->mac_stats.xcvr_id = pcs_id;
8764977Sraghus 		} else {
8774977Sraghus 			phy_id = nxge_get_cl22_phy_id(nxgep,
8785572Ssbehera 			    nxgep->xcvr_addr);
8794977Sraghus 			if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
8804977Sraghus 				nxgep->statsp->mac_stats.xcvr_id = phy_id;
8814977Sraghus 			}
8824977Sraghus 		}
8834977Sraghus 	}
8844977Sraghus 
8854732Sdavemq 	nxgep->mac.linkchkmode = LINKCHK_TIMER;
8864732Sdavemq 
8874977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type"
8887801SSantwona.Behera@Sun.COM 	    "[0x%x] platform type[0x%x] xcvr_addr[%d]", nxgep->niu_type,
8895572Ssbehera 	    nxgep->platform_type, nxgep->xcvr_addr));
8904977Sraghus 
8914732Sdavemq 	return (status);
8924732Sdavemq }
8934732Sdavemq 
8943859Sml29623 /* Initialize the entire MAC and physical layer */
8953859Sml29623 
8963859Sml29623 nxge_status_t
nxge_mac_init(p_nxge_t nxgep)8973859Sml29623 nxge_mac_init(p_nxge_t nxgep)
8983859Sml29623 {
8993859Sml29623 	uint8_t			portn;
9003859Sml29623 	nxge_status_t		status = NXGE_OK;
9013859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
9023859Sml29623 
9033859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn));
9043859Sml29623 
9053859Sml29623 	nxgep->mac.portnum = portn;
9063859Sml29623 	nxgep->mac.porttype = PORT_TYPE_XMAC;
9073859Sml29623 
9083859Sml29623 	if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1))
9093859Sml29623 		nxgep->mac.porttype = PORT_TYPE_BMAC;
9103859Sml29623 
9116835Syc148097 
9123859Sml29623 	/* Initialize XIF to configure a network mode */
9133859Sml29623 	if ((status = nxge_xif_init(nxgep)) != NXGE_OK) {
9143859Sml29623 		goto fail;
9153859Sml29623 	}
9163859Sml29623 
9173859Sml29623 	if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) {
9183859Sml29623 		goto fail;
9193859Sml29623 	}
9203859Sml29623 
9213859Sml29623 	/* Initialize TX and RX MACs */
9223859Sml29623 	/*
9233859Sml29623 	 * Always perform XIF init first, before TX and RX MAC init
9243859Sml29623 	 */
9253859Sml29623 	if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK)
9263859Sml29623 		goto fail;
9273859Sml29623 
9283859Sml29623 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
9293859Sml29623 		goto fail;
9303859Sml29623 
9313859Sml29623 	if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK)
9323859Sml29623 		goto fail;
9333859Sml29623 
9343859Sml29623 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
9353859Sml29623 		goto fail;
9363859Sml29623 
9373859Sml29623 	if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK)
9383859Sml29623 		goto fail;
9393859Sml29623 
9409232SMichael.Speer@Sun.COM 	if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) {
9419232SMichael.Speer@Sun.COM 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
9429232SMichael.Speer@Sun.COM 			goto fail;
9439232SMichael.Speer@Sun.COM 	}
9443859Sml29623 
9455553Smisaki 	/* Initialize MAC control configuration */
9465553Smisaki 	if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) {
9475553Smisaki 		goto fail;
9485553Smisaki 	}
9495553Smisaki 
9503859Sml29623 	nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize;
9513859Sml29623 
9525196Ssbehera 	/* The Neptune Serdes needs to be reinitialized again */
9535196Ssbehera 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
9545196Ssbehera 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
9556835Syc148097 	    (nxgep->mac.portmode == PORT_1G_TN1010) ||
9565196Ssbehera 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
9575196Ssbehera 	    ((portn == 0) || (portn == 1))) {
9585196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
9595196Ssbehera 		    "nxge_mac_init: reinit Neptune 1G Serdes "));
9605196Ssbehera 		if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) {
9615196Ssbehera 			goto fail;
9625196Ssbehera 		}
9635196Ssbehera 	}
9645196Ssbehera 
9654977Sraghus 
9663859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn));
9673859Sml29623 
9683859Sml29623 	return (NXGE_OK);
9693859Sml29623 fail:
9703859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
9716929Smisaki 	    "nxge_mac_init: failed to initialize MAC port<%d>", portn));
9723859Sml29623 	return (status);
9733859Sml29623 }
9743859Sml29623 
9753859Sml29623 /* Initialize the Ethernet Link */
9763859Sml29623 
9773859Sml29623 nxge_status_t
nxge_link_init(p_nxge_t nxgep)9783859Sml29623 nxge_link_init(p_nxge_t nxgep)
9793859Sml29623 {
9803859Sml29623 	nxge_status_t		status = NXGE_OK;
9814977Sraghus 	nxge_port_mode_t	portmode;
9823859Sml29623 #ifdef	NXGE_DEBUG
9833859Sml29623 	uint8_t			portn;
9843859Sml29623 
9853859Sml29623 	portn = nxgep->mac.portnum;
9863859Sml29623 
9873859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn));
9883859Sml29623 #endif
9899599Stc99174@train 	/* For Opus NEM, Serdes always needs to be initialized */
9903859Sml29623 
9914977Sraghus 	portmode = nxgep->mac.portmode;
9925572Ssbehera 
9936835Syc148097 	/*
9946835Syc148097 	 * Workaround to get link up in both NIU ports. Some portmodes require
9956835Syc148097 	 * that the xcvr be initialized twice, the first time before calling
9966835Syc148097 	 * nxge_serdes_init.
9976835Syc148097 	 */
9984977Sraghus 	if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) &&
9996835Syc148097 	    (portmode != PORT_10G_TN1010) &&
10006835Syc148097 	    (portmode != PORT_1G_TN1010) &&
10014977Sraghus 	    (portmode != PORT_1G_SERDES)) {
10024977Sraghus 		if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) {
10033859Sml29623 			goto fail;
10044977Sraghus 		}
10053859Sml29623 	}
10066835Syc148097 
10073859Sml29623 	NXGE_DELAY(200000);
10083859Sml29623 	/* Initialize internal serdes */
10093859Sml29623 	if ((status = nxge_serdes_init(nxgep)) != NXGE_OK)
10103859Sml29623 		goto fail;
10113859Sml29623 	NXGE_DELAY(200000);
10123859Sml29623 	if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
10133859Sml29623 		goto fail;
10143859Sml29623 
10153859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn));
10163859Sml29623 
10173859Sml29623 	return (NXGE_OK);
10183859Sml29623 
10193859Sml29623 fail:
10206929Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_link_init: ",
10216929Smisaki 	    "failed to initialize Ethernet link on port<%d>", portn));
10223859Sml29623 
10233859Sml29623 	return (status);
10243859Sml29623 }
10253859Sml29623 
10263859Sml29623 
10273859Sml29623 /* Initialize the XIF sub-block within the MAC */
10283859Sml29623 
10293859Sml29623 nxge_status_t
nxge_xif_init(p_nxge_t nxgep)10303859Sml29623 nxge_xif_init(p_nxge_t nxgep)
10313859Sml29623 {
10323859Sml29623 	uint32_t		xif_cfg = 0;
10333859Sml29623 	npi_attr_t		ap;
10343859Sml29623 	uint8_t			portn;
10353859Sml29623 	nxge_port_t		portt;
10363859Sml29623 	nxge_port_mode_t	portmode;
10373859Sml29623 	p_nxge_stats_t		statsp;
10383859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
10393859Sml29623 	npi_handle_t		handle;
10403859Sml29623 
10413859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
10423859Sml29623 
10433859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn));
10443859Sml29623 
10453859Sml29623 	handle = nxgep->npi_handle;
10463859Sml29623 	portmode = nxgep->mac.portmode;
10473859Sml29623 	portt = nxgep->mac.porttype;
10483859Sml29623 	statsp = nxgep->statsp;
10493859Sml29623 
10505196Ssbehera 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
10515196Ssbehera 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
10526835Syc148097 	    (nxgep->mac.portmode == PORT_1G_TN1010) ||
10535196Ssbehera 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
10545196Ssbehera 	    ((portn == 0) || (portn == 1))) {
10555196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
10565196Ssbehera 		    "nxge_xcvr_init: set ATCA mode"));
10575196Ssbehera 		npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE);
10585196Ssbehera 	}
10595196Ssbehera 
10603859Sml29623 	if (portt == PORT_TYPE_XMAC) {
10613859Sml29623 
10623859Sml29623 		/* Setup XIF Configuration for XMAC */
10633859Sml29623 
10643859Sml29623 		if ((portmode == PORT_10G_FIBER) ||
10654977Sraghus 		    (portmode == PORT_10G_COPPER) ||
10666835Syc148097 		    (portmode == PORT_10G_TN1010) ||
10679599Stc99174@train 		    (portmode == PORT_HSP_MODE) ||
10684977Sraghus 		    (portmode == PORT_10G_SERDES))
10693859Sml29623 			xif_cfg |= CFG_XMAC_XIF_LFS;
10703859Sml29623 
10716835Syc148097 		/* Bypass PCS so that RGMII will be used */
10723859Sml29623 		if (portmode == PORT_1G_COPPER) {
10733859Sml29623 			xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS;
10743859Sml29623 		}
10753859Sml29623 
10763859Sml29623 		/* Set MAC Internal Loopback if necessary */
10773859Sml29623 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
10783859Sml29623 			xif_cfg |= CFG_XMAC_XIF_LOOPBACK;
10793859Sml29623 
10803859Sml29623 		if (statsp->mac_stats.link_speed == 100)
10813859Sml29623 			xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ;
10823859Sml29623 
10833859Sml29623 		xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT;
10843859Sml29623 
10854977Sraghus 		if ((portmode == PORT_10G_FIBER) ||
108612103SSantwona.Behera@Sun.COM 		    (portmode == PORT_10G_COPPER) ||
10876835Syc148097 		    (portmode == PORT_10G_TN1010) ||
10886835Syc148097 		    (portmode == PORT_1G_TN1010) ||
10899599Stc99174@train 		    (portmode == PORT_HSP_MODE) ||
10904977Sraghus 		    (portmode == PORT_10G_SERDES)) {
10916835Syc148097 			/* Assume LED same for 1G and 10G */
10923859Sml29623 			if (statsp->mac_stats.link_up) {
10933859Sml29623 				xif_cfg |= CFG_XMAC_XIF_LED_POLARITY;
10943859Sml29623 			} else {
10953859Sml29623 				xif_cfg |= CFG_XMAC_XIF_LED_FORCE;
10963859Sml29623 			}
10973859Sml29623 		}
10983859Sml29623 
10993859Sml29623 		rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg);
11003859Sml29623 		if (rs != NPI_SUCCESS)
11013859Sml29623 			goto fail;
11023859Sml29623 
11033859Sml29623 		nxgep->mac.xif_config = xif_cfg;
11043859Sml29623 
11053859Sml29623 		/* Set Port Mode */
11063859Sml29623 		if ((portmode == PORT_10G_FIBER) ||
11074977Sraghus 		    (portmode == PORT_10G_COPPER) ||
11086835Syc148097 		    (portmode == PORT_10G_TN1010) ||
11099599Stc99174@train 		    (portmode == PORT_HSP_MODE) ||
11104977Sraghus 		    (portmode == PORT_10G_SERDES)) {
11113859Sml29623 			SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11126929Smisaki 			    MAC_XGMII_MODE, rs);
11133859Sml29623 			if (rs != NPI_SUCCESS)
11143859Sml29623 				goto fail;
11153859Sml29623 			if (statsp->mac_stats.link_up) {
11163859Sml29623 				if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
11173859Sml29623 					goto fail;
11183859Sml29623 			} else {
11193859Sml29623 				if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
11203859Sml29623 					goto fail;
11213859Sml29623 			}
11223859Sml29623 		} else if ((portmode == PORT_1G_FIBER) ||
11234977Sraghus 		    (portmode == PORT_1G_COPPER) ||
11245196Ssbehera 		    (portmode == PORT_1G_SERDES) ||
11256835Syc148097 		    (portmode == PORT_1G_TN1010) ||
11265196Ssbehera 		    (portmode == PORT_1G_RGMII_FIBER)) {
11275196Ssbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11285196Ssbehera 			    "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]",
11295196Ssbehera 			    portn, portmode, statsp->mac_stats.link_speed));
11303859Sml29623 			if (statsp->mac_stats.link_speed == 1000) {
11313859Sml29623 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11326929Smisaki 				    MAC_GMII_MODE, rs);
11333859Sml29623 			} else {
11343859Sml29623 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11356929Smisaki 				    MAC_MII_MODE, rs);
11363859Sml29623 			}
11373859Sml29623 			if (rs != NPI_SUCCESS)
11383859Sml29623 				goto fail;
11393859Sml29623 		} else {
11403859Sml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11416929Smisaki 			    "nxge_xif_init: Unknown port mode (%d)"
11426929Smisaki 			    " for port<%d>", portmode, portn));
11433859Sml29623 			goto fail;
11443859Sml29623 		}
11453859Sml29623 
11465196Ssbehera 		/* Enable ATCA mode */
11475196Ssbehera 
11483859Sml29623 	} else if (portt == PORT_TYPE_BMAC) {
11493859Sml29623 
11503859Sml29623 		/* Setup XIF Configuration for BMAC */
11513859Sml29623 
11525196Ssbehera 		if ((portmode == PORT_1G_COPPER) ||
11535196Ssbehera 		    (portmode == PORT_1G_RGMII_FIBER)) {
11543859Sml29623 			if (statsp->mac_stats.link_speed == 100)
11553859Sml29623 				xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ;
11563859Sml29623 		}
11573859Sml29623 
11583859Sml29623 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
11593859Sml29623 			xif_cfg |= CFG_BMAC_XIF_LOOPBACK;
11603859Sml29623 
11613859Sml29623 		if (statsp->mac_stats.link_speed == 1000)
11623859Sml29623 			xif_cfg |= CFG_BMAC_XIF_GMII_MODE;
11633859Sml29623 
11643859Sml29623 		xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT;
11653859Sml29623 
11663859Sml29623 		rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg);
11673859Sml29623 		if (rs != NPI_SUCCESS)
11683859Sml29623 			goto fail;
11693859Sml29623 		nxgep->mac.xif_config = xif_cfg;
11703859Sml29623 	}
11713859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn));
11723859Sml29623 	return (NXGE_OK);
11733859Sml29623 fail:
11743859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11756929Smisaki 	    "nxge_xif_init: Failed to initialize XIF port<%d>", portn));
11763859Sml29623 	return (NXGE_ERROR | rs);
11773859Sml29623 }
11783859Sml29623 
11796835Syc148097 
11806835Syc148097 /*
11816835Syc148097  * Initialize the PCS sub-block in the MAC.  Note that PCS does not
11826835Syc148097  * support loopback like XPCS.
11836835Syc148097  */
11843859Sml29623 nxge_status_t
nxge_pcs_init(p_nxge_t nxgep)11853859Sml29623 nxge_pcs_init(p_nxge_t nxgep)
11863859Sml29623 {
11873859Sml29623 	pcs_cfg_t		pcs_cfg;
11883859Sml29623 	uint32_t		val;
11893859Sml29623 	uint8_t			portn;
11903859Sml29623 	nxge_port_mode_t	portmode;
11913859Sml29623 	npi_handle_t		handle;
11923859Sml29623 	p_nxge_stats_t		statsp;
11936835Syc148097 	pcs_ctrl_t		pcs_ctrl;
11943859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
11956835Syc148097 	uint8_t i;
11963859Sml29623 
11973859Sml29623 	handle = nxgep->npi_handle;
11983859Sml29623 	portmode = nxgep->mac.portmode;
11993859Sml29623 	portn = nxgep->mac.portnum;
12003859Sml29623 	statsp = nxgep->statsp;
12013859Sml29623 
12023859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn));
12033859Sml29623 
12046835Syc148097 	if (portmode == PORT_1G_FIBER ||
12056835Syc148097 	    portmode == PORT_1G_TN1010 ||
12066835Syc148097 	    portmode == PORT_1G_SERDES) {
12076835Syc148097 		if (portmode == PORT_1G_TN1010) {
12086835Syc148097 			/* Reset PCS multiple time in PORT_1G_TN1010 mode */
12096835Syc148097 			for (i = 0; i < 6; i ++) {
12106835Syc148097 				if ((rs = npi_mac_pcs_reset(handle, portn))
12116835Syc148097 				    != NPI_SUCCESS) {
12126835Syc148097 					goto fail;
12136835Syc148097 				}
12146835Syc148097 			}
12156835Syc148097 		} else {
12166835Syc148097 			if ((rs = npi_mac_pcs_reset(handle, portn))
12176835Syc148097 			    != NPI_SUCCESS)
12186835Syc148097 				goto fail;
12194977Sraghus 		}
12204977Sraghus 
12213859Sml29623 		/* Initialize port's PCS */
12223859Sml29623 		pcs_cfg.value = 0;
12233859Sml29623 		pcs_cfg.bits.w0.enable = 1;
12243859Sml29623 		pcs_cfg.bits.w0.mask = 1;
12253859Sml29623 		PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value);
12263859Sml29623 		PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0);
12274977Sraghus 
12284977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12294977Sraghus 		    "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx",
12304977Sraghus 		    portn, pcs_cfg.value));
12316835Syc148097 
12326835Syc148097 		if (portmode == PORT_1G_TN1010) {
12336835Syc148097 			/*
12346835Syc148097 			 * Must disable PCS auto-negotiation when the the driver
12356835Syc148097 			 * is driving the TN1010 based XAUI card  Otherwise the
12366835Syc148097 			 * autonegotiation between the PCS and the TN1010 PCS
12376835Syc148097 			 * will never complete and the Neptune/NIU will not work
12386835Syc148097 			 */
12396835Syc148097 			pcs_ctrl.value = 0;
12406835Syc148097 			PCS_REG_WR(handle, portn, PCS_MII_CTRL_REG,
12416835Syc148097 			    pcs_ctrl.value);
12426835Syc148097 		}
12436835Syc148097 	} else if (portmode == PORT_10G_FIBER ||
12446835Syc148097 	    portmode == PORT_10G_COPPER ||
12456835Syc148097 	    portmode == PORT_10G_TN1010 ||
12469599Stc99174@train 	    portmode == PORT_HSP_MODE ||
12476835Syc148097 	    portmode == PORT_10G_SERDES) {
12483859Sml29623 		/* Use internal XPCS, bypass 1G PCS */
12493859Sml29623 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
12503859Sml29623 		val &= ~XMAC_XIF_XPCS_BYPASS;
12513859Sml29623 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
12523859Sml29623 
12533859Sml29623 		if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS)
12543859Sml29623 			goto fail;
12553859Sml29623 
12563859Sml29623 		/* Set XPCS Internal Loopback if necessary */
12573859Sml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
12586929Smisaki 		    XPCS_REG_CONTROL1, &val)) != NPI_SUCCESS)
12593859Sml29623 			goto fail;
12606835Syc148097 
12613859Sml29623 		if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) ||
12626929Smisaki 		    (statsp->port_stats.lb_mode == nxge_lb_mac1000))
12633859Sml29623 			val |= XPCS_CTRL1_LOOPBK;
12643859Sml29623 		else
12653859Sml29623 			val &= ~XPCS_CTRL1_LOOPBK;
12663859Sml29623 		if ((rs = npi_xmac_xpcs_write(handle, portn,
12676929Smisaki 		    XPCS_REG_CONTROL1, val)) != NPI_SUCCESS)
12683859Sml29623 			goto fail;
12693859Sml29623 
12703859Sml29623 		/* Clear descw errors */
12713859Sml29623 		if ((rs = npi_xmac_xpcs_write(handle, portn,
12726929Smisaki 		    XPCS_REG_DESCWERR_COUNTER, 0)) != NPI_SUCCESS)
12733859Sml29623 			goto fail;
12743859Sml29623 		/* Clear symbol errors */
12753859Sml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
12766929Smisaki 		    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) != NPI_SUCCESS)
12773859Sml29623 			goto fail;
12783859Sml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
12796929Smisaki 		    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) != NPI_SUCCESS)
12803859Sml29623 			goto fail;
12813859Sml29623 
12825196Ssbehera 	} else if ((portmode == PORT_1G_COPPER) ||
12835196Ssbehera 	    (portmode == PORT_1G_RGMII_FIBER)) {
12845196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12855196Ssbehera 		    "==> nxge_pcs_init: (1G) copper port<%d>", portn));
12863859Sml29623 		if (portn < 4) {
12873859Sml29623 			PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG,
12886929Smisaki 			    PCS_DATAPATH_MODE_MII);
12893859Sml29623 		}
12903859Sml29623 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
12913859Sml29623 			goto fail;
12923859Sml29623 
12933859Sml29623 	} else {
12943859Sml29623 		goto fail;
12953859Sml29623 	}
12963859Sml29623 pass:
12973859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn));
12983859Sml29623 	return (NXGE_OK);
12993859Sml29623 fail:
13003859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13016929Smisaki 	    "nxge_pcs_init: Failed to initialize PCS port<%d>", portn));
13023859Sml29623 	return (NXGE_ERROR | rs);
13033859Sml29623 }
13043859Sml29623 
13055553Smisaki /*
13065553Smisaki  * Initialize the MAC CTRL sub-block within the MAC
13075553Smisaki  * Only the receive-pause-cap is supported.
13085553Smisaki  */
13095553Smisaki nxge_status_t
nxge_mac_ctrl_init(p_nxge_t nxgep)13105553Smisaki nxge_mac_ctrl_init(p_nxge_t nxgep)
13115553Smisaki {
13125553Smisaki 	uint8_t			portn;
13135553Smisaki 	nxge_port_t		portt;
13145553Smisaki 	p_nxge_stats_t		statsp;
13155553Smisaki 	npi_handle_t		handle;
13165553Smisaki 	uint32_t		val;
13175553Smisaki 
13185553Smisaki 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
13195553Smisaki 
13205553Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>",
13215553Smisaki 	    portn));
13225553Smisaki 
13235553Smisaki 	handle = nxgep->npi_handle;
13245553Smisaki 	portt = nxgep->mac.porttype;
13255553Smisaki 	statsp = nxgep->statsp;
13265553Smisaki 
13275553Smisaki 	if (portt == PORT_TYPE_XMAC) {
13286835Syc148097 		/* Reading the current XMAC Config Register for XMAC */
13295553Smisaki 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
13305553Smisaki 
13315553Smisaki 		/*
13325553Smisaki 		 * Setup XMAC Configuration for XMAC
13335553Smisaki 		 * XMAC only supports receive-pause
13345553Smisaki 		 */
13355553Smisaki 		if (statsp->mac_stats.adv_cap_asmpause) {
13365553Smisaki 			if (!statsp->mac_stats.adv_cap_pause) {
13375553Smisaki 				/*
13385553Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
13395553Smisaki 				 * is 0, enable receive pause.
13405553Smisaki 				 */
13415553Smisaki 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
13425553Smisaki 			} else {
13435553Smisaki 				/*
13445553Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
13455553Smisaki 				 * is 1, disable receive pause.  Send pause is
13465553Smisaki 				 * not supported.
13475553Smisaki 				 */
13485553Smisaki 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
13495553Smisaki 			}
13505553Smisaki 		} else {
13516439Sml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13526439Sml29623 			    "==> nxge_mac_ctrl_init: port<%d>: pause",
13536439Sml29623 			    portn));
13545553Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
13556439Sml29623 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13566439Sml29623 				    "==> nxge_mac_ctrl_init: port<%d>: "
13576439Sml29623 				    "enable pause", portn));
13585553Smisaki 				/*
13595553Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
13605553Smisaki 				 * is 1, enable receive pause.
13615553Smisaki 				 */
13625553Smisaki 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
13635553Smisaki 			} else {
13645553Smisaki 				/*
13655553Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
13665553Smisaki 				 * is 0, disable receive pause. Send pause is
13675553Smisaki 				 * not supported
13685553Smisaki 				 */
13696439Sml29623 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13706439Sml29623 				    "==> nxge_mac_ctrl_init: port<%d>: "
13716439Sml29623 				    "disable pause", portn));
13725553Smisaki 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
13735553Smisaki 			}
13745553Smisaki 		}
13755553Smisaki 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
13765553Smisaki 	} else if (portt == PORT_TYPE_BMAC) {
13776835Syc148097 		/* Reading the current MAC CTRL Config Register for BMAC */
13785553Smisaki 		BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val);
13795553Smisaki 
13805553Smisaki 		/* Setup MAC CTRL Configuration for BMAC */
13815553Smisaki 		if (statsp->mac_stats.adv_cap_asmpause) {
13825553Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
13835553Smisaki 				/*
13845553Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
13855553Smisaki 				 * is 1, disable receive pause. Send pause
13865553Smisaki 				 * is not supported
13875553Smisaki 				 */
13885553Smisaki 				val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN;
13895553Smisaki 			} else {
13905553Smisaki 				/*
13915553Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
13925553Smisaki 				 * is 0, enable receive pause and disable
13935553Smisaki 				 * send pause.
13945553Smisaki 				 */
13955553Smisaki 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
13965553Smisaki 				val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN;
13975553Smisaki 			}
13985553Smisaki 		} else {
13995553Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
14005553Smisaki 				/*
14015553Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
14025553Smisaki 				 * is 1, enable receive pause. Send pause is
14035553Smisaki 				 * not supported.
14045553Smisaki 				 */
14055553Smisaki 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
14065553Smisaki 			} else {
14075553Smisaki 				/*
14085553Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
14095553Smisaki 				 * is 0, pause capability is not available in
14105553Smisaki 				 * either direction.
14115553Smisaki 				 */
14125553Smisaki 				val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN &
14136929Smisaki 				    ~MAC_CTRL_CFG_RECV_PAUSE_EN);
14145553Smisaki 			}
14155553Smisaki 		}
14165553Smisaki 		BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val);
14175553Smisaki 	}
14185553Smisaki 
14195553Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>",
14205553Smisaki 	    portn));
14215553Smisaki 
14225553Smisaki 	return (NXGE_OK);
14235553Smisaki }
14245553Smisaki 
14253859Sml29623 /* Initialize the Internal Serdes */
14263859Sml29623 
14273859Sml29623 nxge_status_t
nxge_serdes_init(p_nxge_t nxgep)14283859Sml29623 nxge_serdes_init(p_nxge_t nxgep)
14293859Sml29623 {
14303859Sml29623 	p_nxge_stats_t		statsp;
14313859Sml29623 #ifdef	NXGE_DEBUG
14323859Sml29623 	uint8_t			portn;
14333859Sml29623 #endif
14343859Sml29623 	nxge_status_t		status = NXGE_OK;
14353859Sml29623 
14363859Sml29623 #ifdef	NXGE_DEBUG
14373859Sml29623 	portn = nxgep->mac.portnum;
14383859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14394732Sdavemq 	    "==> nxge_serdes_init port<%d>", portn));
14403859Sml29623 #endif
14413859Sml29623 
14424732Sdavemq 	if (nxgep->xcvr.serdes_init) {
14434732Sdavemq 		statsp = nxgep->statsp;
14444732Sdavemq 		status = nxgep->xcvr.serdes_init(nxgep);
14454732Sdavemq 		if (status != NXGE_OK)
14463859Sml29623 			goto fail;
14474732Sdavemq 		statsp->mac_stats.serdes_inits++;
14483859Sml29623 	}
14493859Sml29623 
14503859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
14514732Sdavemq 	    portn));
14523859Sml29623 
14533859Sml29623 	return (NXGE_OK);
14543859Sml29623 
14553859Sml29623 fail:
14563859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14574732Sdavemq 	    "nxge_serdes_init: Failed to initialize serdes for port<%d>",
14584732Sdavemq 	    portn));
14593859Sml29623 
14603859Sml29623 	return (status);
14613859Sml29623 }
14623859Sml29623 
14633859Sml29623 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
14643859Sml29623 
14654732Sdavemq static nxge_status_t
nxge_n2_serdes_init(p_nxge_t nxgep)14663859Sml29623 nxge_n2_serdes_init(p_nxge_t nxgep)
14673859Sml29623 {
14683859Sml29623 	uint8_t portn;
14693859Sml29623 	int chan;
14703859Sml29623 	esr_ti_cfgpll_l_t pll_cfg_l;
14714977Sraghus 	esr_ti_cfgpll_l_t pll_sts_l;
14723859Sml29623 	esr_ti_cfgrx_l_t rx_cfg_l;
14733859Sml29623 	esr_ti_cfgrx_h_t rx_cfg_h;
14743859Sml29623 	esr_ti_cfgtx_l_t tx_cfg_l;
14753859Sml29623 	esr_ti_cfgtx_h_t tx_cfg_h;
14764977Sraghus #ifdef NXGE_DEBUG
14774977Sraghus 	esr_ti_testcfg_t cfg;
14784977Sraghus #endif
14793859Sml29623 	esr_ti_testcfg_t test_cfg;
14803859Sml29623 	nxge_status_t status = NXGE_OK;
14813859Sml29623 
14823859Sml29623 	portn = nxgep->mac.portnum;
14833859Sml29623 
14843859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>",
14856929Smisaki 	    portn));
148611304SJanie.Lu@Sun.COM 	if (nxgep->niu_hw_type == NIU_HW_TYPE_RF) {
148711304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
148811304SJanie.Lu@Sun.COM 		    "==> nxge_n2_serdes_init port<%d>: KT-NIU", portn));
148911304SJanie.Lu@Sun.COM 		return (nxge_n2_kt_serdes_init(nxgep));
149011304SJanie.Lu@Sun.COM 	}
14913859Sml29623 
14923859Sml29623 	tx_cfg_l.value = 0;
14933859Sml29623 	tx_cfg_h.value = 0;
14943859Sml29623 	rx_cfg_l.value = 0;
14953859Sml29623 	rx_cfg_h.value = 0;
14963859Sml29623 	pll_cfg_l.value = 0;
14974977Sraghus 	pll_sts_l.value = 0;
14983859Sml29623 	test_cfg.value = 0;
14993859Sml29623 
15006835Syc148097 	/*
15016835Syc148097 	 * If the nxge driver has been plumbed without a link, then it will
15026835Syc148097 	 * detect a link up when a cable connecting to an anto-negotiation
15036835Syc148097 	 * partner is plugged into the port. Because the TN1010 PHY supports
15046835Syc148097 	 * both 1G and 10G speeds, the driver must re-configure the
15056835Syc148097 	 * Neptune/NIU according to the negotiated speed.  nxge_n2_serdes_init
15066835Syc148097 	 * is called at the post-link-up reconfiguration time. Here it calls
15076835Syc148097 	 * nxge_set_tn1010_param to set portmode before re-initializing
15086835Syc148097 	 * the serdes.
15096835Syc148097 	 */
15106835Syc148097 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
15116835Syc148097 	    nxgep->mac.portmode == PORT_10G_TN1010) {
15126835Syc148097 		if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
15136835Syc148097 			goto fail;
15146835Syc148097 		}
15156835Syc148097 	}
15166835Syc148097 
15176835Syc148097 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
151812103SSantwona.Behera@Sun.COM 	    nxgep->mac.portmode == PORT_10G_COPPER ||
15196835Syc148097 	    nxgep->mac.portmode == PORT_10G_TN1010 ||
15209599Stc99174@train 	    nxgep->mac.portmode == PORT_HSP_MODE ||
15216835Syc148097 	    nxgep->mac.portmode == PORT_10G_SERDES) {
15223859Sml29623 		/* 0x0E01 */
15233859Sml29623 		tx_cfg_l.bits.entx = 1;
15243859Sml29623 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
15253859Sml29623 
15263859Sml29623 		/* 0x9101 */
15273859Sml29623 		rx_cfg_l.bits.enrx = 1;
15283859Sml29623 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
15293859Sml29623 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
15303859Sml29623 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
15313859Sml29623 
15323859Sml29623 		/* 0x0008 */
15333859Sml29623 		rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
15343859Sml29623 
15353859Sml29623 		/* Set loopback mode if necessary */
15363859Sml29623 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
15373859Sml29623 			tx_cfg_l.bits.entest = 1;
15383859Sml29623 			rx_cfg_l.bits.entest = 1;
15393859Sml29623 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
15403859Sml29623 			if ((status = nxge_mdio_write(nxgep, portn,
15416929Smisaki 			    ESR_N2_DEV_ADDR,
15426929Smisaki 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK)
15433859Sml29623 			goto fail;
15443859Sml29623 		}
15453859Sml29623 
15466835Syc148097 		/* Initialize PLL for 10G */
15476835Syc148097 		pll_cfg_l.bits.mpy = CFGPLL_MPY_10X;
15486835Syc148097 		pll_cfg_l.bits.enpll = 1;
15496835Syc148097 		pll_sts_l.bits.enpll = 1;
15506835Syc148097 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
15516835Syc148097 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
15526835Syc148097 			goto fail;
15536835Syc148097 
15546835Syc148097 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
15556835Syc148097 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
15566835Syc148097 			goto fail;
15576835Syc148097 
15586835Syc148097 #ifdef  NXGE_DEBUG
15596835Syc148097 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
15606835Syc148097 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
15616835Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
15626835Syc148097 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
15636835Syc148097 		    portn, pll_cfg_l.value, cfg.value));
15646835Syc148097 
15656835Syc148097 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
15666835Syc148097 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
15676835Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
15686835Syc148097 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
15696835Syc148097 		    portn, pll_sts_l.value, cfg.value));
15706835Syc148097 #endif
15716835Syc148097 	} else if (nxgep->mac.portmode == PORT_1G_FIBER ||
15726835Syc148097 	    nxgep->mac.portmode == PORT_1G_TN1010 ||
15736835Syc148097 	    nxgep->mac.portmode == PORT_1G_SERDES) {
15743859Sml29623 		/* 0x0E21 */
15753859Sml29623 		tx_cfg_l.bits.entx = 1;
15763859Sml29623 		tx_cfg_l.bits.rate = CFGTX_RATE_HALF;
15773859Sml29623 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
15783859Sml29623 
15793859Sml29623 		/* 0x9121 */
15803859Sml29623 		rx_cfg_l.bits.enrx = 1;
15813859Sml29623 		rx_cfg_l.bits.rate = CFGRX_RATE_HALF;
15823859Sml29623 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
15833859Sml29623 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
15843859Sml29623 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
15853859Sml29623 
15864977Sraghus 		if (portn == 0) {
15874977Sraghus 			/* 0x8 */
15884977Sraghus 			rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
15894977Sraghus 		}
15903859Sml29623 
15916835Syc148097 		/* Initialize PLL for 1G */
15923859Sml29623 		pll_cfg_l.bits.mpy = CFGPLL_MPY_8X;
15933859Sml29623 		pll_cfg_l.bits.enpll = 1;
15944977Sraghus 		pll_sts_l.bits.enpll = 1;
15953859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
15966929Smisaki 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
15973859Sml29623 			goto fail;
15984977Sraghus 
15994977Sraghus 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16004977Sraghus 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
16014977Sraghus 			goto fail;
16024977Sraghus 
16034977Sraghus #ifdef  NXGE_DEBUG
16044977Sraghus 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
16054977Sraghus 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
16064977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16074977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
16084977Sraghus 		    portn, pll_cfg_l.value, cfg.value));
16094977Sraghus 
16104977Sraghus 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
16114977Sraghus 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
16124977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16134977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
16144977Sraghus 		    portn, pll_sts_l.value, cfg.value));
16154977Sraghus #endif
16164977Sraghus 
16174977Sraghus 		/* Set loopback mode if necessary */
16184977Sraghus 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
16194977Sraghus 			tx_cfg_l.bits.entest = 1;
16204977Sraghus 			rx_cfg_l.bits.entest = 1;
16214977Sraghus 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
16224977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16234977Sraghus 			    "==> nxge_n2_serdes_init port<%d>: loopback 0x%x",
16244977Sraghus 			    portn, test_cfg.value));
16254977Sraghus 			if ((status = nxge_mdio_write(nxgep, portn,
16264977Sraghus 			    ESR_N2_DEV_ADDR,
16274977Sraghus 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
16284977Sraghus 				goto fail;
16294977Sraghus 			}
16304977Sraghus 		}
16313859Sml29623 	} else {
16323859Sml29623 		goto fail;
16333859Sml29623 	}
16343859Sml29623 
16353859Sml29623 	/*   MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
16363859Sml29623 
16373859Sml29623 	NXGE_DELAY(20);
16383859Sml29623 
16393859Sml29623 	/* init TX channels */
16403859Sml29623 	for (chan = 0; chan < 4; chan++) {
16413859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16426929Smisaki 		    ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK)
16433859Sml29623 			goto fail;
16443859Sml29623 
16453859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16466929Smisaki 		    ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK)
16473859Sml29623 			goto fail;
16484977Sraghus 
16494977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16504977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x",
16514977Sraghus 		    portn, chan, tx_cfg_l.value));
16524977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16534977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x",
16544977Sraghus 		    portn, chan, tx_cfg_h.value));
16553859Sml29623 	}
16563859Sml29623 
16573859Sml29623 	/* init RX channels */
16583859Sml29623 	for (chan = 0; chan < 4; chan++) {
16593859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16606929Smisaki 		    ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) != NXGE_OK)
16613859Sml29623 			goto fail;
16623859Sml29623 
16633859Sml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16646929Smisaki 		    ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) != NXGE_OK)
16653859Sml29623 			goto fail;
16664977Sraghus 
16674977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16684977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x",
16694977Sraghus 		    portn, chan, rx_cfg_l.value));
16706835Syc148097 
16714977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16724977Sraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x",
16734977Sraghus 		    portn, chan, rx_cfg_h.value));
16743859Sml29623 	}
16753859Sml29623 
16763859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>",
16776929Smisaki 	    portn));
16783859Sml29623 
16793859Sml29623 	return (NXGE_OK);
16803859Sml29623 fail:
16815572Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16825572Ssbehera 	    "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
16835572Ssbehera 	    portn));
16843859Sml29623 
16853859Sml29623 	return (status);
168611304SJanie.Lu@Sun.COM 
168711304SJanie.Lu@Sun.COM }
168811304SJanie.Lu@Sun.COM 
168911304SJanie.Lu@Sun.COM /* Initialize the TI Hedwig Internal Serdes (N2-KT-NIU only) */
169011304SJanie.Lu@Sun.COM 
169111304SJanie.Lu@Sun.COM static nxge_status_t
nxge_n2_kt_serdes_init(p_nxge_t nxgep)169211304SJanie.Lu@Sun.COM nxge_n2_kt_serdes_init(p_nxge_t nxgep)
169311304SJanie.Lu@Sun.COM {
169411304SJanie.Lu@Sun.COM 	uint8_t portn;
169512103SSantwona.Behera@Sun.COM 	int chan, i;
169611304SJanie.Lu@Sun.COM 	k_esr_ti_cfgpll_l_t pll_cfg_l;
169711304SJanie.Lu@Sun.COM 	k_esr_ti_cfgrx_l_t rx_cfg_l;
169811304SJanie.Lu@Sun.COM 	k_esr_ti_cfgrx_h_t rx_cfg_h;
169911304SJanie.Lu@Sun.COM 	k_esr_ti_cfgtx_l_t tx_cfg_l;
170011304SJanie.Lu@Sun.COM 	k_esr_ti_cfgtx_h_t tx_cfg_h;
170111304SJanie.Lu@Sun.COM #ifdef NXGE_DEBUG
170211304SJanie.Lu@Sun.COM 	k_esr_ti_testcfg_t cfg;
170311304SJanie.Lu@Sun.COM #endif
170411304SJanie.Lu@Sun.COM 	k_esr_ti_testcfg_t test_cfg;
170511304SJanie.Lu@Sun.COM 	nxge_status_t status = NXGE_OK;
170611304SJanie.Lu@Sun.COM 	boolean_t mode_1g = B_FALSE;
170712103SSantwona.Behera@Sun.COM 	uint64_t val;
170812103SSantwona.Behera@Sun.COM 	npi_handle_t handle;
170911304SJanie.Lu@Sun.COM 
171011304SJanie.Lu@Sun.COM 	portn = nxgep->mac.portnum;
171111304SJanie.Lu@Sun.COM 
171211304SJanie.Lu@Sun.COM 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
171311304SJanie.Lu@Sun.COM 	    "==> nxge_n2_kt_serdes_init port<%d>", portn));
171412103SSantwona.Behera@Sun.COM 	handle = nxgep->npi_handle;
171511304SJanie.Lu@Sun.COM 
171611304SJanie.Lu@Sun.COM 	tx_cfg_l.value = 0;
171711304SJanie.Lu@Sun.COM 	tx_cfg_h.value = 0;
171811304SJanie.Lu@Sun.COM 	rx_cfg_l.value = 0;
171911304SJanie.Lu@Sun.COM 	rx_cfg_h.value = 0;
172011304SJanie.Lu@Sun.COM 	pll_cfg_l.value = 0;
172111304SJanie.Lu@Sun.COM 	test_cfg.value = 0;
172211304SJanie.Lu@Sun.COM 
172311304SJanie.Lu@Sun.COM 	/*
172411304SJanie.Lu@Sun.COM 	 * The following setting assumes the reference clock frquency
172511304SJanie.Lu@Sun.COM 	 * is 156.25 MHz.
172611304SJanie.Lu@Sun.COM 	 */
172711304SJanie.Lu@Sun.COM 	/*
172811304SJanie.Lu@Sun.COM 	 * If the nxge driver has been plumbed without a link, then it will
172911304SJanie.Lu@Sun.COM 	 * detect a link up when a cable connecting to an anto-negotiation
173011304SJanie.Lu@Sun.COM 	 * partner is plugged into the port. Because the TN1010 PHY supports
173111304SJanie.Lu@Sun.COM 	 * both 1G and 10G speeds, the driver must re-configure the
173211304SJanie.Lu@Sun.COM 	 * Neptune/NIU according to the negotiated speed.  nxge_n2_serdes_init
173311304SJanie.Lu@Sun.COM 	 * is called at the post-link-up reconfiguration time. Here it calls
173411304SJanie.Lu@Sun.COM 	 * nxge_set_tn1010_param to set portmode before re-initializing
173511304SJanie.Lu@Sun.COM 	 * the serdes.
173611304SJanie.Lu@Sun.COM 	 */
173711304SJanie.Lu@Sun.COM 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
173811304SJanie.Lu@Sun.COM 	    nxgep->mac.portmode == PORT_10G_TN1010) {
173911304SJanie.Lu@Sun.COM 		if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
174011304SJanie.Lu@Sun.COM 			goto fail;
174111304SJanie.Lu@Sun.COM 		}
174211304SJanie.Lu@Sun.COM 	}
174311304SJanie.Lu@Sun.COM 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
174412103SSantwona.Behera@Sun.COM 	    nxgep->mac.portmode == PORT_10G_COPPER ||
174511304SJanie.Lu@Sun.COM 	    nxgep->mac.portmode == PORT_10G_TN1010 ||
174611304SJanie.Lu@Sun.COM 	    nxgep->mac.portmode == PORT_10G_SERDES) {
1747*12452SSantwona.Behera@oracle.COM 
1748*12452SSantwona.Behera@oracle.COM 		/* Take tunables from OBP if present, otherwise use defaults */
1749*12452SSantwona.Behera@oracle.COM 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_TXCFGL) {
1750*12452SSantwona.Behera@oracle.COM 			tx_cfg_l.value = nxgep->srds_prop.tx_cfg_l;
1751*12452SSantwona.Behera@oracle.COM 		} else {
1752*12452SSantwona.Behera@oracle.COM 			tx_cfg_l.bits.entx = K_CFGTX_ENABLE_TX;
1753*12452SSantwona.Behera@oracle.COM 			/* 0x1e21 */
1754*12452SSantwona.Behera@oracle.COM 			tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
1755*12452SSantwona.Behera@oracle.COM 			tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF;
1756*12452SSantwona.Behera@oracle.COM 		}
175711304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
175811304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x",
175911304SJanie.Lu@Sun.COM 		    portn, tx_cfg_l.value));
176011304SJanie.Lu@Sun.COM 
1761*12452SSantwona.Behera@oracle.COM 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_TXCFGH) {
1762*12452SSantwona.Behera@oracle.COM 			tx_cfg_h.value = nxgep->srds_prop.tx_cfg_h;
1763*12452SSantwona.Behera@oracle.COM 		} else {
1764*12452SSantwona.Behera@oracle.COM 			/* channel 0: enable syn. master */
1765*12452SSantwona.Behera@oracle.COM 			/* 0x40 */
1766*12452SSantwona.Behera@oracle.COM 			tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC;
1767*12452SSantwona.Behera@oracle.COM 		}
176811304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
176911304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
177011304SJanie.Lu@Sun.COM 		    portn, tx_cfg_h.value));
1771*12452SSantwona.Behera@oracle.COM 
1772*12452SSantwona.Behera@oracle.COM 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_RXCFGL) {
1773*12452SSantwona.Behera@oracle.COM 			rx_cfg_l.value = nxgep->srds_prop.rx_cfg_l;
1774*12452SSantwona.Behera@oracle.COM 		} else {
1775*12452SSantwona.Behera@oracle.COM 			/* 0x4821 */
1776*12452SSantwona.Behera@oracle.COM 			rx_cfg_l.bits.enrx = K_CFGRX_ENABLE_RX;
1777*12452SSantwona.Behera@oracle.COM 			rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
1778*12452SSantwona.Behera@oracle.COM 			rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
1779*12452SSantwona.Behera@oracle.COM 			rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE;
1780*12452SSantwona.Behera@oracle.COM 		}
178111304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
178211304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x",
178311304SJanie.Lu@Sun.COM 		    portn, rx_cfg_l.value));
178411304SJanie.Lu@Sun.COM 
1785*12452SSantwona.Behera@oracle.COM 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_RXCFGH) {
1786*12452SSantwona.Behera@oracle.COM 			rx_cfg_h.value = nxgep->srds_prop.rx_cfg_h;
1787*12452SSantwona.Behera@oracle.COM 		} else {
1788*12452SSantwona.Behera@oracle.COM 			/* 0x0008 */
1789*12452SSantwona.Behera@oracle.COM 			rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE;
1790*12452SSantwona.Behera@oracle.COM 		}
179111304SJanie.Lu@Sun.COM 
179211304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
179311304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_h 0x%x",
179411304SJanie.Lu@Sun.COM 		    portn, rx_cfg_h.value));
179511304SJanie.Lu@Sun.COM 
1796*12452SSantwona.Behera@oracle.COM 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_PLLCFGL) {
1797*12452SSantwona.Behera@oracle.COM 			pll_cfg_l.value = nxgep->srds_prop.pll_cfg_l;
1798*12452SSantwona.Behera@oracle.COM 		} else {
1799*12452SSantwona.Behera@oracle.COM 			/* 0xa1: Initialize PLL for 10G */
1800*12452SSantwona.Behera@oracle.COM 			pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
1801*12452SSantwona.Behera@oracle.COM 			pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
1802*12452SSantwona.Behera@oracle.COM 		}
1803*12452SSantwona.Behera@oracle.COM 
1804*12452SSantwona.Behera@oracle.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1805*12452SSantwona.Behera@oracle.COM 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
1806*12452SSantwona.Behera@oracle.COM 		    portn, pll_cfg_l.value));
1807*12452SSantwona.Behera@oracle.COM 
1808*12452SSantwona.Behera@oracle.COM 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
1809*12452SSantwona.Behera@oracle.COM 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
1810*12452SSantwona.Behera@oracle.COM 			goto fail;
1811*12452SSantwona.Behera@oracle.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1812*12452SSantwona.Behera@oracle.COM 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
1813*12452SSantwona.Behera@oracle.COM 		    portn, pll_cfg_l.value));
1814*12452SSantwona.Behera@oracle.COM 
181511304SJanie.Lu@Sun.COM 		/* Set loopback mode if necessary */
181611304SJanie.Lu@Sun.COM 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
181711304SJanie.Lu@Sun.COM 			tx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK;
181811304SJanie.Lu@Sun.COM 			rx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK;
181911304SJanie.Lu@Sun.COM 			rx_cfg_l.bits.los = 0;
182011304SJanie.Lu@Sun.COM 
182111304SJanie.Lu@Sun.COM 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
182211304SJanie.Lu@Sun.COM 			    "==> nxge_n2_kt_serdes_init port<%d>: "
182311304SJanie.Lu@Sun.COM 			    "loopback 0x%x", portn, tx_cfg_h.value));
182411304SJanie.Lu@Sun.COM 		}
182511304SJanie.Lu@Sun.COM #ifdef  NXGE_DEBUG
182611304SJanie.Lu@Sun.COM 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
182711304SJanie.Lu@Sun.COM 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
182811304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
182911304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d>: "
183011304SJanie.Lu@Sun.COM 		    "PLL cfg.l 0x%x (0x%x)",
183111304SJanie.Lu@Sun.COM 		    portn, pll_cfg_l.value, cfg.value));
183211304SJanie.Lu@Sun.COM 
183311304SJanie.Lu@Sun.COM 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
183411304SJanie.Lu@Sun.COM 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
183511304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
183611304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)",
183711304SJanie.Lu@Sun.COM 		    portn, cfg.value));
183811304SJanie.Lu@Sun.COM #endif
183911304SJanie.Lu@Sun.COM 	} else if (nxgep->mac.portmode == PORT_1G_FIBER ||
184011304SJanie.Lu@Sun.COM 	    nxgep->mac.portmode == PORT_1G_TN1010 ||
184111304SJanie.Lu@Sun.COM 	    nxgep->mac.portmode == PORT_1G_SERDES) {
184211304SJanie.Lu@Sun.COM 		mode_1g = B_TRUE;
184311304SJanie.Lu@Sun.COM 		/* 0x1e41 */
184411304SJanie.Lu@Sun.COM 		tx_cfg_l.bits.entx = 1;
184511304SJanie.Lu@Sun.COM 		tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF;
184611304SJanie.Lu@Sun.COM 		tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
184711304SJanie.Lu@Sun.COM 
184811304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
184911304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x",
185011304SJanie.Lu@Sun.COM 		    portn, tx_cfg_l.value));
185111304SJanie.Lu@Sun.COM 
185211304SJanie.Lu@Sun.COM 
185311304SJanie.Lu@Sun.COM 		/* channel 0: enable syn. master */
185411304SJanie.Lu@Sun.COM 		tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC;
185511304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
185611304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
185711304SJanie.Lu@Sun.COM 		    portn, tx_cfg_h.value));
185811304SJanie.Lu@Sun.COM 
185911304SJanie.Lu@Sun.COM 
186011304SJanie.Lu@Sun.COM 		/* 0x4841 */
186111304SJanie.Lu@Sun.COM 		rx_cfg_l.bits.enrx = 1;
186211304SJanie.Lu@Sun.COM 		rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
186311304SJanie.Lu@Sun.COM 		rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
186411304SJanie.Lu@Sun.COM 		rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE;
186511304SJanie.Lu@Sun.COM 
186611304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
186711304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x",
186811304SJanie.Lu@Sun.COM 		    portn, rx_cfg_l.value));
186911304SJanie.Lu@Sun.COM 
187011304SJanie.Lu@Sun.COM 		/* 0x0008 */
187111304SJanie.Lu@Sun.COM 		rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE_LF_365MHZ_ZF;
187211304SJanie.Lu@Sun.COM 
187311304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
187411304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
187511304SJanie.Lu@Sun.COM 		    portn, rx_cfg_h.value));
187611304SJanie.Lu@Sun.COM 
187711304SJanie.Lu@Sun.COM 		/* 0xa1: Initialize PLL for 1G */
187811304SJanie.Lu@Sun.COM 		pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
187911304SJanie.Lu@Sun.COM 		pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
188011304SJanie.Lu@Sun.COM 
188111304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
188211304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
188311304SJanie.Lu@Sun.COM 		    portn, pll_cfg_l.value));
188411304SJanie.Lu@Sun.COM 
188511304SJanie.Lu@Sun.COM 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
188611304SJanie.Lu@Sun.COM 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value))
188711304SJanie.Lu@Sun.COM 		    != NXGE_OK)
188811304SJanie.Lu@Sun.COM 			goto fail;
188911304SJanie.Lu@Sun.COM 
189011304SJanie.Lu@Sun.COM 
189111304SJanie.Lu@Sun.COM #ifdef  NXGE_DEBUG
189211304SJanie.Lu@Sun.COM 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
189311304SJanie.Lu@Sun.COM 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
189411304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
189511304SJanie.Lu@Sun.COM 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
189611304SJanie.Lu@Sun.COM 		    portn, pll_cfg_l.value, cfg.value));
189711304SJanie.Lu@Sun.COM 
189811304SJanie.Lu@Sun.COM 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
189911304SJanie.Lu@Sun.COM 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
190011304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
190111304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)",
190211304SJanie.Lu@Sun.COM 		    portn, cfg.value));
190311304SJanie.Lu@Sun.COM #endif
190411304SJanie.Lu@Sun.COM 
190511304SJanie.Lu@Sun.COM 		/* Set loopback mode if necessary */
190611304SJanie.Lu@Sun.COM 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
190711304SJanie.Lu@Sun.COM 			tx_cfg_h.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
190811304SJanie.Lu@Sun.COM 
190911304SJanie.Lu@Sun.COM 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
191011304SJanie.Lu@Sun.COM 			    "==> nxge_n2_kt_serdes_init port<%d>: "
191111304SJanie.Lu@Sun.COM 			    "loopback 0x%x", portn, test_cfg.value));
191211304SJanie.Lu@Sun.COM 			if ((status = nxge_mdio_write(nxgep, portn,
191311304SJanie.Lu@Sun.COM 			    ESR_N2_DEV_ADDR,
191411304SJanie.Lu@Sun.COM 			    ESR_N2_TX_CFG_L_REG_ADDR(0),
191511304SJanie.Lu@Sun.COM 			    tx_cfg_h.value)) != NXGE_OK) {
191611304SJanie.Lu@Sun.COM 				goto fail;
191711304SJanie.Lu@Sun.COM 			}
191811304SJanie.Lu@Sun.COM 		}
191911304SJanie.Lu@Sun.COM 	} else {
192011304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
192111304SJanie.Lu@Sun.COM 		    "nxge_n2_kt_serdes_init:port<%d> - "
192211304SJanie.Lu@Sun.COM 		    "unsupported port mode %d",
192311304SJanie.Lu@Sun.COM 		    portn, nxgep->mac.portmode));
192411304SJanie.Lu@Sun.COM 		goto fail;
192511304SJanie.Lu@Sun.COM 	}
192611304SJanie.Lu@Sun.COM 
192711304SJanie.Lu@Sun.COM 	NXGE_DELAY(20);
192811304SJanie.Lu@Sun.COM 	/* Clear the test register (offset 0x8004) */
192911304SJanie.Lu@Sun.COM 	if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
193011304SJanie.Lu@Sun.COM 	    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
193111304SJanie.Lu@Sun.COM 		goto fail;
193211304SJanie.Lu@Sun.COM 	}
193311304SJanie.Lu@Sun.COM 	NXGE_DELAY(20);
193411304SJanie.Lu@Sun.COM 
193511304SJanie.Lu@Sun.COM 	/* init TX channels */
193611304SJanie.Lu@Sun.COM 	for (chan = 0; chan < 4; chan++) {
193711304SJanie.Lu@Sun.COM 		if (mode_1g)
193811304SJanie.Lu@Sun.COM 			tx_cfg_l.value = 0;
193911304SJanie.Lu@Sun.COM 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
194011304SJanie.Lu@Sun.COM 		    ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK)
194111304SJanie.Lu@Sun.COM 			goto fail;
194211304SJanie.Lu@Sun.COM 
194311304SJanie.Lu@Sun.COM 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
194411304SJanie.Lu@Sun.COM 		    ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK)
194511304SJanie.Lu@Sun.COM 			goto fail;
194611304SJanie.Lu@Sun.COM 
194711304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
194811304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d>: "
194911304SJanie.Lu@Sun.COM 		    "chan %d tx_cfg_l 0x%x", portn, chan, tx_cfg_l.value));
195011304SJanie.Lu@Sun.COM 
195111304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
195211304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d>: "
195311304SJanie.Lu@Sun.COM 		    "chan %d tx_cfg_h 0x%x", portn, chan, tx_cfg_h.value));
195411304SJanie.Lu@Sun.COM 	}
195511304SJanie.Lu@Sun.COM 
195611304SJanie.Lu@Sun.COM 	/* init RX channels */
195711304SJanie.Lu@Sun.COM 	/* 1G mode only write to the first channel */
195811304SJanie.Lu@Sun.COM 	for (chan = 0; chan < 4; chan++) {
195911304SJanie.Lu@Sun.COM 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
196011304SJanie.Lu@Sun.COM 		    ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value))
196111304SJanie.Lu@Sun.COM 		    != NXGE_OK)
196211304SJanie.Lu@Sun.COM 			goto fail;
196311304SJanie.Lu@Sun.COM 
196411304SJanie.Lu@Sun.COM 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
196511304SJanie.Lu@Sun.COM 		    ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value))
196611304SJanie.Lu@Sun.COM 		    != NXGE_OK)
196711304SJanie.Lu@Sun.COM 			goto fail;
196811304SJanie.Lu@Sun.COM 
196911304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
197011304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d>: "
197111304SJanie.Lu@Sun.COM 		    "chan %d rx_cfg_l 0x%x", portn, chan, rx_cfg_l.value));
197211304SJanie.Lu@Sun.COM 
197311304SJanie.Lu@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
197411304SJanie.Lu@Sun.COM 		    "==> nxge_n2_kt_serdes_init port<%d>: "
197511304SJanie.Lu@Sun.COM 		    "chan %d rx_cfg_h 0x%x", portn, chan, rx_cfg_h.value));
197611304SJanie.Lu@Sun.COM 	}
197711304SJanie.Lu@Sun.COM 
197812103SSantwona.Behera@Sun.COM 	if (portn == 0) {
197912103SSantwona.Behera@Sun.COM 		/* Wait for serdes to be ready */
198012103SSantwona.Behera@Sun.COM 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
198112103SSantwona.Behera@Sun.COM 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
198212103SSantwona.Behera@Sun.COM 			if ((val & ESR_SIG_P0_BITS_MASK) !=
198312103SSantwona.Behera@Sun.COM 			    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
198412103SSantwona.Behera@Sun.COM 			    ESR_SIG_XSERDES_RDY_P0 |
198512103SSantwona.Behera@Sun.COM 			    ESR_SIG_XDETECT_P0_CH3 |
198612103SSantwona.Behera@Sun.COM 			    ESR_SIG_XDETECT_P0_CH2 |
198712103SSantwona.Behera@Sun.COM 			    ESR_SIG_XDETECT_P0_CH1 |
198812103SSantwona.Behera@Sun.COM 			    ESR_SIG_XDETECT_P0_CH0))
198912103SSantwona.Behera@Sun.COM 
199012103SSantwona.Behera@Sun.COM 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
199112103SSantwona.Behera@Sun.COM 			else
199212103SSantwona.Behera@Sun.COM 				break;
199312103SSantwona.Behera@Sun.COM 		}
199412103SSantwona.Behera@Sun.COM 
199512103SSantwona.Behera@Sun.COM 		if (i == MAX_SERDES_RDY_RETRIES) {
199612103SSantwona.Behera@Sun.COM 			/*
199712103SSantwona.Behera@Sun.COM 			 * RDY signal stays low may due to the absent of the
199812103SSantwona.Behera@Sun.COM 			 * external PHY, it is not an error condition.
199912103SSantwona.Behera@Sun.COM 			 * But still print the message for the debugging
200012103SSantwona.Behera@Sun.COM 			 * purpose when link stays down
200112103SSantwona.Behera@Sun.COM 			 */
200212103SSantwona.Behera@Sun.COM 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
200312103SSantwona.Behera@Sun.COM 			    "nxge_n2_kt_serdes_init: "
200412103SSantwona.Behera@Sun.COM 			    "Serdes/signal for port<%d> not ready", portn));
200512103SSantwona.Behera@Sun.COM 				goto done;
200612103SSantwona.Behera@Sun.COM 		}
200712103SSantwona.Behera@Sun.COM 	} else if (portn == 1) {
200812103SSantwona.Behera@Sun.COM 		/* Wait for serdes to be ready */
200912103SSantwona.Behera@Sun.COM 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
201012103SSantwona.Behera@Sun.COM 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
201112103SSantwona.Behera@Sun.COM 			if ((val & ESR_SIG_P1_BITS_MASK) !=
201212103SSantwona.Behera@Sun.COM 			    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
201312103SSantwona.Behera@Sun.COM 			    ESR_SIG_XSERDES_RDY_P1 |
201412103SSantwona.Behera@Sun.COM 			    ESR_SIG_XDETECT_P1_CH3 |
201512103SSantwona.Behera@Sun.COM 			    ESR_SIG_XDETECT_P1_CH2 |
201612103SSantwona.Behera@Sun.COM 			    ESR_SIG_XDETECT_P1_CH1 |
201712103SSantwona.Behera@Sun.COM 			    ESR_SIG_XDETECT_P1_CH0))
201812103SSantwona.Behera@Sun.COM 
201912103SSantwona.Behera@Sun.COM 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
202012103SSantwona.Behera@Sun.COM 			else
202112103SSantwona.Behera@Sun.COM 				break;
202212103SSantwona.Behera@Sun.COM 		}
202312103SSantwona.Behera@Sun.COM 
202412103SSantwona.Behera@Sun.COM 		if (i == MAX_SERDES_RDY_RETRIES) {
202512103SSantwona.Behera@Sun.COM 			/*
202612103SSantwona.Behera@Sun.COM 			 * RDY signal stays low may due to the absent of the
202712103SSantwona.Behera@Sun.COM 			 * external PHY, it is not an error condition.
202812103SSantwona.Behera@Sun.COM 			 * But still print the message for the debugging
202912103SSantwona.Behera@Sun.COM 			 * purpose when link stays down
203012103SSantwona.Behera@Sun.COM 			 */
203112103SSantwona.Behera@Sun.COM 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
203212103SSantwona.Behera@Sun.COM 			    "nxge_n2_kt_serdes_init: "
203312103SSantwona.Behera@Sun.COM 			    "Serdes/signal for port<%d> not ready", portn));
203412103SSantwona.Behera@Sun.COM 				goto done;
203512103SSantwona.Behera@Sun.COM 		}
203612103SSantwona.Behera@Sun.COM 	}
203712103SSantwona.Behera@Sun.COM done:
203812103SSantwona.Behera@Sun.COM 
203911304SJanie.Lu@Sun.COM 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
204011304SJanie.Lu@Sun.COM 	    "<== nxge_n2_kt_serdes_init port<%d>", portn));
204111304SJanie.Lu@Sun.COM 
204211304SJanie.Lu@Sun.COM 	return (NXGE_OK);
204311304SJanie.Lu@Sun.COM fail:
204411304SJanie.Lu@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
204511304SJanie.Lu@Sun.COM 	    "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
204611304SJanie.Lu@Sun.COM 	    portn));
204711304SJanie.Lu@Sun.COM 
204811304SJanie.Lu@Sun.COM 	return (status);
20493859Sml29623 }
20503859Sml29623 
20514732Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
20524732Sdavemq 
20534732Sdavemq static nxge_status_t
nxge_neptune_10G_serdes_init(p_nxge_t nxgep)20544732Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep)
20553859Sml29623 {
20563859Sml29623 	npi_handle_t		handle;
20573859Sml29623 	uint8_t			portn;
20586075Ssbehera 	int			chan, i;
20593859Sml29623 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
20603859Sml29623 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
20613859Sml29623 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
20623859Sml29623 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
20633859Sml29623 	uint64_t		val;
20643859Sml29623 	uint16_t		val16l;
20653859Sml29623 	uint16_t		val16h;
20663859Sml29623 	nxge_status_t		status = NXGE_OK;
20673859Sml29623 
20683859Sml29623 	portn = nxgep->mac.portnum;
20693859Sml29623 
20703859Sml29623 	if ((portn != 0) && (portn != 1))
20713859Sml29623 		return (NXGE_OK);
20723859Sml29623 
20734732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
20744732Sdavemq 	    "==> nxge_neptune_10G_serdes_init port<%d>", portn));
20753859Sml29623 	handle = nxgep->npi_handle;
20764732Sdavemq 	switch (portn) {
20774732Sdavemq 	case 0:
20786028Ssbehera 		/* Reset Serdes */
20796028Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0);
20806028Ssbehera 		NXGE_DELAY(20);
20816028Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
20826028Ssbehera 		NXGE_DELAY(2000);
20836028Ssbehera 
20846028Ssbehera 		/* Configure Serdes to 10G mode */
20856028Ssbehera 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
20866028Ssbehera 		    ESR_PLL_CFG_10G_SERDES);
20876028Ssbehera 
20884732Sdavemq 		ESR_REG_WR(handle, ESR_0_CONTROL_REG,
20894732Sdavemq 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
20904732Sdavemq 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
20914732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
20924732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
20934732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
20944732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
20954732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
20964732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
20974732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
20984732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
20994732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
21004732Sdavemq 
21014732Sdavemq 		/* Set Serdes0 Internal Loopback if necessary */
21024732Sdavemq 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
21034732Sdavemq 			ESR_REG_WR(handle,
21044732Sdavemq 			    ESR_0_TEST_CONFIG_REG,
21054732Sdavemq 			    ESR_PAD_LOOPBACK_CH3 |
21064732Sdavemq 			    ESR_PAD_LOOPBACK_CH2 |
21074732Sdavemq 			    ESR_PAD_LOOPBACK_CH1 |
21084732Sdavemq 			    ESR_PAD_LOOPBACK_CH0);
21094732Sdavemq 		} else {
21104732Sdavemq 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
21113859Sml29623 		}
21124732Sdavemq 		break;
21134732Sdavemq 	case 1:
21146028Ssbehera 		/* Reset Serdes */
21156028Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_1);
21166028Ssbehera 		NXGE_DELAY(20);
21176028Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
21186028Ssbehera 		NXGE_DELAY(2000);
21196028Ssbehera 
21206028Ssbehera 		/* Configure Serdes to 10G mode */
21216028Ssbehera 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
21226028Ssbehera 		    ESR_PLL_CFG_10G_SERDES);
21236028Ssbehera 
21244732Sdavemq 		ESR_REG_WR(handle, ESR_1_CONTROL_REG,
21254732Sdavemq 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
21264732Sdavemq 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
21274732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
21284732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
21294732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
21304732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
21314732Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
21324732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
21334732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
21344732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
21354732Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
21364732Sdavemq 
21374732Sdavemq 		/* Set Serdes1 Internal Loopback if necessary */
21384732Sdavemq 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
21394732Sdavemq 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
21404732Sdavemq 			    ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 |
21414732Sdavemq 			    ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0);
21424732Sdavemq 		} else {
21434732Sdavemq 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
21443859Sml29623 		}
21454732Sdavemq 		break;
21464732Sdavemq 	default:
21474732Sdavemq 		/* Nothing to do here */
21484732Sdavemq 		goto done;
21494732Sdavemq 	}
21504732Sdavemq 
21514732Sdavemq 	/* init TX RX channels */
21524732Sdavemq 	for (chan = 0; chan < 4; chan++) {
21534732Sdavemq 		if ((status = nxge_mdio_read(nxgep, portn,
21544732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
21554732Sdavemq 		    &rx_tx_ctrl_l.value)) != NXGE_OK)
21563859Sml29623 			goto fail;
21574732Sdavemq 		if ((status = nxge_mdio_read(nxgep, portn,
21584732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
21594732Sdavemq 		    &rx_tx_ctrl_h.value)) != NXGE_OK)
21603859Sml29623 			goto fail;
21613859Sml29623 		if ((status = nxge_mdio_read(nxgep, portn,
21624732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
21634732Sdavemq 		    &glue_ctrl0_l.value)) != NXGE_OK)
21643859Sml29623 			goto fail;
21653859Sml29623 		if ((status = nxge_mdio_read(nxgep, portn,
21664732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
21674732Sdavemq 		    &glue_ctrl0_h.value)) != NXGE_OK)
21684732Sdavemq 			goto fail;
21694732Sdavemq 		rx_tx_ctrl_l.bits.enstretch = 1;
21704732Sdavemq 		rx_tx_ctrl_h.bits.vmuxlo = 2;
21714732Sdavemq 		rx_tx_ctrl_h.bits.vpulselo = 2;
21724732Sdavemq 		glue_ctrl0_l.bits.rxlosenable = 1;
21734732Sdavemq 		glue_ctrl0_l.bits.samplerate = 0xF;
21744732Sdavemq 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
21754732Sdavemq 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
21764732Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
21774732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
21784732Sdavemq 		    rx_tx_ctrl_l.value)) != NXGE_OK)
21794732Sdavemq 			goto fail;
21804732Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
21814732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
21824732Sdavemq 		    rx_tx_ctrl_h.value)) != NXGE_OK)
21834732Sdavemq 			goto fail;
21844732Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
21854732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
21864732Sdavemq 		    glue_ctrl0_l.value)) != NXGE_OK)
21874732Sdavemq 			goto fail;
21884732Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
21894732Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
21904732Sdavemq 		    glue_ctrl0_h.value)) != NXGE_OK)
21913859Sml29623 			goto fail;
21923859Sml29623 		}
21933859Sml29623 
21944732Sdavemq 	/* Apply Tx core reset */
21954732Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn,
21964732Sdavemq 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
21974732Sdavemq 	    (uint16_t)0)) != NXGE_OK)
21984732Sdavemq 		goto fail;
21994732Sdavemq 
22004732Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
22014732Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
22024732Sdavemq 	    NXGE_OK)
22034732Sdavemq 		goto fail;
22044732Sdavemq 
22054732Sdavemq 	NXGE_DELAY(200);
22064732Sdavemq 
22074732Sdavemq 	/* Apply Rx core reset */
22084732Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
22094732Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
22104732Sdavemq 	    NXGE_OK)
22114732Sdavemq 		goto fail;
22124732Sdavemq 
22134732Sdavemq 	NXGE_DELAY(200);
22144732Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
22154732Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK)
22164732Sdavemq 		goto fail;
22174732Sdavemq 
22184732Sdavemq 	NXGE_DELAY(200);
22194732Sdavemq 	if ((status = nxge_mdio_read(nxgep, portn,
22204732Sdavemq 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
22214732Sdavemq 	    &val16l)) != NXGE_OK)
22224732Sdavemq 		goto fail;
22234732Sdavemq 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
22244732Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK)
22254732Sdavemq 		goto fail;
22264732Sdavemq 	if ((val16l != 0) || (val16h != 0)) {
22274732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
22285196Ssbehera 		    "Failed to reset port<%d> XAUI Serdes "
22295196Ssbehera 		    "(val16l 0x%x val16h 0x%x)",
22305196Ssbehera 		    portn, val16l, val16h));
22314732Sdavemq 	}
22324732Sdavemq 
22334732Sdavemq 	if (portn == 0) {
22346075Ssbehera 		/* Wait for serdes to be ready */
22356075Ssbehera 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
22366075Ssbehera 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
22376075Ssbehera 			if ((val & ESR_SIG_P0_BITS_MASK) !=
22386075Ssbehera 			    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
22396075Ssbehera 			    ESR_SIG_XSERDES_RDY_P0 |
22406075Ssbehera 			    ESR_SIG_XDETECT_P0_CH3 |
22416075Ssbehera 			    ESR_SIG_XDETECT_P0_CH2 |
22426075Ssbehera 			    ESR_SIG_XDETECT_P0_CH1 |
22436075Ssbehera 			    ESR_SIG_XDETECT_P0_CH0))
22446075Ssbehera 
22456075Ssbehera 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
22466075Ssbehera 			else
22476075Ssbehera 				break;
22486075Ssbehera 		}
22496075Ssbehera 
22506075Ssbehera 		if (i == MAX_SERDES_RDY_RETRIES) {
22516650Sjoycey 			/*
22526650Sjoycey 			 * RDY signal stays low may due to the absent of the
22536650Sjoycey 			 * external PHY, it is not an error condition. But still
22546650Sjoycey 			 * print the message for the debugging purpose when link
22556650Sjoycey 			 * stays down
22566650Sjoycey 			 */
225711409Stc99174@train 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
22586075Ssbehera 			    "nxge_neptune_10G_serdes_init: "
22596075Ssbehera 			    "Serdes/signal for port<%d> not ready", portn));
22606835Syc148097 				goto done;
22614732Sdavemq 		}
22624732Sdavemq 	} else if (portn == 1) {
22636075Ssbehera 		/* Wait for serdes to be ready */
22646075Ssbehera 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
22656075Ssbehera 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
22666075Ssbehera 			if ((val & ESR_SIG_P1_BITS_MASK) !=
22676075Ssbehera 			    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
22686075Ssbehera 			    ESR_SIG_XSERDES_RDY_P1 |
22696075Ssbehera 			    ESR_SIG_XDETECT_P1_CH3 |
22706075Ssbehera 			    ESR_SIG_XDETECT_P1_CH2 |
22716075Ssbehera 			    ESR_SIG_XDETECT_P1_CH1 |
22726075Ssbehera 			    ESR_SIG_XDETECT_P1_CH0))
22736075Ssbehera 
22746075Ssbehera 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
22756075Ssbehera 			else
22766075Ssbehera 				break;
22776075Ssbehera 		}
22786075Ssbehera 
22796075Ssbehera 		if (i == MAX_SERDES_RDY_RETRIES) {
22806650Sjoycey 			/*
22816650Sjoycey 			 * RDY signal stays low may due to the absent of the
22826650Sjoycey 			 * external PHY, it is not an error condition. But still
22836650Sjoycey 			 * print the message for the debugging purpose when link
22846650Sjoycey 			 * stays down
22856650Sjoycey 			 */
228611409Stc99174@train 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
22876075Ssbehera 			    "nxge_neptune_10G_serdes_init: "
22886075Ssbehera 			    "Serdes/signal for port<%d> not ready", portn));
22896835Syc148097 				goto done;
22903859Sml29623 		}
22913859Sml29623 	}
22923859Sml29623 
22933859Sml29623 done:
22944732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
22954732Sdavemq 	    "<== nxge_neptune_10G_serdes_init port<%d>", portn));
22964732Sdavemq 
22973859Sml29623 	return (NXGE_OK);
22983859Sml29623 fail:
22995572Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
23004732Sdavemq 	    "nxge_neptune_10G_serdes_init: "
23014732Sdavemq 	    "Failed to initialize Neptune serdes for port<%d>", portn));
23023859Sml29623 
23033859Sml29623 	return (status);
23043859Sml29623 }
23053859Sml29623 
23064732Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */
23074732Sdavemq 
23084732Sdavemq static nxge_status_t
nxge_1G_serdes_init(p_nxge_t nxgep)23094732Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep)
23103859Sml29623 {
23114732Sdavemq 	npi_handle_t		handle;
23124732Sdavemq 	uint8_t			portn;
23135196Ssbehera 	int			chan;
23145196Ssbehera 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
23155196Ssbehera 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
23165196Ssbehera 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
23175196Ssbehera 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
23184732Sdavemq 	uint64_t		val;
23195196Ssbehera 	uint16_t		val16l;
23205196Ssbehera 	uint16_t		val16h;
23215196Ssbehera 	nxge_status_t		status = NXGE_OK;
23223859Sml29623 
23233859Sml29623 	portn = nxgep->mac.portnum;
23244732Sdavemq 
23254732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
23264732Sdavemq 	    "==> nxge_1G_serdes_init port<%d>", portn));
23274732Sdavemq 
23284732Sdavemq 	handle = nxgep->npi_handle;
23294732Sdavemq 
23304732Sdavemq 	switch (portn) {
23314732Sdavemq 	case 0:
23325196Ssbehera 		/* Assert the reset register */
23335196Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
23345196Ssbehera 		val |= ESR_RESET_0;
23355196Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
23365196Ssbehera 
23375196Ssbehera 		/* Set the PLL register to 0x79 */
23385196Ssbehera 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
23395196Ssbehera 		    ESR_PLL_CFG_1G_SERDES);
23405196Ssbehera 
23415196Ssbehera 		/* Set the control register to 0x249249f */
23425196Ssbehera 		ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES);
23435196Ssbehera 
23445196Ssbehera 		/* Set Serdes0 Internal Loopback if necessary */
23455196Ssbehera 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
23465196Ssbehera 			/* Set pad loopback modes 0xaa */
23475196Ssbehera 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG,
23485196Ssbehera 			    ESR_TSTCFG_LBTEST_PAD);
23495196Ssbehera 		} else {
23505196Ssbehera 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
23515196Ssbehera 		}
23525196Ssbehera 
23535196Ssbehera 		/* Deassert the reset register */
23545196Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
23555196Ssbehera 		val &= ~ESR_RESET_0;
23565196Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
23574732Sdavemq 		break;
23585196Ssbehera 
23594732Sdavemq 	case 1:
23605196Ssbehera 		/* Assert the reset register */
23615196Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
23625196Ssbehera 		val |= ESR_RESET_1;
23635196Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
23645196Ssbehera 
23655196Ssbehera 		/* Set PLL register to 0x79 */
23665196Ssbehera 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
23675196Ssbehera 		    ESR_PLL_CFG_1G_SERDES);
23685196Ssbehera 
23695196Ssbehera 		/* Set the control register to 0x249249f */
23705196Ssbehera 		ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES);
23715196Ssbehera 
23725196Ssbehera 		/* Set Serdes1 Internal Loopback if necessary */
23735196Ssbehera 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
23745196Ssbehera 			/* Set pad loopback mode 0xaa */
23755196Ssbehera 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
23765196Ssbehera 			    ESR_TSTCFG_LBTEST_PAD);
23775196Ssbehera 		} else {
23785196Ssbehera 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
23795196Ssbehera 		}
23805196Ssbehera 
23815196Ssbehera 		/* Deassert the reset register */
23825196Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
23835196Ssbehera 		val &= ~ESR_RESET_1;
23845196Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
23854732Sdavemq 		break;
23865196Ssbehera 
23874732Sdavemq 	default:
23885196Ssbehera 		/* Nothing to do here */
23895196Ssbehera 		goto done;
23905196Ssbehera 	}
23915196Ssbehera 
23925196Ssbehera 	/* init TX RX channels */
23935196Ssbehera 	for (chan = 0; chan < 4; chan++) {
23945196Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
23955196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
23965196Ssbehera 		    &rx_tx_ctrl_l.value)) != NXGE_OK) {
23975196Ssbehera 			goto fail;
23985196Ssbehera 		}
23995196Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
24005196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
24015196Ssbehera 		    &rx_tx_ctrl_h.value)) != NXGE_OK) {
24025196Ssbehera 			goto fail;
24035196Ssbehera 		}
24045196Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
24055196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
24065196Ssbehera 		    &glue_ctrl0_l.value)) != NXGE_OK) {
24075196Ssbehera 			goto fail;
24085196Ssbehera 		}
24095196Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
24105196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
24115196Ssbehera 		    &glue_ctrl0_h.value)) != NXGE_OK) {
24125196Ssbehera 			goto fail;
24135196Ssbehera 		}
24145196Ssbehera 
24155196Ssbehera 		rx_tx_ctrl_l.bits.enstretch = 1;
24165196Ssbehera 		rx_tx_ctrl_h.bits.vmuxlo = 2;
24175196Ssbehera 		rx_tx_ctrl_h.bits.vpulselo = 2;
24185196Ssbehera 		glue_ctrl0_l.bits.rxlosenable = 1;
24195196Ssbehera 		glue_ctrl0_l.bits.samplerate = 0xF;
24205196Ssbehera 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
24215196Ssbehera 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
24225196Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
24235196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
24245196Ssbehera 		    rx_tx_ctrl_l.value)) != NXGE_OK) {
24255196Ssbehera 			goto fail;
24265196Ssbehera 		}
24275196Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
24285196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
24295196Ssbehera 		    rx_tx_ctrl_h.value)) != NXGE_OK) {
24305196Ssbehera 			goto fail;
24315196Ssbehera 		}
24325196Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
24335196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
24345196Ssbehera 		    glue_ctrl0_l.value)) != NXGE_OK) {
24355196Ssbehera 			goto fail;
24365196Ssbehera 		}
24375196Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
24385196Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
24395196Ssbehera 		    glue_ctrl0_h.value)) != NXGE_OK) {
24405196Ssbehera 			goto fail;
24415196Ssbehera 		}
24425196Ssbehera 	}
24435196Ssbehera 
24445196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24455196Ssbehera 	    ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) {
24464732Sdavemq 		goto fail;
24473859Sml29623 	}
24485196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24495196Ssbehera 	    ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
24505196Ssbehera 		goto fail;
24515196Ssbehera 	}
24525196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24535196Ssbehera 	    ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) {
24545196Ssbehera 		goto fail;
24555196Ssbehera 	}
24565196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24575196Ssbehera 	    ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
24585196Ssbehera 		goto fail;
24595196Ssbehera 	}
24605196Ssbehera 
24615196Ssbehera 	/* Apply Tx core reset */
24625196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24635196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) {
24645196Ssbehera 		goto fail;
24655196Ssbehera 	}
24665196Ssbehera 
24675196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24685196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
24695196Ssbehera 	    NXGE_OK) {
24705196Ssbehera 		goto fail;
24715196Ssbehera 	}
24725196Ssbehera 
24735196Ssbehera 	NXGE_DELAY(200);
24745196Ssbehera 
24755196Ssbehera 	/* Apply Rx core reset */
24765196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24775196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
24785196Ssbehera 	    NXGE_OK) {
24795196Ssbehera 		goto fail;
24805196Ssbehera 	}
24815196Ssbehera 
24825196Ssbehera 	NXGE_DELAY(200);
24835196Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24845196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) {
24855196Ssbehera 		goto fail;
24865196Ssbehera 	}
24875196Ssbehera 
24885196Ssbehera 	NXGE_DELAY(200);
24895196Ssbehera 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24905196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) {
24915196Ssbehera 		goto fail;
24925196Ssbehera 	}
24935196Ssbehera 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24945196Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) {
24955196Ssbehera 		goto fail;
24965196Ssbehera 	}
24975196Ssbehera 	if ((val16l != 0) || (val16h != 0)) {
24985196Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
24995196Ssbehera 		    "Failed to reset port<%d> XAUI Serdes "
25005196Ssbehera 		    "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h));
25015196Ssbehera 		status = NXGE_ERROR;
25025196Ssbehera 		goto fail;
25035196Ssbehera 	}
25045196Ssbehera 
25055196Ssbehera 	NXGE_DELAY(200);
25065196Ssbehera 	ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
25075196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
25085196Ssbehera 	    "nxge_neptune_serdes_init: read internal signal reg port<%d> "
25095196Ssbehera 	    "val 0x%x", portn, val));
25105196Ssbehera 	if (portn == 0) {
25115196Ssbehera 		if ((val & ESR_SIG_P0_BITS_MASK_1G) !=
25125196Ssbehera 		    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) {
25136650Sjoycey 			/*
25146650Sjoycey 			 * RDY signal stays low may due to the absent of the
25156650Sjoycey 			 * external PHY, it is not an error condition. But still
25166650Sjoycey 			 * print the message for the debugging purpose when link
25176650Sjoycey 			 * stays down
25186650Sjoycey 			 */
25195196Ssbehera 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25206650Sjoycey 			    "nxge_neptune_1G_serdes_init: "
25216650Sjoycey 			    "Serdes/signal for port<%d> not ready", portn));
25226835Syc148097 				goto done;
25235196Ssbehera 		}
25245196Ssbehera 	} else if (portn == 1) {
25255196Ssbehera 		if ((val & ESR_SIG_P1_BITS_MASK_1G) !=
25265196Ssbehera 		    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) {
25276650Sjoycey 			/*
25286650Sjoycey 			 * RDY signal stays low may due to the absent of the
25296650Sjoycey 			 * external PHY, it is not an error condition. But still
25306650Sjoycey 			 * print the message for the debugging purpose when link
25316650Sjoycey 			 * stays down
25326650Sjoycey 			 */
25335196Ssbehera 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25346650Sjoycey 			    "nxge_neptune_1G_serdes_init: "
25356650Sjoycey 			    "Serdes/signal for port<%d> not ready", portn));
25366835Syc148097 				goto done;
25376835Syc148097 
25385196Ssbehera 		}
25395196Ssbehera 	}
25405196Ssbehera done:
25414732Sdavemq 
25424732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
25434732Sdavemq 	    "<== nxge_1G_serdes_init port<%d>", portn));
25443859Sml29623 	return (NXGE_OK);
25454732Sdavemq fail:
25465196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25474732Sdavemq 	    "nxge_1G_serdes_init: "
25484732Sdavemq 	    "Failed to initialize Neptune serdes for port<%d>",
25494732Sdavemq 	    portn));
25504732Sdavemq 
25515196Ssbehera 	return (status);
25523859Sml29623 }
25533859Sml29623 
2554*12452SSantwona.Behera@oracle.COM #define	NXGE_SET_PHY_TUNABLES(nxgep, phy_port, stat)			\
2555*12452SSantwona.Behera@oracle.COM {									\
2556*12452SSantwona.Behera@oracle.COM 	int i;								\
2557*12452SSantwona.Behera@oracle.COM 									\
2558*12452SSantwona.Behera@oracle.COM 	if (nxgep->phy_prop.cnt > 0) {					\
2559*12452SSantwona.Behera@oracle.COM 		for (i = 0; i < nxgep->phy_prop.cnt; i++) {		\
2560*12452SSantwona.Behera@oracle.COM 			if ((stat = nxge_mdio_write(nxgep, phy_port,	\
2561*12452SSantwona.Behera@oracle.COM 			    nxgep->phy_prop.arr[i].dev,			\
2562*12452SSantwona.Behera@oracle.COM 			    nxgep->phy_prop.arr[i].reg,			\
2563*12452SSantwona.Behera@oracle.COM 			    nxgep->phy_prop.arr[i].val)) != NXGE_OK) {	\
2564*12452SSantwona.Behera@oracle.COM 				break;					\
2565*12452SSantwona.Behera@oracle.COM 			}						\
2566*12452SSantwona.Behera@oracle.COM 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,			\
2567*12452SSantwona.Behera@oracle.COM 			    "From OBP, write<dev.reg.val> = "		\
2568*12452SSantwona.Behera@oracle.COM 			    "<0x%x.0x%x.0x%x>",				\
2569*12452SSantwona.Behera@oracle.COM 			    nxgep->phy_prop.arr[i].dev,			\
2570*12452SSantwona.Behera@oracle.COM 			    nxgep->phy_prop.arr[i].reg,			\
2571*12452SSantwona.Behera@oracle.COM 			    nxgep->phy_prop.arr[i].val));		\
2572*12452SSantwona.Behera@oracle.COM 		}							\
2573*12452SSantwona.Behera@oracle.COM 	}								\
2574*12452SSantwona.Behera@oracle.COM }
2575*12452SSantwona.Behera@oracle.COM 
25765572Ssbehera /* Initialize the BCM 8704 xcvr */
25774732Sdavemq 
25784732Sdavemq static nxge_status_t
nxge_BCM8704_xcvr_init(p_nxge_t nxgep)25795572Ssbehera nxge_BCM8704_xcvr_init(p_nxge_t nxgep)
25803859Sml29623 {
25813859Sml29623 	uint16_t		val;
25823859Sml29623 #ifdef	NXGE_DEBUG
25833859Sml29623 	uint8_t			portn;
25843859Sml29623 	uint16_t		val1;
25853859Sml29623 #endif
25863859Sml29623 	uint8_t			phy_port_addr;
25873859Sml29623 	pmd_tx_control_t	tx_ctl;
25883859Sml29623 	control_t		ctl;
25893859Sml29623 	phyxs_control_t		phyxs_ctl;
25903859Sml29623 	pcs_control_t		pcs_ctl;
25913859Sml29623 	uint32_t		delay = 0;
25923859Sml29623 	optics_dcntr_t		op_ctr;
25933859Sml29623 	nxge_status_t		status = NXGE_OK;
25943859Sml29623 #ifdef	NXGE_DEBUG
25953859Sml29623 	portn = nxgep->mac.portnum;
25963859Sml29623 #endif
2597*12452SSantwona.Behera@oracle.COM 
25985572Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
25994732Sdavemq 	    portn));
26004732Sdavemq 
26014732Sdavemq 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
26024732Sdavemq 
26034732Sdavemq 	/* Reset the transceiver */
26044732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
26054732Sdavemq 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
26064732Sdavemq 		goto fail;
26074732Sdavemq 
26084732Sdavemq 	phyxs_ctl.bits.reset = 1;
26094732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
26104732Sdavemq 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
26114732Sdavemq 		goto fail;
26124732Sdavemq 
26134732Sdavemq 	do {
26144732Sdavemq 		drv_usecwait(500);
26154732Sdavemq 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26164732Sdavemq 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
26174732Sdavemq 		    &phyxs_ctl.value)) != NXGE_OK)
26184732Sdavemq 			goto fail;
26194732Sdavemq 		delay++;
26204732Sdavemq 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
26214732Sdavemq 	if (delay == 100) {
26224732Sdavemq 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
26234732Sdavemq 		    "failed to reset Transceiver on port<%d>", portn));
26244732Sdavemq 		status = NXGE_ERROR;
26254732Sdavemq 		goto fail;
26264732Sdavemq 	}
26274732Sdavemq 
26284732Sdavemq 	/* Set to 0x7FBF */
26294732Sdavemq 	ctl.value = 0;
26304732Sdavemq 	ctl.bits.res1 = 0x3F;
26314732Sdavemq 	ctl.bits.optxon_lvl = 1;
26324732Sdavemq 	ctl.bits.oprxflt_lvl = 1;
26334732Sdavemq 	ctl.bits.optrxlos_lvl = 1;
26344732Sdavemq 	ctl.bits.optxflt_lvl = 1;
26354732Sdavemq 	ctl.bits.opprflt_lvl = 1;
26364732Sdavemq 	ctl.bits.obtmpflt_lvl = 1;
26374732Sdavemq 	ctl.bits.opbiasflt_lvl = 1;
26384732Sdavemq 	ctl.bits.optxrst_lvl = 1;
26394732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
26404732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value))
26414732Sdavemq 	    != NXGE_OK)
26424732Sdavemq 		goto fail;
26434732Sdavemq 
26444732Sdavemq 	/* Set to 0x164 */
26454732Sdavemq 	tx_ctl.value = 0;
26464732Sdavemq 	tx_ctl.bits.tsck_lpwren = 1;
26474732Sdavemq 	tx_ctl.bits.tx_dac_txck = 0x2;
26484732Sdavemq 	tx_ctl.bits.tx_dac_txd = 0x1;
26494732Sdavemq 	tx_ctl.bits.xfp_clken = 1;
26504732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
26514732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG,
26524732Sdavemq 	    tx_ctl.value)) != NXGE_OK)
26534732Sdavemq 		goto fail;
26544732Sdavemq 	/*
26554732Sdavemq 	 * According to Broadcom's instruction, SW needs to read
26564732Sdavemq 	 * back these registers twice after written.
26574732Sdavemq 	 */
26584732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26594732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
26604732Sdavemq 	    != NXGE_OK)
26614732Sdavemq 		goto fail;
26624732Sdavemq 
26634732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26644732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
26654732Sdavemq 	    != NXGE_OK)
26664732Sdavemq 		goto fail;
26674732Sdavemq 
26684732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26694732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
26704732Sdavemq 	    != NXGE_OK)
26714732Sdavemq 		goto fail;
26724732Sdavemq 
26734732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26744732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
26754732Sdavemq 	    != NXGE_OK)
26764732Sdavemq 		goto fail;
26774732Sdavemq 
26784732Sdavemq 	/* Enable Tx and Rx LEDs to be driven by traffic */
26794732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26804732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
26814732Sdavemq 	    &op_ctr.value)) != NXGE_OK)
26824732Sdavemq 		goto fail;
26835553Smisaki 	if (NXGE_IS_XAUI_PLATFORM(nxgep)) {
26845553Smisaki 		op_ctr.bits.gpio_sel = 0x1;
26855553Smisaki 	} else {
26865553Smisaki 		op_ctr.bits.gpio_sel = 0x3;
26875553Smisaki 	}
26884732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
26894732Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
26904732Sdavemq 	    op_ctr.value)) != NXGE_OK)
26914732Sdavemq 		goto fail;
26924732Sdavemq 
26934732Sdavemq 	NXGE_DELAY(1000000);
26944732Sdavemq 
2695*12452SSantwona.Behera@oracle.COM 	/*
2696*12452SSantwona.Behera@oracle.COM 	 * Set XAUI link tunables from OBP if present.
2697*12452SSantwona.Behera@oracle.COM 	 */
2698*12452SSantwona.Behera@oracle.COM 	NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
2699*12452SSantwona.Behera@oracle.COM 	if (status != NXGE_OK) {
2700*12452SSantwona.Behera@oracle.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2701*12452SSantwona.Behera@oracle.COM 		    "nxge_BCM8704_xcvr_init: Failed setting PHY tunables"));
2702*12452SSantwona.Behera@oracle.COM 		goto fail;
2703*12452SSantwona.Behera@oracle.COM 	}
2704*12452SSantwona.Behera@oracle.COM 
27054732Sdavemq 	/* Set BCM8704 Internal Loopback mode if necessary */
27064732Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
27074732Sdavemq 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
27084732Sdavemq 	    != NXGE_OK)
27094732Sdavemq 		goto fail;
27104732Sdavemq 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
27114732Sdavemq 		pcs_ctl.bits.loopback = 1;
27124732Sdavemq 	else
27134732Sdavemq 		pcs_ctl.bits.loopback = 0;
27144732Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
27154732Sdavemq 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
27164732Sdavemq 	    != NXGE_OK)
27174732Sdavemq 		goto fail;
27184732Sdavemq 
27194732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val);
27204732Sdavemq 	if (status != NXGE_OK)
27214732Sdavemq 		goto fail;
27224732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27234732Sdavemq 	    "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val));
27244732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
27254732Sdavemq 	if (status != NXGE_OK)
27264732Sdavemq 		goto fail;
27274732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27284732Sdavemq 	    "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val));
27294732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
27304732Sdavemq 	if (status != NXGE_OK)
27314732Sdavemq 		goto fail;
27324732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27334732Sdavemq 	    "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val));
27344732Sdavemq 
27354732Sdavemq #ifdef	NXGE_DEBUG
27364732Sdavemq 	/* Diagnose link issue if link is not up */
27374732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR,
27384732Sdavemq 	    BCM8704_USER_ANALOG_STATUS0_REG,
27394732Sdavemq 	    &val);
27404732Sdavemq 	if (status != NXGE_OK)
27414732Sdavemq 		goto fail;
27424732Sdavemq 
27434732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
27446929Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_ANALOG_STATUS0_REG, &val);
27454732Sdavemq 	if (status != NXGE_OK)
27464732Sdavemq 		goto fail;
27474732Sdavemq 
27484732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
27496929Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
27504732Sdavemq 	if (status != NXGE_OK)
27514732Sdavemq 		goto fail;
27524732Sdavemq 
27534732Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
27546929Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
27554732Sdavemq 	if (status != NXGE_OK)
27564732Sdavemq 		goto fail;
27574732Sdavemq 
27584732Sdavemq 	if (val != 0x3FC) {
27594732Sdavemq 		if ((val == 0x43BC) && (val1 != 0)) {
27604732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27614732Sdavemq 			    "Cable not connected to peer or bad"
27624732Sdavemq 			    " cable on port<%d>\n", portn));
27634732Sdavemq 		} else if (val == 0x639C) {
27644732Sdavemq 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27654732Sdavemq 			    "Optical module (XFP) is bad or absent"
27664732Sdavemq 			    " on port<%d>\n", portn));
27674732Sdavemq 		}
27684732Sdavemq 	}
27694732Sdavemq #endif
27704732Sdavemq 
27715572Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
27725572Ssbehera 	    portn));
27735572Ssbehera 	return (NXGE_OK);
27745572Ssbehera 
27755572Ssbehera fail:
27765572Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27775572Ssbehera 	    "nxge_BCM8704_xcvr_init: failed to initialize transceiver for "
27785572Ssbehera 	    "port<%d>", nxgep->mac.portnum));
27795572Ssbehera 	return (NXGE_ERROR);
27805572Ssbehera }
27815572Ssbehera 
27825572Ssbehera /* Initialize the BCM 8706 Transceiver */
27835572Ssbehera 
27845572Ssbehera static nxge_status_t
nxge_BCM8706_xcvr_init(p_nxge_t nxgep)27855572Ssbehera nxge_BCM8706_xcvr_init(p_nxge_t nxgep)
27865572Ssbehera {
27875572Ssbehera 	uint8_t			phy_port_addr;
27885572Ssbehera 	phyxs_control_t		phyxs_ctl;
27895572Ssbehera 	pcs_control_t		pcs_ctl;
27905572Ssbehera 	uint32_t		delay = 0;
27915572Ssbehera 	optics_dcntr_t		op_ctr;
27925572Ssbehera 	nxge_status_t		status = NXGE_OK;
27935572Ssbehera #ifdef	NXGE_DEBUG
27945572Ssbehera 	uint8_t			portn = nxgep->mac.portnum;
27955572Ssbehera #endif
27965572Ssbehera 
27975572Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
27985572Ssbehera 	    portn));
27995572Ssbehera 
28005572Ssbehera 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
28015572Ssbehera 
28025572Ssbehera 	/* Reset the transceiver */
28035572Ssbehera 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
28045572Ssbehera 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
28055572Ssbehera 		goto fail;
28065572Ssbehera 
28075572Ssbehera 	phyxs_ctl.bits.reset = 1;
28085572Ssbehera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
28095572Ssbehera 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
28105572Ssbehera 		goto fail;
28115572Ssbehera 	do {
28125572Ssbehera 		drv_usecwait(500);
28135572Ssbehera 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28145572Ssbehera 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
28155572Ssbehera 		    &phyxs_ctl.value)) != NXGE_OK)
28165572Ssbehera 			goto fail;
28175572Ssbehera 		delay++;
28185572Ssbehera 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
28195572Ssbehera 
28205572Ssbehera 	if (delay == 100) {
28215572Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
28225572Ssbehera 		    "failed to reset Transceiver on port<%d>", portn));
28235572Ssbehera 		status = NXGE_ERROR;
28245572Ssbehera 		goto fail;
28255572Ssbehera 	}
28265572Ssbehera 
28275572Ssbehera 	NXGE_DELAY(1000000);
28285572Ssbehera 
2829*12452SSantwona.Behera@oracle.COM 	/*
2830*12452SSantwona.Behera@oracle.COM 	 * Set XAUI link tunables from OBP if present.
2831*12452SSantwona.Behera@oracle.COM 	 */
2832*12452SSantwona.Behera@oracle.COM 	NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
2833*12452SSantwona.Behera@oracle.COM 	if (status != NXGE_OK) {
2834*12452SSantwona.Behera@oracle.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2835*12452SSantwona.Behera@oracle.COM 		    "nxge_BCM8706_xcvr_init: Failed setting PHY tunables"));
2836*12452SSantwona.Behera@oracle.COM 		goto fail;
2837*12452SSantwona.Behera@oracle.COM 	}
2838*12452SSantwona.Behera@oracle.COM 
28395572Ssbehera 	/* Set BCM8706 Internal Loopback mode if necessary */
28405572Ssbehera 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28415572Ssbehera 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
28425572Ssbehera 	    != NXGE_OK)
28435572Ssbehera 		goto fail;
28445572Ssbehera 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
28455572Ssbehera 		pcs_ctl.bits.loopback = 1;
28465572Ssbehera 	else
28475572Ssbehera 		pcs_ctl.bits.loopback = 0;
28485572Ssbehera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
28495572Ssbehera 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
28505572Ssbehera 	    != NXGE_OK)
28515572Ssbehera 		goto fail;
28525572Ssbehera 
28535572Ssbehera 	/* Enable Tx and Rx LEDs to be driven by traffic */
28545572Ssbehera 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28555572Ssbehera 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
28565572Ssbehera 	    &op_ctr.value)) != NXGE_OK)
28575572Ssbehera 		goto fail;
28585572Ssbehera 	op_ctr.bits.gpio_sel = 0x3;
28595572Ssbehera 	op_ctr.bits.res2 = 0x1;
28605572Ssbehera 
28615572Ssbehera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
28625572Ssbehera 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
28635572Ssbehera 	    op_ctr.value)) != NXGE_OK)
28645572Ssbehera 		goto fail;
28655572Ssbehera 
28665572Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
28675572Ssbehera 	    portn));
28685572Ssbehera 	return (NXGE_OK);
28695572Ssbehera 
28705572Ssbehera fail:
28715572Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
28725572Ssbehera 	    "nxge_BCM8706_xcvr_init: failed to initialize transceiver for "
28735572Ssbehera 	    "port<%d>", nxgep->mac.portnum));
28745572Ssbehera 	return (status);
28755572Ssbehera }
28765572Ssbehera 
287712103SSantwona.Behera@Sun.COM static int
nxge_nlp2020_i2c_read(p_nxge_t nxgep,uint8_t ctrl_port,uint16_t address,uint16_t reg,uint8_t * data)287812103SSantwona.Behera@Sun.COM nxge_nlp2020_i2c_read(p_nxge_t nxgep, uint8_t ctrl_port, uint16_t address,
287912103SSantwona.Behera@Sun.COM 	    uint16_t reg, uint8_t *data)
288012103SSantwona.Behera@Sun.COM {
288112103SSantwona.Behera@Sun.COM 	int  phy_dev, phy_reg;
288212103SSantwona.Behera@Sun.COM 	uint16_t phy_data = 0;
288312103SSantwona.Behera@Sun.COM 	uint16_t stat;
288412103SSantwona.Behera@Sun.COM 	uint8_t count = 100;
288512103SSantwona.Behera@Sun.COM 
288612103SSantwona.Behera@Sun.COM 	/*
288712103SSantwona.Behera@Sun.COM 	 * NLP2020_I2C_SNOOP_ADDR_REG [15:9][1] - Address
288812103SSantwona.Behera@Sun.COM 	 * NLP2020_I2C_SNOOP_ADDR_REG[7:0] - register in the xcvr's i2c
288912103SSantwona.Behera@Sun.COM 	 */
289012103SSantwona.Behera@Sun.COM 	phy_dev = NLP2020_I2C_SNOOP_DEV_ADDR;
289112103SSantwona.Behera@Sun.COM 	phy_reg = NLP2020_I2C_SNOOP_ADDR_REG;
289212103SSantwona.Behera@Sun.COM 	phy_data = ((address + 1) << NLP2020_XCVR_I2C_ADDR_SH) | reg;
289312103SSantwona.Behera@Sun.COM 	if (nxge_mdio_write(nxgep, ctrl_port,
289412103SSantwona.Behera@Sun.COM 	    phy_dev, phy_reg, phy_data) != NXGE_OK)
289512103SSantwona.Behera@Sun.COM 		goto fail;
289612103SSantwona.Behera@Sun.COM 
289712103SSantwona.Behera@Sun.COM 	phy_reg = NLP2020_I2C_SNOOP_STAT_REG;
289812103SSantwona.Behera@Sun.COM 	(void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg, &stat);
289912103SSantwona.Behera@Sun.COM 	while ((stat != 0x01) && (count-- > 0)) {
290012103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg,
290112103SSantwona.Behera@Sun.COM 		    &stat);
290212103SSantwona.Behera@Sun.COM 	}
290312103SSantwona.Behera@Sun.COM 	if (count) {
290412103SSantwona.Behera@Sun.COM 		phy_reg = NLP2020_I2C_SNOOP_DATA_REG;
290512103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg,
290612103SSantwona.Behera@Sun.COM 		    &phy_data);
290712103SSantwona.Behera@Sun.COM 		*data = (phy_data >> 8);
290812103SSantwona.Behera@Sun.COM 		return (0);
290912103SSantwona.Behera@Sun.COM 	}
291012103SSantwona.Behera@Sun.COM fail:
291112103SSantwona.Behera@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
291212103SSantwona.Behera@Sun.COM 	    "nxge_nlp2020_i2c_read: FAILED"));
291312103SSantwona.Behera@Sun.COM 	return (1);
291412103SSantwona.Behera@Sun.COM 
291512103SSantwona.Behera@Sun.COM }
291612103SSantwona.Behera@Sun.COM 
291712103SSantwona.Behera@Sun.COM /* Initialize the Netlogic AEL2020 Transceiver */
291812103SSantwona.Behera@Sun.COM 
291912103SSantwona.Behera@Sun.COM #define	NLP_INI_WAIT	1
292012103SSantwona.Behera@Sun.COM #define	NLP_INI_STOP	0
292112103SSantwona.Behera@Sun.COM 
292212103SSantwona.Behera@Sun.COM static nxge_nlp_initseq_t nlp2020_revC_fiber_init[] = {
292312103SSantwona.Behera@Sun.COM 	{0x1C003, 0x3101},
292412103SSantwona.Behera@Sun.COM 	{0x1CC01, 0x488a},
292512103SSantwona.Behera@Sun.COM 	{0x1CB1B, 0x0200},
292612103SSantwona.Behera@Sun.COM 	{0x1CB1C, 0x00f0},
292712103SSantwona.Behera@Sun.COM 	{0x1CC06, 0x00e0},
292812103SSantwona.Behera@Sun.COM 	{NLP_INI_STOP, 0},
292912103SSantwona.Behera@Sun.COM };
293012103SSantwona.Behera@Sun.COM 
293112103SSantwona.Behera@Sun.COM static nxge_nlp_initseq_t nlp2020_revC_copper_init[] = {
293212103SSantwona.Behera@Sun.COM 
293312103SSantwona.Behera@Sun.COM 	{0x1C003, 0x3101},
293412103SSantwona.Behera@Sun.COM 	{0x1CD40, 0x0001},
293512103SSantwona.Behera@Sun.COM 
293612103SSantwona.Behera@Sun.COM 	{0x1CA12, 0x0100},
293712103SSantwona.Behera@Sun.COM 	{0x1CA22, 0x0100},
293812103SSantwona.Behera@Sun.COM 	{0x1CA42, 0x0100},
293912103SSantwona.Behera@Sun.COM 	{0x1C20D, 0x0002},
294012103SSantwona.Behera@Sun.COM 	{NLP_INI_WAIT, 100},
294112103SSantwona.Behera@Sun.COM 
294212103SSantwona.Behera@Sun.COM 	{0x1ff28, 0x4001},
294312103SSantwona.Behera@Sun.COM 	{0x1ff2A, 0x004A},
294412103SSantwona.Behera@Sun.COM 	{NLP_INI_WAIT, 500},
294512103SSantwona.Behera@Sun.COM 
294612103SSantwona.Behera@Sun.COM 	{0x1d000, 0x5200},
294712103SSantwona.Behera@Sun.COM 	{NLP_INI_WAIT, 500},
294812103SSantwona.Behera@Sun.COM 
294912103SSantwona.Behera@Sun.COM 	{0x1d800, 0x4009},
295012103SSantwona.Behera@Sun.COM 	{0x1d801, 0x2fff},
295112103SSantwona.Behera@Sun.COM 	{0x1d802, 0x300f},
295212103SSantwona.Behera@Sun.COM 	{0x1d803, 0x40aa},
295312103SSantwona.Behera@Sun.COM 	{0x1d804, 0x401c},
295412103SSantwona.Behera@Sun.COM 	{0x1d805, 0x401e},
295512103SSantwona.Behera@Sun.COM 	{0x1d806, 0x20c5},
295612103SSantwona.Behera@Sun.COM 	{0x1d807, 0x3c05},
295712103SSantwona.Behera@Sun.COM 	{0x1d808, 0x6536},
295812103SSantwona.Behera@Sun.COM 	{0x1d809, 0x2fe4},
295912103SSantwona.Behera@Sun.COM 	{0x1d80a, 0x3dc4},
296012103SSantwona.Behera@Sun.COM 	{0x1d80b, 0x6624},
296112103SSantwona.Behera@Sun.COM 	{0x1d80c, 0x2ff4},
296212103SSantwona.Behera@Sun.COM 	{0x1d80d, 0x3dc4},
296312103SSantwona.Behera@Sun.COM 	{0x1d80e, 0x2035},
296412103SSantwona.Behera@Sun.COM 	{0x1d80f, 0x30a5},
296512103SSantwona.Behera@Sun.COM 	{0x1d810, 0x6524},
296612103SSantwona.Behera@Sun.COM 	{0x1d811, 0x2ca2},
296712103SSantwona.Behera@Sun.COM 	{0x1d812, 0x3012},
296812103SSantwona.Behera@Sun.COM 	{0x1d813, 0x1002},
296912103SSantwona.Behera@Sun.COM 	{0x1d814, 0x2882},
297012103SSantwona.Behera@Sun.COM 	{0x1d815, 0x3022},
297112103SSantwona.Behera@Sun.COM 	{0x1d816, 0x1002},
297212103SSantwona.Behera@Sun.COM 	{0x1d817, 0x2972},
297312103SSantwona.Behera@Sun.COM 	{0x1d818, 0x3022},
297412103SSantwona.Behera@Sun.COM 	{0x1d819, 0x1002},
297512103SSantwona.Behera@Sun.COM 	{0x1d81a, 0x2892},
297612103SSantwona.Behera@Sun.COM 	{0x1d81b, 0x3012},
297712103SSantwona.Behera@Sun.COM 	{0x1d81c, 0x1002},
297812103SSantwona.Behera@Sun.COM 	{0x1d81d, 0x24e2},
297912103SSantwona.Behera@Sun.COM 	{0x1d81e, 0x3022},
298012103SSantwona.Behera@Sun.COM 	{0x1d81f, 0x1002},
298112103SSantwona.Behera@Sun.COM 	{0x1d820, 0x27e2},
298212103SSantwona.Behera@Sun.COM 	{0x1d821, 0x3012},
298312103SSantwona.Behera@Sun.COM 	{0x1d822, 0x1002},
298412103SSantwona.Behera@Sun.COM 	{0x1d823, 0x2422},
298512103SSantwona.Behera@Sun.COM 	{0x1d824, 0x3022},
298612103SSantwona.Behera@Sun.COM 	{0x1d825, 0x1002},
298712103SSantwona.Behera@Sun.COM 	{0x1d826, 0x22cd},
298812103SSantwona.Behera@Sun.COM 	{0x1d827, 0x301d},
298912103SSantwona.Behera@Sun.COM 	{0x1d828, 0x2992},
299012103SSantwona.Behera@Sun.COM 	{0x1d829, 0x3022},
299112103SSantwona.Behera@Sun.COM 	{0x1d82a, 0x1002},
299212103SSantwona.Behera@Sun.COM 	{0x1d82b, 0x5553},
299312103SSantwona.Behera@Sun.COM 	{0x1d82c, 0x0307},
299412103SSantwona.Behera@Sun.COM 	{0x1d82d, 0x2572},
299512103SSantwona.Behera@Sun.COM 	{0x1d82e, 0x3022},
299612103SSantwona.Behera@Sun.COM 	{0x1d82f, 0x1002},
299712103SSantwona.Behera@Sun.COM 	{0x1d830, 0x21a2},
299812103SSantwona.Behera@Sun.COM 	{0x1d831, 0x3012},
299912103SSantwona.Behera@Sun.COM 	{0x1d832, 0x1002},
300012103SSantwona.Behera@Sun.COM 	{0x1d833, 0x4016},
300112103SSantwona.Behera@Sun.COM 	{0x1d834, 0x5e63},
300212103SSantwona.Behera@Sun.COM 	{0x1d835, 0x0344},
300312103SSantwona.Behera@Sun.COM 	{0x1d836, 0x21a2},
300412103SSantwona.Behera@Sun.COM 	{0x1d837, 0x3012},
300512103SSantwona.Behera@Sun.COM 	{0x1d838, 0x1002},
300612103SSantwona.Behera@Sun.COM 	{0x1d839, 0x400e},
300712103SSantwona.Behera@Sun.COM 	{0x1d83a, 0x2572},
300812103SSantwona.Behera@Sun.COM 	{0x1d83b, 0x3022},
300912103SSantwona.Behera@Sun.COM 	{0x1d83c, 0x1002},
301012103SSantwona.Behera@Sun.COM 	{0x1d83d, 0x2b22},
301112103SSantwona.Behera@Sun.COM 	{0x1d83e, 0x3012},
301212103SSantwona.Behera@Sun.COM 	{0x1d83f, 0x1002},
301312103SSantwona.Behera@Sun.COM 	{0x1d840, 0x28e2},
301412103SSantwona.Behera@Sun.COM 	{0x1d841, 0x3022},
301512103SSantwona.Behera@Sun.COM 	{0x1d842, 0x1002},
301612103SSantwona.Behera@Sun.COM 	{0x1d843, 0x2782},
301712103SSantwona.Behera@Sun.COM 	{0x1d844, 0x3022},
301812103SSantwona.Behera@Sun.COM 	{0x1d845, 0x1002},
301912103SSantwona.Behera@Sun.COM 	{0x1d846, 0x2fa4},
302012103SSantwona.Behera@Sun.COM 	{0x1d847, 0x3dc4},
302112103SSantwona.Behera@Sun.COM 	{0x1d848, 0x6624},
302212103SSantwona.Behera@Sun.COM 	{0x1d849, 0x2e8b},
302312103SSantwona.Behera@Sun.COM 	{0x1d84a, 0x303b},
302412103SSantwona.Behera@Sun.COM 	{0x1d84b, 0x56b3},
302512103SSantwona.Behera@Sun.COM 	{0x1d84c, 0x03c6},
302612103SSantwona.Behera@Sun.COM 	{0x1d84d, 0x866b},
302712103SSantwona.Behera@Sun.COM 	{0x1d84e, 0x400c},
302812103SSantwona.Behera@Sun.COM 	{0x1d84f, 0x2782},
302912103SSantwona.Behera@Sun.COM 	{0x1d850, 0x3012},
303012103SSantwona.Behera@Sun.COM 	{0x1d851, 0x1002},
303112103SSantwona.Behera@Sun.COM 	{0x1d852, 0x2c4b},
303212103SSantwona.Behera@Sun.COM 	{0x1d853, 0x309b},
303312103SSantwona.Behera@Sun.COM 	{0x1d854, 0x56b3},
303412103SSantwona.Behera@Sun.COM 	{0x1d855, 0x03c3},
303512103SSantwona.Behera@Sun.COM 	{0x1d856, 0x866b},
303612103SSantwona.Behera@Sun.COM 	{0x1d857, 0x400c},
303712103SSantwona.Behera@Sun.COM 	{0x1d858, 0x22a2},
303812103SSantwona.Behera@Sun.COM 	{0x1d859, 0x3022},
303912103SSantwona.Behera@Sun.COM 	{0x1d85a, 0x1002},
304012103SSantwona.Behera@Sun.COM 	{0x1d85b, 0x28e2},
304112103SSantwona.Behera@Sun.COM 	{0x1d85c, 0x3022},
304212103SSantwona.Behera@Sun.COM 	{0x1d85d, 0x1002},
304312103SSantwona.Behera@Sun.COM 	{0x1d85e, 0x2782},
304412103SSantwona.Behera@Sun.COM 	{0x1d85f, 0x3022},
304512103SSantwona.Behera@Sun.COM 	{0x1d860, 0x1002},
304612103SSantwona.Behera@Sun.COM 	{0x1d861, 0x2fb4},
304712103SSantwona.Behera@Sun.COM 	{0x1d862, 0x3dc4},
304812103SSantwona.Behera@Sun.COM 	{0x1d863, 0x6624},
304912103SSantwona.Behera@Sun.COM 	{0x1d864, 0x56b3},
305012103SSantwona.Behera@Sun.COM 	{0x1d865, 0x03c3},
305112103SSantwona.Behera@Sun.COM 	{0x1d866, 0x866b},
305212103SSantwona.Behera@Sun.COM 	{0x1d867, 0x401c},
305312103SSantwona.Behera@Sun.COM 	{0x1d868, 0x2c45},
305412103SSantwona.Behera@Sun.COM 	{0x1d869, 0x3095},
305512103SSantwona.Behera@Sun.COM 	{0x1d86a, 0x5b53},
305612103SSantwona.Behera@Sun.COM 	{0x1d86b, 0x23d2},
305712103SSantwona.Behera@Sun.COM 	{0x1d86c, 0x3012},
305812103SSantwona.Behera@Sun.COM 	{0x1d86d, 0x13c2},
305912103SSantwona.Behera@Sun.COM 	{0x1d86e, 0x5cc3},
306012103SSantwona.Behera@Sun.COM 	{0x1d86f, 0x2782},
306112103SSantwona.Behera@Sun.COM 	{0x1d870, 0x3012},
306212103SSantwona.Behera@Sun.COM 	{0x1d871, 0x1312},
306312103SSantwona.Behera@Sun.COM 	{0x1d872, 0x2b22},
306412103SSantwona.Behera@Sun.COM 	{0x1d873, 0x3012},
306512103SSantwona.Behera@Sun.COM 	{0x1d874, 0x1002},
306612103SSantwona.Behera@Sun.COM 	{0x1d875, 0x28e2},
306712103SSantwona.Behera@Sun.COM 	{0x1d876, 0x3022},
306812103SSantwona.Behera@Sun.COM 	{0x1d877, 0x1002},
306912103SSantwona.Behera@Sun.COM 	{0x1d878, 0x2672},
307012103SSantwona.Behera@Sun.COM 	{0x1d879, 0x3022},
307112103SSantwona.Behera@Sun.COM 	{0x1d87a, 0x1002},
307212103SSantwona.Behera@Sun.COM 	{0x1d87b, 0x21a2},
307312103SSantwona.Behera@Sun.COM 	{0x1d87c, 0x3012},
307412103SSantwona.Behera@Sun.COM 	{0x1d87d, 0x1002},
307512103SSantwona.Behera@Sun.COM 	{0x1d87e, 0x628f},
307612103SSantwona.Behera@Sun.COM 	{0x1d87f, 0x2985},
307712103SSantwona.Behera@Sun.COM 	{0x1d880, 0x33a5},
307812103SSantwona.Behera@Sun.COM 	{0x1d881, 0x2782},
307912103SSantwona.Behera@Sun.COM 	{0x1d882, 0x3022},
308012103SSantwona.Behera@Sun.COM 	{0x1d883, 0x1002},
308112103SSantwona.Behera@Sun.COM 	{0x1d884, 0x5653},
308212103SSantwona.Behera@Sun.COM 	{0x1d885, 0x03d2},
308312103SSantwona.Behera@Sun.COM 	{0x1d886, 0x401e},
308412103SSantwona.Behera@Sun.COM 	{0x1d887, 0x6f72},
308512103SSantwona.Behera@Sun.COM 	{0x1d888, 0x1002},
308612103SSantwona.Behera@Sun.COM 	{0x1d889, 0x628f},
308712103SSantwona.Behera@Sun.COM 	{0x1d88a, 0x2304},
308812103SSantwona.Behera@Sun.COM 	{0x1d88b, 0x3c84},
308912103SSantwona.Behera@Sun.COM 	{0x1d88c, 0x6436},
309012103SSantwona.Behera@Sun.COM 	{0x1d88d, 0xdff4},
309112103SSantwona.Behera@Sun.COM 	{0x1d88e, 0x6436},
309212103SSantwona.Behera@Sun.COM 	{0x1d88f, 0x2ff5},
309312103SSantwona.Behera@Sun.COM 	{0x1d890, 0x3005},
309412103SSantwona.Behera@Sun.COM 	{0x1d891, 0x8656},
309512103SSantwona.Behera@Sun.COM 	{0x1d892, 0xdfba},
309612103SSantwona.Behera@Sun.COM 	{0x1d893, 0x56a3},
309712103SSantwona.Behera@Sun.COM 	{0x1d894, 0xd05a},
309812103SSantwona.Behera@Sun.COM 	{0x1d895, 0x29e2},
309912103SSantwona.Behera@Sun.COM 	{0x1d896, 0x3012},
310012103SSantwona.Behera@Sun.COM 	{0x1d897, 0x1392},
310112103SSantwona.Behera@Sun.COM 	{0x1d898, 0xd05a},
310212103SSantwona.Behera@Sun.COM 	{0x1d899, 0x56a3},
310312103SSantwona.Behera@Sun.COM 	{0x1d89a, 0xdfba},
310412103SSantwona.Behera@Sun.COM 	{0x1d89b, 0x0383},
310512103SSantwona.Behera@Sun.COM 	{0x1d89c, 0x6f72},
310612103SSantwona.Behera@Sun.COM 	{0x1d89d, 0x1002},
310712103SSantwona.Behera@Sun.COM 	{0x1d89e, 0x2a64},
310812103SSantwona.Behera@Sun.COM 	{0x1d89f, 0x3014},
310912103SSantwona.Behera@Sun.COM 	{0x1d8a0, 0x2005},
311012103SSantwona.Behera@Sun.COM 	{0x1d8a1, 0x3d75},
311112103SSantwona.Behera@Sun.COM 	{0x1d8a2, 0xc451},
311212103SSantwona.Behera@Sun.COM 	{0x1d8a3, 0x2a42},
311312103SSantwona.Behera@Sun.COM 	{0x1d8a4, 0x3022},
311412103SSantwona.Behera@Sun.COM 	{0x1d8a5, 0x1002},
311512103SSantwona.Behera@Sun.COM 	{0x1d8a6, 0x178c},
311612103SSantwona.Behera@Sun.COM 	{0x1d8a7, 0x1898},
311712103SSantwona.Behera@Sun.COM 	{0x1d8a8, 0x19a4},
311812103SSantwona.Behera@Sun.COM 	{0x1d8a9, 0x1ab0},
311912103SSantwona.Behera@Sun.COM 	{0x1d8aa, 0x1bbc},
312012103SSantwona.Behera@Sun.COM 	{0x1d8ab, 0x1cc8},
312112103SSantwona.Behera@Sun.COM 	{0x1d8ac, 0x1dd3},
312212103SSantwona.Behera@Sun.COM 	{0x1d8ad, 0x1ede},
312312103SSantwona.Behera@Sun.COM 	{0x1d8ae, 0x1fe9},
312412103SSantwona.Behera@Sun.COM 	{0x1d8af, 0x20f4},
312512103SSantwona.Behera@Sun.COM 	{0x1d8b0, 0x21ff},
312612103SSantwona.Behera@Sun.COM 	{0x1d8b1, 0x0000},
312712103SSantwona.Behera@Sun.COM 	{0x1d8b2, 0x27e1},
312812103SSantwona.Behera@Sun.COM 	{0x1d8b3, 0x3021},
312912103SSantwona.Behera@Sun.COM 	{0x1d8b4, 0x1001},
313012103SSantwona.Behera@Sun.COM 	{0x1d8b5, 0xc620},
313112103SSantwona.Behera@Sun.COM 	{0x1d8b6, 0x0000},
313212103SSantwona.Behera@Sun.COM 	{0x1d8b7, 0xc621},
313312103SSantwona.Behera@Sun.COM 	{0x1d8b8, 0x0000},
313412103SSantwona.Behera@Sun.COM 	{0x1d8b9, 0xc622},
313512103SSantwona.Behera@Sun.COM 	{0x1d8ba, 0x00e2},
313612103SSantwona.Behera@Sun.COM 	{0x1d8bb, 0xc623},
313712103SSantwona.Behera@Sun.COM 	{0x1d8bc, 0x007f},
313812103SSantwona.Behera@Sun.COM 	{0x1d8bd, 0xc624},
313912103SSantwona.Behera@Sun.COM 	{0x1d8be, 0x00ce},
314012103SSantwona.Behera@Sun.COM 	{0x1d8bf, 0xc625},
314112103SSantwona.Behera@Sun.COM 	{0x1d8c0, 0x0000},
314212103SSantwona.Behera@Sun.COM 	{0x1d8c1, 0xc627},
314312103SSantwona.Behera@Sun.COM 	{0x1d8c2, 0x0000},
314412103SSantwona.Behera@Sun.COM 	{0x1d8c3, 0xc628},
314512103SSantwona.Behera@Sun.COM 	{0x1d8c4, 0x0000},
314612103SSantwona.Behera@Sun.COM 	{0x1d8c5, 0xc90a},
314712103SSantwona.Behera@Sun.COM 	{0x1d8c6, 0x3a7c},
314812103SSantwona.Behera@Sun.COM 	{0x1d8c7, 0xc62c},
314912103SSantwona.Behera@Sun.COM 	{0x1d8c8, 0x0000},
315012103SSantwona.Behera@Sun.COM 	{0x1d8c9, 0x0000},
315112103SSantwona.Behera@Sun.COM 	{0x1d8ca, 0x27e1},
315212103SSantwona.Behera@Sun.COM 	{0x1d8cb, 0x3021},
315312103SSantwona.Behera@Sun.COM 	{0x1d8cc, 0x1001},
315412103SSantwona.Behera@Sun.COM 	{0x1d8cd, 0xc502},
315512103SSantwona.Behera@Sun.COM 	{0x1d8ce, 0x53ac},
315612103SSantwona.Behera@Sun.COM 	{0x1d8cf, 0xc503},
315712103SSantwona.Behera@Sun.COM 	{0x1d8d0, 0x2cd3},
315812103SSantwona.Behera@Sun.COM 	{0x1d8d1, 0xc600},
315912103SSantwona.Behera@Sun.COM 	{0x1d8d2, 0x2a6e},
316012103SSantwona.Behera@Sun.COM 	{0x1d8d3, 0xc601},
316112103SSantwona.Behera@Sun.COM 	{0x1d8d4, 0x2a2c},
316212103SSantwona.Behera@Sun.COM 	{0x1d8d5, 0xc605},
316312103SSantwona.Behera@Sun.COM 	{0x1d8d6, 0x5557},
316412103SSantwona.Behera@Sun.COM 	{0x1d8d7, 0xc60c},
316512103SSantwona.Behera@Sun.COM 	{0x1d8d8, 0x5400},
316612103SSantwona.Behera@Sun.COM 	{0x1d8d9, 0xc710},
316712103SSantwona.Behera@Sun.COM 	{0x1d8da, 0x0700},
316812103SSantwona.Behera@Sun.COM 	{0x1d8db, 0xc711},
316912103SSantwona.Behera@Sun.COM 	{0x1d8dc, 0x0f06},
317012103SSantwona.Behera@Sun.COM 	{0x1d8dd, 0xc718},
317112103SSantwona.Behera@Sun.COM 	{0x1d8de, 0x0700},
317212103SSantwona.Behera@Sun.COM 	{0x1d8df, 0xc719},
317312103SSantwona.Behera@Sun.COM 	{0x1d8e0, 0x0f06},
317412103SSantwona.Behera@Sun.COM 	{0x1d8e1, 0xc720},
317512103SSantwona.Behera@Sun.COM 	{0x1d8e2, 0x4700},
317612103SSantwona.Behera@Sun.COM 	{0x1d8e3, 0xc721},
317712103SSantwona.Behera@Sun.COM 	{0x1d8e4, 0x0f06},
317812103SSantwona.Behera@Sun.COM 	{0x1d8e5, 0xc728},
317912103SSantwona.Behera@Sun.COM 	{0x1d8e6, 0x0700},
318012103SSantwona.Behera@Sun.COM 	{0x1d8e7, 0xc729},
318112103SSantwona.Behera@Sun.COM 	{0x1d8e8, 0x1207},
318212103SSantwona.Behera@Sun.COM 	{0x1d8e9, 0xc801},
318312103SSantwona.Behera@Sun.COM 	{0x1d8ea, 0x7f50},
318412103SSantwona.Behera@Sun.COM 	{0x1d8eb, 0xc802},
318512103SSantwona.Behera@Sun.COM 	{0x1d8ec, 0x7760},
318612103SSantwona.Behera@Sun.COM 	{0x1d8ed, 0xc803},
318712103SSantwona.Behera@Sun.COM 	{0x1d8ee, 0x7fce},
318812103SSantwona.Behera@Sun.COM 	{0x1d8ef, 0xc804},
318912103SSantwona.Behera@Sun.COM 	{0x1d8f0, 0x520e},
319012103SSantwona.Behera@Sun.COM 	{0x1d8f1, 0xc805},
319112103SSantwona.Behera@Sun.COM 	{0x1d8f2, 0x5c11},
319212103SSantwona.Behera@Sun.COM 	{0x1d8f3, 0xc806},
319312103SSantwona.Behera@Sun.COM 	{0x1d8f4, 0x3c51},
319412103SSantwona.Behera@Sun.COM 	{0x1d8f5, 0xc807},
319512103SSantwona.Behera@Sun.COM 	{0x1d8f6, 0x4061},
319612103SSantwona.Behera@Sun.COM 	{0x1d8f7, 0xc808},
319712103SSantwona.Behera@Sun.COM 	{0x1d8f8, 0x49c1},
319812103SSantwona.Behera@Sun.COM 	{0x1d8f9, 0xc809},
319912103SSantwona.Behera@Sun.COM 	{0x1d8fa, 0x3840},
320012103SSantwona.Behera@Sun.COM 	{0x1d8fb, 0xc80a},
320112103SSantwona.Behera@Sun.COM 	{0x1d8fc, 0x0000},
320212103SSantwona.Behera@Sun.COM 	{0x1d8fd, 0xc821},
320312103SSantwona.Behera@Sun.COM 	{0x1d8fe, 0x0002},
320412103SSantwona.Behera@Sun.COM 	{0x1d8ff, 0xc822},
320512103SSantwona.Behera@Sun.COM 	{0x1d900, 0x0046},
320612103SSantwona.Behera@Sun.COM 	{0x1d901, 0xc844},
320712103SSantwona.Behera@Sun.COM 	{0x1d902, 0x182f},
320812103SSantwona.Behera@Sun.COM 	{0x1d903, 0xc849},
320912103SSantwona.Behera@Sun.COM 	{0x1d904, 0x0400},
321012103SSantwona.Behera@Sun.COM 	{0x1d905, 0xc84a},
321112103SSantwona.Behera@Sun.COM 	{0x1d906, 0x0002},
321212103SSantwona.Behera@Sun.COM 	{0x1d907, 0xc013},
321312103SSantwona.Behera@Sun.COM 	{0x1d908, 0xf341},
321412103SSantwona.Behera@Sun.COM 	{0x1d909, 0xc084},
321512103SSantwona.Behera@Sun.COM 	{0x1d90a, 0x0030},
321612103SSantwona.Behera@Sun.COM 	{0x1d90b, 0xc904},
321712103SSantwona.Behera@Sun.COM 	{0x1d90c, 0x1401},
321812103SSantwona.Behera@Sun.COM 	{0x1d90d, 0xcb0c},
321912103SSantwona.Behera@Sun.COM 	{0x1d90e, 0x0004},
322012103SSantwona.Behera@Sun.COM 	{0x1d90f, 0xcb0e},
322112103SSantwona.Behera@Sun.COM 	{0x1d910, 0xa00a},
322212103SSantwona.Behera@Sun.COM 	{0x1d911, 0xcb0f},
322312103SSantwona.Behera@Sun.COM 	{0x1d912, 0xc0c0},
322412103SSantwona.Behera@Sun.COM 	{0x1d913, 0xcb10},
322512103SSantwona.Behera@Sun.COM 	{0x1d914, 0xc0c0},
322612103SSantwona.Behera@Sun.COM 	{0x1d915, 0xcb11},
322712103SSantwona.Behera@Sun.COM 	{0x1d916, 0x00a0},
322812103SSantwona.Behera@Sun.COM 	{0x1d917, 0xcb12},
322912103SSantwona.Behera@Sun.COM 	{0x1d918, 0x0007},
323012103SSantwona.Behera@Sun.COM 	{0x1d919, 0xc241},
323112103SSantwona.Behera@Sun.COM 	{0x1d91a, 0xa000},
323212103SSantwona.Behera@Sun.COM 	{0x1d91b, 0xc243},
323312103SSantwona.Behera@Sun.COM 	{0x1d91c, 0x7fe0},
323412103SSantwona.Behera@Sun.COM 	{0x1d91d, 0xc604},
323512103SSantwona.Behera@Sun.COM 	{0x1d91e, 0x000e},
323612103SSantwona.Behera@Sun.COM 	{0x1d91f, 0xc609},
323712103SSantwona.Behera@Sun.COM 	{0x1d920, 0x00f5},
323812103SSantwona.Behera@Sun.COM 	{0x1d921, 0x0c61},
323912103SSantwona.Behera@Sun.COM 	{0x1d922, 0x000e},
324012103SSantwona.Behera@Sun.COM 	{0x1d923, 0xc660},
324112103SSantwona.Behera@Sun.COM 	{0x1d924, 0x9600},
324212103SSantwona.Behera@Sun.COM 	{0x1d925, 0xc687},
324312103SSantwona.Behera@Sun.COM 	{0x1d926, 0x0004},
324412103SSantwona.Behera@Sun.COM 	{0x1d927, 0xc60a},
324512103SSantwona.Behera@Sun.COM 	{0x1d928, 0x04f5},
324612103SSantwona.Behera@Sun.COM 	{0x1d929, 0x0000},
324712103SSantwona.Behera@Sun.COM 	{0x1d92a, 0x27e1},
324812103SSantwona.Behera@Sun.COM 	{0x1d92b, 0x3021},
324912103SSantwona.Behera@Sun.COM 	{0x1d92c, 0x1001},
325012103SSantwona.Behera@Sun.COM 	{0x1d92d, 0xc620},
325112103SSantwona.Behera@Sun.COM 	{0x1d92e, 0x14e5},
325212103SSantwona.Behera@Sun.COM 	{0x1d92f, 0xc621},
325312103SSantwona.Behera@Sun.COM 	{0x1d930, 0xc53d},
325412103SSantwona.Behera@Sun.COM 	{0x1d931, 0xc622},
325512103SSantwona.Behera@Sun.COM 	{0x1d932, 0x3cbe},
325612103SSantwona.Behera@Sun.COM 	{0x1d933, 0xc623},
325712103SSantwona.Behera@Sun.COM 	{0x1d934, 0x4452},
325812103SSantwona.Behera@Sun.COM 	{0x1d935, 0xc624},
325912103SSantwona.Behera@Sun.COM 	{0x1d936, 0xc5c5},
326012103SSantwona.Behera@Sun.COM 	{0x1d937, 0xc625},
326112103SSantwona.Behera@Sun.COM 	{0x1d938, 0xe01e},
326212103SSantwona.Behera@Sun.COM 	{0x1d939, 0xc627},
326312103SSantwona.Behera@Sun.COM 	{0x1d93a, 0x0000},
326412103SSantwona.Behera@Sun.COM 	{0x1d93b, 0xc628},
326512103SSantwona.Behera@Sun.COM 	{0x1d93c, 0x0000},
326612103SSantwona.Behera@Sun.COM 	{0x1d93d, 0xc62c},
326712103SSantwona.Behera@Sun.COM 	{0x1d93e, 0x0000},
326812103SSantwona.Behera@Sun.COM 	{0x1d93f, 0xc90a},
326912103SSantwona.Behera@Sun.COM 	{0x1d940, 0x3a7c},
327012103SSantwona.Behera@Sun.COM 	{0x1d941, 0x0000},
327112103SSantwona.Behera@Sun.COM 	{0x1d942, 0x2b84},
327212103SSantwona.Behera@Sun.COM 	{0x1d943, 0x3c74},
327312103SSantwona.Behera@Sun.COM 	{0x1d944, 0x6435},
327412103SSantwona.Behera@Sun.COM 	{0x1d945, 0xdff4},
327512103SSantwona.Behera@Sun.COM 	{0x1d946, 0x6435},
327612103SSantwona.Behera@Sun.COM 	{0x1d947, 0x2806},
327712103SSantwona.Behera@Sun.COM 	{0x1d948, 0x3006},
327812103SSantwona.Behera@Sun.COM 	{0x1d949, 0x8565},
327912103SSantwona.Behera@Sun.COM 	{0x1d94a, 0x2b24},
328012103SSantwona.Behera@Sun.COM 	{0x1d94b, 0x3c24},
328112103SSantwona.Behera@Sun.COM 	{0x1d94c, 0x6436},
328212103SSantwona.Behera@Sun.COM 	{0x1d94d, 0x1002},
328312103SSantwona.Behera@Sun.COM 	{0x1d94e, 0x2b24},
328412103SSantwona.Behera@Sun.COM 	{0x1d94f, 0x3c24},
328512103SSantwona.Behera@Sun.COM 	{0x1d950, 0x6436},
328612103SSantwona.Behera@Sun.COM 	{0x1d951, 0x4045},
328712103SSantwona.Behera@Sun.COM 	{0x1d952, 0x8656},
328812103SSantwona.Behera@Sun.COM 	{0x1d953, 0x5663},
328912103SSantwona.Behera@Sun.COM 	{0x1d954, 0x0302},
329012103SSantwona.Behera@Sun.COM 	{0x1d955, 0x401e},
329112103SSantwona.Behera@Sun.COM 	{0x1d956, 0x1002},
329212103SSantwona.Behera@Sun.COM 	{0x1d957, 0x2017},
329312103SSantwona.Behera@Sun.COM 	{0x1d958, 0x3b17},
329412103SSantwona.Behera@Sun.COM 	{0x1d959, 0x2084},
329512103SSantwona.Behera@Sun.COM 	{0x1d95a, 0x3c14},
329612103SSantwona.Behera@Sun.COM 	{0x1d95b, 0x6724},
329712103SSantwona.Behera@Sun.COM 	{0x1d95c, 0x2807},
329812103SSantwona.Behera@Sun.COM 	{0x1d95d, 0x31a7},
329912103SSantwona.Behera@Sun.COM 	{0x1d95e, 0x20c4},
330012103SSantwona.Behera@Sun.COM 	{0x1d95f, 0x3c24},
330112103SSantwona.Behera@Sun.COM 	{0x1d960, 0x6724},
330212103SSantwona.Behera@Sun.COM 	{0x1d961, 0x2ff7},
330312103SSantwona.Behera@Sun.COM 	{0x1d962, 0x30f7},
330412103SSantwona.Behera@Sun.COM 	{0x1d963, 0x20c4},
330512103SSantwona.Behera@Sun.COM 	{0x1d964, 0x3c04},
330612103SSantwona.Behera@Sun.COM 	{0x1d965, 0x6724},
330712103SSantwona.Behera@Sun.COM 	{0x1d966, 0x1002},
330812103SSantwona.Behera@Sun.COM 	{0x1d967, 0x2807},
330912103SSantwona.Behera@Sun.COM 	{0x1d968, 0x3187},
331012103SSantwona.Behera@Sun.COM 	{0x1d969, 0x20c4},
331112103SSantwona.Behera@Sun.COM 	{0x1d96a, 0x3c24},
331212103SSantwona.Behera@Sun.COM 	{0x1d96b, 0x6724},
331312103SSantwona.Behera@Sun.COM 	{0x1d96c, 0x2fe4},
331412103SSantwona.Behera@Sun.COM 	{0x1d96d, 0x3dc4},
331512103SSantwona.Behera@Sun.COM 	{0x1d96e, 0x6437},
331612103SSantwona.Behera@Sun.COM 	{0x1d96f, 0x20c4},
331712103SSantwona.Behera@Sun.COM 	{0x1d970, 0x3c04},
331812103SSantwona.Behera@Sun.COM 	{0x1d971, 0x6724},
331912103SSantwona.Behera@Sun.COM 	{0x1d972, 0x2017},
332012103SSantwona.Behera@Sun.COM 	{0x1d973, 0x3d17},
332112103SSantwona.Behera@Sun.COM 	{0x1d974, 0x2084},
332212103SSantwona.Behera@Sun.COM 	{0x1d975, 0x3c14},
332312103SSantwona.Behera@Sun.COM 	{0x1d976, 0x6724},
332412103SSantwona.Behera@Sun.COM 	{0x1d977, 0x1002},
332512103SSantwona.Behera@Sun.COM 	{0x1d978, 0x24f4},
332612103SSantwona.Behera@Sun.COM 	{0x1d979, 0x3c64},
332712103SSantwona.Behera@Sun.COM 	{0x1d97a, 0x6436},
332812103SSantwona.Behera@Sun.COM 	{0x1d97b, 0xdff4},
332912103SSantwona.Behera@Sun.COM 	{0x1d97c, 0x6436},
333012103SSantwona.Behera@Sun.COM 	{0x1d97d, 0x1002},
333112103SSantwona.Behera@Sun.COM 	{0x1d97e, 0x2006},
333212103SSantwona.Behera@Sun.COM 	{0x1d97f, 0x3d76},
333312103SSantwona.Behera@Sun.COM 	{0x1d980, 0xc161},
333412103SSantwona.Behera@Sun.COM 	{0x1d981, 0x6134},
333512103SSantwona.Behera@Sun.COM 	{0x1d982, 0x6135},
333612103SSantwona.Behera@Sun.COM 	{0x1d983, 0x5443},
333712103SSantwona.Behera@Sun.COM 	{0x1d984, 0x0303},
333812103SSantwona.Behera@Sun.COM 	{0x1d985, 0x6524},
333912103SSantwona.Behera@Sun.COM 	{0x1d986, 0x00fb},
334012103SSantwona.Behera@Sun.COM 	{0x1d987, 0x1002},
334112103SSantwona.Behera@Sun.COM 	{0x1d988, 0x20d4},
334212103SSantwona.Behera@Sun.COM 	{0x1d989, 0x3c24},
334312103SSantwona.Behera@Sun.COM 	{0x1d98a, 0x2025},
334412103SSantwona.Behera@Sun.COM 	{0x1d98b, 0x3005},
334512103SSantwona.Behera@Sun.COM 	{0x1d98c, 0x6524},
334612103SSantwona.Behera@Sun.COM 	{0x1d98d, 0x1002},
334712103SSantwona.Behera@Sun.COM 	{0x1d98e, 0xd019},
334812103SSantwona.Behera@Sun.COM 	{0x1d98f, 0x2104},
334912103SSantwona.Behera@Sun.COM 	{0x1d990, 0x3c24},
335012103SSantwona.Behera@Sun.COM 	{0x1d991, 0x2105},
335112103SSantwona.Behera@Sun.COM 	{0x1d992, 0x3805},
335212103SSantwona.Behera@Sun.COM 	{0x1d993, 0x6524},
335312103SSantwona.Behera@Sun.COM 	{0x1d994, 0xdff4},
335412103SSantwona.Behera@Sun.COM 	{0x1d995, 0x4005},
335512103SSantwona.Behera@Sun.COM 	{0x1d996, 0x6524},
335612103SSantwona.Behera@Sun.COM 	{0x1d997, 0x2e8d},
335712103SSantwona.Behera@Sun.COM 	{0x1d998, 0x303d},
335812103SSantwona.Behera@Sun.COM 	{0x1d999, 0x2408},
335912103SSantwona.Behera@Sun.COM 	{0x1d99a, 0x35d8},
336012103SSantwona.Behera@Sun.COM 	{0x1d99b, 0x5dd3},
336112103SSantwona.Behera@Sun.COM 	{0x1d99c, 0x0307},
336212103SSantwona.Behera@Sun.COM 	{0x1d99d, 0x8887},
336312103SSantwona.Behera@Sun.COM 	{0x1d99e, 0x63a7},
336412103SSantwona.Behera@Sun.COM 	{0x1d99f, 0x8887},
336512103SSantwona.Behera@Sun.COM 	{0x1d9a0, 0x63a7},
336612103SSantwona.Behera@Sun.COM 	{0x1d9a1, 0xdffd},
336712103SSantwona.Behera@Sun.COM 	{0x1d9a2, 0x00f9},
336812103SSantwona.Behera@Sun.COM 	{0x1d9a3, 0x1002},
336912103SSantwona.Behera@Sun.COM 	{0x1d9a4, 0x866a},
337012103SSantwona.Behera@Sun.COM 	{0x1d9a5, 0x6138},
337112103SSantwona.Behera@Sun.COM 	{0x1d9a6, 0x5883},
337212103SSantwona.Behera@Sun.COM 	{0x1d9a7, 0x2b42},
337312103SSantwona.Behera@Sun.COM 	{0x1d9a8, 0x3022},
337412103SSantwona.Behera@Sun.COM 	{0x1d9a9, 0x1302},
337512103SSantwona.Behera@Sun.COM 	{0x1d9aa, 0x2ff7},
337612103SSantwona.Behera@Sun.COM 	{0x1d9ab, 0x3007},
337712103SSantwona.Behera@Sun.COM 	{0x1d9ac, 0x8785},
337812103SSantwona.Behera@Sun.COM 	{0x1d9ad, 0xb887},
337912103SSantwona.Behera@Sun.COM 	{0x1d9ae, 0x8786},
338012103SSantwona.Behera@Sun.COM 	{0x1d9af, 0xb8c6},
338112103SSantwona.Behera@Sun.COM 	{0x1d9b0, 0x5a53},
338212103SSantwona.Behera@Sun.COM 	{0x1d9b1, 0x2a52},
338312103SSantwona.Behera@Sun.COM 	{0x1d9b2, 0x3022},
338412103SSantwona.Behera@Sun.COM 	{0x1d9b3, 0x13c2},
338512103SSantwona.Behera@Sun.COM 	{0x1d9b4, 0x2474},
338612103SSantwona.Behera@Sun.COM 	{0x1d9b5, 0x3c84},
338712103SSantwona.Behera@Sun.COM 	{0x1d9b6, 0x64d7},
338812103SSantwona.Behera@Sun.COM 	{0x1d9b7, 0x64d7},
338912103SSantwona.Behera@Sun.COM 	{0x1d9b8, 0x2ff5},
339012103SSantwona.Behera@Sun.COM 	{0x1d9b9, 0x3c05},
339112103SSantwona.Behera@Sun.COM 	{0x1d9ba, 0x8757},
339212103SSantwona.Behera@Sun.COM 	{0x1d9bb, 0xb886},
339312103SSantwona.Behera@Sun.COM 	{0x1d9bc, 0x9767},
339412103SSantwona.Behera@Sun.COM 	{0x1d9bd, 0x67c4},
339512103SSantwona.Behera@Sun.COM 	{0x1d9be, 0x6f72},
339612103SSantwona.Behera@Sun.COM 	{0x1d9bf, 0x1002},
339712103SSantwona.Behera@Sun.COM 	{0x1d9c0, 0x0000},
339812103SSantwona.Behera@Sun.COM 	{0x1d080, 0x0100},
339912103SSantwona.Behera@Sun.COM 	{0x1d092, 0x0000},
340012103SSantwona.Behera@Sun.COM 	{NLP_INI_STOP, 0},
340112103SSantwona.Behera@Sun.COM };
340212103SSantwona.Behera@Sun.COM 
340312103SSantwona.Behera@Sun.COM static nxge_status_t
nxge_nlp2020_xcvr_init(p_nxge_t nxgep)340412103SSantwona.Behera@Sun.COM nxge_nlp2020_xcvr_init(p_nxge_t nxgep)
340512103SSantwona.Behera@Sun.COM {
340612103SSantwona.Behera@Sun.COM 	uint8_t			phy_port_addr;
340712103SSantwona.Behera@Sun.COM 	nxge_status_t		status = NXGE_OK;
340812103SSantwona.Behera@Sun.COM 	uint16_t		ctrl_reg, rst_val, pmd_ctl, rx_los;
340912103SSantwona.Behera@Sun.COM 	int			i = 0, count = 1000;
341012103SSantwona.Behera@Sun.COM 
341112103SSantwona.Behera@Sun.COM 	uint8_t			connector = 0, len, lpm;
341212103SSantwona.Behera@Sun.COM 	p_nxge_nlp_initseq_t	initseq;
341312103SSantwona.Behera@Sun.COM 	uint16_t		dev, reg, val;
341412103SSantwona.Behera@Sun.COM 
341512103SSantwona.Behera@Sun.COM 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_nlp2020_xcvr_init: "
341612103SSantwona.Behera@Sun.COM 	    "port<%d>, phyaddr[0x%x]", nxgep->mac.portnum,
341712103SSantwona.Behera@Sun.COM 	    nxgep->statsp->mac_stats.xcvr_portn));
341812103SSantwona.Behera@Sun.COM 
341912103SSantwona.Behera@Sun.COM 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
342012103SSantwona.Behera@Sun.COM 
342112103SSantwona.Behera@Sun.COM 	/* Reset the transceiver */
342212103SSantwona.Behera@Sun.COM 	rst_val = ctrl_reg = NLP2020_PMA_PMD_PHY_RST;
342312103SSantwona.Behera@Sun.COM 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
342412103SSantwona.Behera@Sun.COM 	    NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, rst_val))
342512103SSantwona.Behera@Sun.COM 	    != NXGE_OK)
342612103SSantwona.Behera@Sun.COM 		goto fail;
342712103SSantwona.Behera@Sun.COM 	while ((count--) && (ctrl_reg & rst_val)) {
342812103SSantwona.Behera@Sun.COM 		drv_usecwait(1000);
342912103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_read(nxgep, phy_port_addr,
343012103SSantwona.Behera@Sun.COM 		    NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, &ctrl_reg);
343112103SSantwona.Behera@Sun.COM 	}
343212103SSantwona.Behera@Sun.COM 	if (count == 0) {
343312103SSantwona.Behera@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_nlp2020_xcvr_init: "
343412103SSantwona.Behera@Sun.COM 		    "PMA_PMD reset failed"));
343512103SSantwona.Behera@Sun.COM 		goto fail;
343612103SSantwona.Behera@Sun.COM 	}
343712103SSantwona.Behera@Sun.COM 
343812103SSantwona.Behera@Sun.COM 	/* Set loopback mode if required */
343912103SSantwona.Behera@Sun.COM 	/* Set PMA PMD system loopback */
344012103SSantwona.Behera@Sun.COM 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
344112103SSantwona.Behera@Sun.COM 	    NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, &pmd_ctl))
344212103SSantwona.Behera@Sun.COM 	    != NXGE_OK)
344312103SSantwona.Behera@Sun.COM 		goto fail;
344412103SSantwona.Behera@Sun.COM 
344512103SSantwona.Behera@Sun.COM 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
344612103SSantwona.Behera@Sun.COM 		pmd_ctl |= 0x0001;
344712103SSantwona.Behera@Sun.COM 	else
344812103SSantwona.Behera@Sun.COM 		pmd_ctl &= 0xfffe;
344912103SSantwona.Behera@Sun.COM 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
345012103SSantwona.Behera@Sun.COM 	    NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, pmd_ctl))
345112103SSantwona.Behera@Sun.COM 	    != NXGE_OK)
345212103SSantwona.Behera@Sun.COM 		goto fail;
345312103SSantwona.Behera@Sun.COM 
345412103SSantwona.Behera@Sun.COM 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_nlp2020_xcvr_init: "
345512103SSantwona.Behera@Sun.COM 	    "setting LB, wrote NLP2020_PMA_PMD_CTL_REG[0x%x]", pmd_ctl));
345612103SSantwona.Behera@Sun.COM 
345712103SSantwona.Behera@Sun.COM 	/* Check connector details using I2c */
345812103SSantwona.Behera@Sun.COM 	if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
345912103SSantwona.Behera@Sun.COM 	    QSFP_MSA_CONN_REG, &connector) == 1) {
346012103SSantwona.Behera@Sun.COM 		goto fail;
346112103SSantwona.Behera@Sun.COM 	}
346212103SSantwona.Behera@Sun.COM 
346312103SSantwona.Behera@Sun.COM 	switch (connector) {
346412103SSantwona.Behera@Sun.COM 	case SFPP_FIBER:
346512103SSantwona.Behera@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
346612103SSantwona.Behera@Sun.COM 		    "nxge_nlp2020_xcvr_init: SFPP_FIBER detected"));
346712103SSantwona.Behera@Sun.COM 		initseq = nlp2020_revC_fiber_init;
346812103SSantwona.Behera@Sun.COM 		nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
346912103SSantwona.Behera@Sun.COM 		break;
347012103SSantwona.Behera@Sun.COM 	case QSFP_FIBER:
347112103SSantwona.Behera@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
347212103SSantwona.Behera@Sun.COM 		    "nxge_nlp2020_xcvr_init: QSFP_FIBER detected"));
347312103SSantwona.Behera@Sun.COM 		initseq = nlp2020_revC_fiber_init;
347412103SSantwona.Behera@Sun.COM 		nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
347512103SSantwona.Behera@Sun.COM 		break;
347612103SSantwona.Behera@Sun.COM 	case QSFP_COPPER_TWINAX:
347712103SSantwona.Behera@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
347812103SSantwona.Behera@Sun.COM 		    "nxge_nlp2020_xcvr_init: QSFP_COPPER_TWINAX/"
347912103SSantwona.Behera@Sun.COM 		    "SFPP_COPPER_TWINAX detected"));
348012103SSantwona.Behera@Sun.COM 
348112103SSantwona.Behera@Sun.COM 		initseq = nlp2020_revC_copper_init;
348212103SSantwona.Behera@Sun.COM 		nxgep->nlp_conn = NXGE_NLP_CONN_COPPER_LT_7M;
348312103SSantwona.Behera@Sun.COM 		break;
348412103SSantwona.Behera@Sun.COM 	default:
348512103SSantwona.Behera@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
348612103SSantwona.Behera@Sun.COM 		    "nxge_nlp2020_xcvr_init: Unknown type [0x%x] detected",
348712103SSantwona.Behera@Sun.COM 		    "...setting to QSFP_FIBER",
348812103SSantwona.Behera@Sun.COM 		    connector));
348912103SSantwona.Behera@Sun.COM 		initseq = nlp2020_revC_fiber_init;
349012103SSantwona.Behera@Sun.COM 		nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
349112103SSantwona.Behera@Sun.COM 		break;
349212103SSantwona.Behera@Sun.COM 	}
349312103SSantwona.Behera@Sun.COM 
349412103SSantwona.Behera@Sun.COM 	/* Run appropriate init sequence */
349512103SSantwona.Behera@Sun.COM 	for (i = 0; initseq[i].dev_reg != NLP_INI_STOP; i++) {
349612103SSantwona.Behera@Sun.COM 		dev = initseq[i].dev_reg >> 16;
349712103SSantwona.Behera@Sun.COM 		reg = initseq[i].dev_reg & 0xffff;
349812103SSantwona.Behera@Sun.COM 		val = initseq[i].val;
349912103SSantwona.Behera@Sun.COM 
350012103SSantwona.Behera@Sun.COM 		if (reg == NLP_INI_WAIT) {
350112103SSantwona.Behera@Sun.COM 			drv_usecwait(1000 * val);
350212103SSantwona.Behera@Sun.COM 		} else {
350312103SSantwona.Behera@Sun.COM 			if ((status = nxge_mdio_write(nxgep, phy_port_addr,
350412103SSantwona.Behera@Sun.COM 			    dev, reg, val)) != NXGE_OK)
350512103SSantwona.Behera@Sun.COM 				goto fail;
350612103SSantwona.Behera@Sun.COM 		}
350712103SSantwona.Behera@Sun.COM 	}
350812103SSantwona.Behera@Sun.COM 
350912103SSantwona.Behera@Sun.COM 	/* rx_los inversion */
351012103SSantwona.Behera@Sun.COM 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
351112103SSantwona.Behera@Sun.COM 	    NLP2020_PMA_PMD_ADDR, NLP2020_OPT_SET_REG, &rx_los)) != NXGE_OK)
351212103SSantwona.Behera@Sun.COM 			goto fail;
351312103SSantwona.Behera@Sun.COM 
351412103SSantwona.Behera@Sun.COM 	rx_los &= ~(NLP2020_RXLOS_ACT_H);
351512103SSantwona.Behera@Sun.COM 
351612103SSantwona.Behera@Sun.COM 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
351712103SSantwona.Behera@Sun.COM 	    NLP2020_PMA_PMD_ADDR, NLP2020_OPT_SET_REG, rx_los)) != NXGE_OK)
351812103SSantwona.Behera@Sun.COM 			goto fail;
351912103SSantwona.Behera@Sun.COM 
352012103SSantwona.Behera@Sun.COM 	if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
352112103SSantwona.Behera@Sun.COM 	    QSFP_MSA_LEN_REG, &len) == 1) {
352212103SSantwona.Behera@Sun.COM 		goto fail;
352312103SSantwona.Behera@Sun.COM 	}
352412103SSantwona.Behera@Sun.COM 
352512103SSantwona.Behera@Sun.COM 	if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
352612103SSantwona.Behera@Sun.COM 	    QSFP_MSA_LPM_REG, &lpm) == 1) {
352712103SSantwona.Behera@Sun.COM 		goto fail;
352812103SSantwona.Behera@Sun.COM 	}
352912103SSantwona.Behera@Sun.COM 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
353012103SSantwona.Behera@Sun.COM 	    "nxge_nlp2020_xcvr_init: len[0x%x] lpm[0x%x]", len, lpm));
353112103SSantwona.Behera@Sun.COM 
353212103SSantwona.Behera@Sun.COM 	if (connector == QSFP_COPPER_TWINAX) {
353312103SSantwona.Behera@Sun.COM 		if (len >= 7) {
353412103SSantwona.Behera@Sun.COM 			nxgep->nlp_conn = NXGE_NLP_CONN_COPPER_7M_ABOVE;
353512103SSantwona.Behera@Sun.COM 			/* enable pre-emphasis */
353612103SSantwona.Behera@Sun.COM 			(void) nxge_mdio_write(nxgep, phy_port_addr,
353712103SSantwona.Behera@Sun.COM 			    NLP2020_PMA_PMD_ADDR, NLP2020_TX_DRV_CTL1_REG,
353812103SSantwona.Behera@Sun.COM 			    NLP2020_TX_DRV_CTL1_PREEMP_EN);
353912103SSantwona.Behera@Sun.COM 			/* write emphasis value */
354012103SSantwona.Behera@Sun.COM 			(void) nxge_mdio_write(nxgep, phy_port_addr,
354112103SSantwona.Behera@Sun.COM 			    NLP2020_PMA_PMD_ADDR, NLP2020_TX_DRV_CTL2_REG,
354212103SSantwona.Behera@Sun.COM 			    NLP2020_TX_DRV_CTL2_EMP_VAL);
354312103SSantwona.Behera@Sun.COM 			/* stop microcontroller */
354412103SSantwona.Behera@Sun.COM 			(void) nxge_mdio_write(nxgep, phy_port_addr,
354512103SSantwona.Behera@Sun.COM 			    NLP2020_PMA_PMD_ADDR, NLP2020_UC_CTL_REG,
354612103SSantwona.Behera@Sun.COM 			    NLP2020_UC_CTL_STOP);
354712103SSantwona.Behera@Sun.COM 			/* reset program counter */
354812103SSantwona.Behera@Sun.COM 			(void) nxge_mdio_write(nxgep, phy_port_addr,
354912103SSantwona.Behera@Sun.COM 			    NLP2020_PMA_PMD_ADDR, NLP2020_UC_PC_START_REG,
355012103SSantwona.Behera@Sun.COM 			    NLP2020_UC_PC_START_VAL);
355112103SSantwona.Behera@Sun.COM 			/* start microcontroller */
355212103SSantwona.Behera@Sun.COM 			(void) nxge_mdio_write(nxgep, phy_port_addr,
355312103SSantwona.Behera@Sun.COM 			    NLP2020_PMA_PMD_ADDR, NLP2020_UC_CTL_REG,
355412103SSantwona.Behera@Sun.COM 			    NLP2020_UC_CTL_START);
355512103SSantwona.Behera@Sun.COM 		}
355612103SSantwona.Behera@Sun.COM 	}
355712103SSantwona.Behera@Sun.COM 	if (lpm & QSFP_MSA_LPM_HIGH) {
355812103SSantwona.Behera@Sun.COM 		/* enable high power mode */
355912103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_write(nxgep, phy_port_addr,
356012103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG,
356112103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_ACT);
356212103SSantwona.Behera@Sun.COM 	} else {
356312103SSantwona.Behera@Sun.COM 		/* revert to low power mode */
356412103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_write(nxgep, phy_port_addr,
356512103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG,
356612103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_INACT);
356712103SSantwona.Behera@Sun.COM 	}
3568*12452SSantwona.Behera@oracle.COM 
3569*12452SSantwona.Behera@oracle.COM 	/*
3570*12452SSantwona.Behera@oracle.COM 	 * Set XAUI link tunables from OBP if present.
3571*12452SSantwona.Behera@oracle.COM 	 */
3572*12452SSantwona.Behera@oracle.COM 	NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
3573*12452SSantwona.Behera@oracle.COM 	if (status != NXGE_OK) {
3574*12452SSantwona.Behera@oracle.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3575*12452SSantwona.Behera@oracle.COM 		    "nxge_nlp2020_xcvr_init: Failed setting PHY tunables"));
3576*12452SSantwona.Behera@oracle.COM 		goto fail;
3577*12452SSantwona.Behera@oracle.COM 	}
3578*12452SSantwona.Behera@oracle.COM 
357912103SSantwona.Behera@Sun.COM 	/* It takes ~2s for EDC to settle */
358012103SSantwona.Behera@Sun.COM 	drv_usecwait(2000000);
358112103SSantwona.Behera@Sun.COM 
358212103SSantwona.Behera@Sun.COM 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_nlp2020_xcvr_init: "
358312103SSantwona.Behera@Sun.COM 	    "port<%d> phyaddr[0x%x]", nxgep->mac.portnum, phy_port_addr));
358412103SSantwona.Behera@Sun.COM 
358512103SSantwona.Behera@Sun.COM 	return (NXGE_OK);
358612103SSantwona.Behera@Sun.COM 
358712103SSantwona.Behera@Sun.COM fail:
358812103SSantwona.Behera@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
358912103SSantwona.Behera@Sun.COM 	    "nxge_nlp2020_xcvr_init: failed to initialize transceiver for "
359012103SSantwona.Behera@Sun.COM 	    "port<%d>", nxgep->mac.portnum));
359112103SSantwona.Behera@Sun.COM 	return (status);
359212103SSantwona.Behera@Sun.COM }
359312103SSantwona.Behera@Sun.COM 
nxge_is_nlp2020_phy(p_nxge_t nxgep)359412103SSantwona.Behera@Sun.COM static boolean_t nxge_is_nlp2020_phy(p_nxge_t nxgep)
359512103SSantwona.Behera@Sun.COM {
359612103SSantwona.Behera@Sun.COM 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
359712103SSantwona.Behera@Sun.COM 	uint32_t	pcs_id = 0;
359812103SSantwona.Behera@Sun.COM 	uint32_t	pma_pmd_id = 0;
359912103SSantwona.Behera@Sun.COM 	uint8_t		xcvr_addr =  nxgep->nxge_hw_p->xcvr_addr[portn];
360012103SSantwona.Behera@Sun.COM 
360112103SSantwona.Behera@Sun.COM 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, xcvr_addr);
360212103SSantwona.Behera@Sun.COM 	pcs_id = nxge_get_cl45_pcs_id(nxgep, xcvr_addr);
360312103SSantwona.Behera@Sun.COM 
360412103SSantwona.Behera@Sun.COM 	if (((pma_pmd_id & NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID) ||
360512103SSantwona.Behera@Sun.COM 	    ((pcs_id & NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID)) {
360612103SSantwona.Behera@Sun.COM 		return (B_TRUE);
360712103SSantwona.Behera@Sun.COM 	} else {
360812103SSantwona.Behera@Sun.COM 		return (B_FALSE);
360912103SSantwona.Behera@Sun.COM 	}
361012103SSantwona.Behera@Sun.COM }
361112103SSantwona.Behera@Sun.COM 
nxge_get_nlp2020_connector_type(p_nxge_t nxgep)361212103SSantwona.Behera@Sun.COM static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t nxgep)
361312103SSantwona.Behera@Sun.COM {
361412103SSantwona.Behera@Sun.COM 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
361512103SSantwona.Behera@Sun.COM 	uint8_t xcvr_addr =  nxgep->nxge_hw_p->xcvr_addr[portn];
361612103SSantwona.Behera@Sun.COM 	uint8_t	connector = 0;
361712103SSantwona.Behera@Sun.COM 
361812103SSantwona.Behera@Sun.COM 	(void) nxge_nlp2020_i2c_read(nxgep, xcvr_addr, NLP2020_XCVR_I2C_ADDR,
361912103SSantwona.Behera@Sun.COM 	    QSFP_MSA_CONN_REG, &connector);
362012103SSantwona.Behera@Sun.COM 
362112103SSantwona.Behera@Sun.COM 	return (connector);
362212103SSantwona.Behera@Sun.COM }
362312103SSantwona.Behera@Sun.COM 
nxge_set_nlp2020_param(p_nxge_t nxgep)362412103SSantwona.Behera@Sun.COM static nxge_status_t nxge_set_nlp2020_param(p_nxge_t nxgep)
362512103SSantwona.Behera@Sun.COM {
362612103SSantwona.Behera@Sun.COM 	uint8_t connector = 0;
362712103SSantwona.Behera@Sun.COM 
362812103SSantwona.Behera@Sun.COM 	connector = nxge_get_nlp2020_connector_type(nxgep);
362912103SSantwona.Behera@Sun.COM 
363012103SSantwona.Behera@Sun.COM 	switch (connector) {
363112103SSantwona.Behera@Sun.COM 	case SFPP_FIBER:
363212103SSantwona.Behera@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
363312103SSantwona.Behera@Sun.COM 		    "nxge_set_nlp2020_param: SFPP_FIBER detected"));
363412103SSantwona.Behera@Sun.COM 		nxgep->mac.portmode = PORT_10G_FIBER;
363512103SSantwona.Behera@Sun.COM 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
363612103SSantwona.Behera@Sun.COM 		break;
363712103SSantwona.Behera@Sun.COM 	case QSFP_FIBER:
363812103SSantwona.Behera@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
363912103SSantwona.Behera@Sun.COM 		    "nxge_set_nlp2020_param: QSFP_FIBER detected"));
364012103SSantwona.Behera@Sun.COM 		nxgep->mac.portmode = PORT_10G_FIBER;
364112103SSantwona.Behera@Sun.COM 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
364212103SSantwona.Behera@Sun.COM 		break;
364312103SSantwona.Behera@Sun.COM 	case QSFP_COPPER_TWINAX:
364412103SSantwona.Behera@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
364512103SSantwona.Behera@Sun.COM 		    "nxge_set_nlp2020_param: QSFP_COPPER_TWINAX/"
364612103SSantwona.Behera@Sun.COM 		    "SFPP_COPPER_TWINAX detected"));
364712103SSantwona.Behera@Sun.COM 		nxgep->mac.portmode = PORT_10G_COPPER;
364812103SSantwona.Behera@Sun.COM 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
364912103SSantwona.Behera@Sun.COM 		break;
365012103SSantwona.Behera@Sun.COM 	default:
365112103SSantwona.Behera@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
365212103SSantwona.Behera@Sun.COM 		    "nxge_set_nlp2020_param: Unknown type [0x%x] detected"
365312103SSantwona.Behera@Sun.COM 		    "...setting to QSFP_FIBER",
365412103SSantwona.Behera@Sun.COM 		    connector));
365512103SSantwona.Behera@Sun.COM 		nxgep->mac.portmode = PORT_10G_FIBER;
365612103SSantwona.Behera@Sun.COM 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
365712103SSantwona.Behera@Sun.COM 		break;
365812103SSantwona.Behera@Sun.COM 	}
365912103SSantwona.Behera@Sun.COM 
366012103SSantwona.Behera@Sun.COM 	return (NXGE_OK);
366112103SSantwona.Behera@Sun.COM }
366212103SSantwona.Behera@Sun.COM 
36636604Ssbehera #define	CHK_STAT(x)	status = (x); if (status != NXGE_OK) goto fail
36646604Ssbehera 
36656604Ssbehera #define	MRVL88X2011_RD(nxgep, port, d, r, p) \
36666604Ssbehera 	CHK_STAT(nxge_mdio_read(nxgep, port, d, r, p))
36676604Ssbehera 
36686604Ssbehera #define	MRVL88X2011_WR(nxgep, port, d, r, p) \
36696604Ssbehera 	CHK_STAT(nxge_mdio_write(nxgep, port, d, r, p))
36706604Ssbehera 
36716604Ssbehera 
36726604Ssbehera static void
nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep,uint16_t rate)36736604Ssbehera nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep, uint16_t rate)
36746604Ssbehera {
36756604Ssbehera 	uint16_t	value;
36766604Ssbehera 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
36776604Ssbehera 
36786604Ssbehera 	if (nxge_mdio_read(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR,
36796604Ssbehera 	    MRVL_88X2011_LED_BLINK_CTL, &value) == NXGE_OK) {
36806604Ssbehera 		value &= ~MRVL_88X2011_LED_BLK_MASK;
36816604Ssbehera 		value |= (rate << MRVL_88X2011_LED_BLK_SHIFT);
36826604Ssbehera 		(void) nxge_mdio_write(nxgep, phy,
36836604Ssbehera 		    MRVL_88X2011_USER_DEV2_ADDR, MRVL_88X2011_LED_BLINK_CTL,
36846604Ssbehera 		    value);
36856604Ssbehera 	}
36866604Ssbehera }
36876604Ssbehera 
36886604Ssbehera static nxge_status_t
nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep)36896604Ssbehera nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep)
36906604Ssbehera {
36916604Ssbehera 	nxge_status_t	status;
36926604Ssbehera 	pcs_control_t	pcs_ctl;
36936604Ssbehera 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
36946604Ssbehera 
36956604Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
36966604Ssbehera 	    MRVL_88X2011_PMA_PMD_CTL_1, &pcs_ctl.value);
36976604Ssbehera 
36986604Ssbehera 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
36996604Ssbehera 		pcs_ctl.bits.loopback = 1;
37006604Ssbehera 	else
37016604Ssbehera 		pcs_ctl.bits.loopback = 0;
37026604Ssbehera 
37036604Ssbehera 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
37046604Ssbehera 	    MRVL_88X2011_PMA_PMD_CTL_1, pcs_ctl.value);
37056604Ssbehera 
37066604Ssbehera fail:
37076604Ssbehera 	return (status);
37086604Ssbehera }
37096604Ssbehera 
37106604Ssbehera 
37116604Ssbehera static void
nxge_mrvl88x2011_led(p_nxge_t nxgep,uint16_t val)37126604Ssbehera nxge_mrvl88x2011_led(p_nxge_t nxgep,  uint16_t val)
37136604Ssbehera {
37146604Ssbehera 	uint16_t	val2;
37156604Ssbehera 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
37166604Ssbehera 
37176604Ssbehera 	val2 = MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val);
37186604Ssbehera 	val2 &= ~MRVL_88X2011_LED(MRVL_88X2011_LED_ACT,
37196604Ssbehera 	    MRVL_88X2011_LED_CTL_MASK);
37206604Ssbehera 	val2 |= MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val);
37216604Ssbehera 
37226604Ssbehera 	if (nxge_mdio_write(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR,
37236604Ssbehera 	    MRVL_88X2011_LED_8_TO_11_CTL, val2) != NXGE_OK) {
37246604Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
37256604Ssbehera 		    "nxge_mrvl88x2011_led: nxge_mdio_write failed!!"));
37266604Ssbehera 	}
37276604Ssbehera }
37286604Ssbehera 
37296604Ssbehera 
37306604Ssbehera static nxge_status_t
nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep)37316604Ssbehera nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep)
37326604Ssbehera {
37336604Ssbehera 	uint8_t		phy;
37346604Ssbehera 	nxge_status_t	status;
37356604Ssbehera 	uint16_t	clk;
37366604Ssbehera 
37376604Ssbehera 	phy = nxgep->statsp->mac_stats.xcvr_portn;
37386604Ssbehera 
37396604Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
37406604Ssbehera 	    "==> nxge_mrvl88x2011_xcvr_init: port<%d> addr<0x%x>",
37416604Ssbehera 	    nxgep->mac.portnum, phy));
37426604Ssbehera 
37436604Ssbehera 	/* Set LED functions	*/
37446604Ssbehera 	nxge_mrvl88x2011_led_blink_rate(nxgep, MRVL_88X2011_LED_BLK134MS);
37456604Ssbehera 	/* PCS activity */
37466604Ssbehera 	nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_ACT);
37476604Ssbehera 
37486604Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
37496604Ssbehera 	    MRVL_88X2011_GEN_CTL, &clk);
37506604Ssbehera 	clk |= MRVL_88X2011_ENA_XFPREFCLK;
37516604Ssbehera 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
37526604Ssbehera 	    MRVL_88X2011_GEN_CTL, clk);
37536604Ssbehera 
37546604Ssbehera 	/* Set internal loopback mode if necessary */
37556604Ssbehera 
37566604Ssbehera 	CHK_STAT(nxge_mrvl88x2011_setup_lb(nxgep));
37576604Ssbehera 
37586604Ssbehera 	/* Enable PMD */
37596604Ssbehera 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
37606604Ssbehera 	    MRVL_88X2011_10G_PMD_TX_DIS, MRVL_88X2011_ENA_PMDTX);
37616604Ssbehera 
37626604Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, " nxge_mrvl88x2011_reset: OK"));
37636604Ssbehera 
37646604Ssbehera fail:
37656604Ssbehera 	return (status);
37666604Ssbehera }
37676604Ssbehera 
37686604Ssbehera 
37696604Ssbehera 
37705572Ssbehera /* Initialize the 10G Transceiver */
37715572Ssbehera 
37725572Ssbehera static nxge_status_t
nxge_10G_xcvr_init(p_nxge_t nxgep)37735572Ssbehera nxge_10G_xcvr_init(p_nxge_t nxgep)
37745572Ssbehera {
37755572Ssbehera 	p_nxge_stats_t		statsp;
37766439Sml29623 	p_nxge_param_t		param_arr = nxgep->param_arr;
37775572Ssbehera 	nxge_status_t		status = NXGE_OK;
37785572Ssbehera #ifdef	NXGE_DEBUG
37795572Ssbehera 	uint8_t			portn = nxgep->mac.portnum;
37805572Ssbehera #endif
37815572Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
37825572Ssbehera 	    portn));
37835572Ssbehera 
37845572Ssbehera 	statsp = nxgep->statsp;
37855572Ssbehera 
37869599Stc99174@train 	/* Disable Link LEDs, with or without PHY */
37879599Stc99174@train 	if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
37885572Ssbehera 		goto done;
37899599Stc99174@train 
37909599Stc99174@train 	/* Skip MDIO, if PHY absent */
37919599Stc99174@train 	if (nxgep->mac.portmode == PORT_10G_SERDES || nxgep->phy_absent) {
37929599Stc99174@train 		goto done;
37939599Stc99174@train 	}
37945572Ssbehera 
37955572Ssbehera 	/* Set Clause 45 */
37965572Ssbehera 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
37975572Ssbehera 
37985572Ssbehera 	switch (nxgep->chip_id) {
37995572Ssbehera 	case BCM8704_CHIP_ID:
38006835Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
38015572Ssbehera 		    "Chip ID 8704 [0x%x] for 10G xcvr", nxgep->chip_id));
38025572Ssbehera 		status = nxge_BCM8704_xcvr_init(nxgep);
38035572Ssbehera 		break;
38045572Ssbehera 	case BCM8706_CHIP_ID:
38056835Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
38065572Ssbehera 		    "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id));
38075572Ssbehera 		status = nxge_BCM8706_xcvr_init(nxgep);
38085572Ssbehera 		break;
38096604Ssbehera 	case MRVL88X201X_CHIP_ID:
38106835Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
381112103SSantwona.Behera@Sun.COM 		    "Chip ID MRVL [0x%x] for 10G xcvr", nxgep->chip_id));
38126604Ssbehera 		status = nxge_mrvl88x2011_xcvr_init(nxgep);
38136604Ssbehera 		break;
381412103SSantwona.Behera@Sun.COM 	case NLP2020_CHIP_ID:
381512103SSantwona.Behera@Sun.COM 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
381612103SSantwona.Behera@Sun.COM 		    "Chip ID NL2020 [0x%x] for 10G xcvr", nxgep->chip_id));
381712103SSantwona.Behera@Sun.COM 		status = nxge_nlp2020_xcvr_init(nxgep);
381812103SSantwona.Behera@Sun.COM 		break;
38195572Ssbehera 	default:
38205572Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_xcvr_init: "
38215572Ssbehera 		    "Unknown chip ID 0x%x for 10G xcvr addr[%d]",
38225572Ssbehera 		    nxgep->chip_id, nxgep->statsp->mac_stats.xcvr_portn));
38235572Ssbehera 		goto fail;
38245572Ssbehera 	}
38255572Ssbehera 
38265572Ssbehera 	if (status != NXGE_OK) {
38275572Ssbehera 		goto fail;
38285572Ssbehera 	}
38294977Sraghus done:
38304732Sdavemq 	statsp->mac_stats.cap_10gfdx = 1;
38314732Sdavemq 	statsp->mac_stats.lp_cap_10gfdx = 1;
38326439Sml29623 	statsp->mac_stats.adv_cap_asmpause =
38336439Sml29623 	    param_arr[param_anar_asmpause].value;
38346439Sml29623 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
38354732Sdavemq 
38364732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
38374732Sdavemq 	    portn));
38384732Sdavemq 	return (NXGE_OK);
38394732Sdavemq 
38404732Sdavemq fail:
38415572Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
38424732Sdavemq 	    "nxge_10G_xcvr_init: failed to initialize transceiver for "
38435572Ssbehera 	    "port<%d>", nxgep->mac.portnum));
38445572Ssbehera 	return (NXGE_ERROR);
38454732Sdavemq }
38464732Sdavemq 
38474732Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */
38484732Sdavemq 
38494732Sdavemq static nxge_status_t
nxge_1G_xcvr_init(p_nxge_t nxgep)38504732Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep)
38514732Sdavemq {
38524732Sdavemq 	p_nxge_param_t		param_arr = nxgep->param_arr;
38534732Sdavemq 	p_nxge_stats_t		statsp = nxgep->statsp;
38544732Sdavemq 	nxge_status_t		status = NXGE_OK;
38554732Sdavemq 
38564977Sraghus 	if (nxgep->mac.portmode == PORT_1G_SERDES) {
38574977Sraghus 		statsp->mac_stats.cap_1000fdx =
38584977Sraghus 		    param_arr[param_anar_1000fdx].value;
38594977Sraghus 		goto done;
38604977Sraghus 	}
38614977Sraghus 
38624732Sdavemq 	/* Set Clause 22 */
38634732Sdavemq 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
38644732Sdavemq 
38654732Sdavemq 	/* Set capability flags */
38664732Sdavemq 	statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value;
38674977Sraghus 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
38684977Sraghus 	    (nxgep->mac.portmode == PORT_1G_FIBER)) {
38694977Sraghus 		statsp->mac_stats.cap_100fdx =
38704977Sraghus 		    param_arr[param_anar_100fdx].value;
38714977Sraghus 		statsp->mac_stats.cap_10fdx =
38724977Sraghus 		    param_arr[param_anar_10fdx].value;
38734977Sraghus 	}
38744732Sdavemq 
38754732Sdavemq 	status = nxge_mii_xcvr_init(nxgep);
38764977Sraghus done:
38774732Sdavemq 	return (status);
38784732Sdavemq }
38794732Sdavemq 
38806835Syc148097 /*
38816835Syc148097  * Although the Teranetics copper transceiver (TN1010) does not need
38826835Syc148097  * to be initialized by the driver for passing packets, this funtion
38836835Syc148097  * initializes the members of nxgep->statsp->mac_stats struct for
38846835Syc148097  * kstat based on the value of nxgep->statsp->ports_stats.lb_mode.
38856835Syc148097  * It also configures the TN1010 for PHY loopback to support SunVTS.
38866835Syc148097  *
38876835Syc148097  * TN1010 only has the option to disable advertisement for the 10G
38886835Syc148097  * mode. So we can set it to either Dual Mode or 1G Only mode but
38896835Syc148097  * can't set it to 10G Only mode.
38906835Syc148097  *
38916835Syc148097  * ndd -set command can set the following 6 speed/duplex related parameters.
38926835Syc148097  *
38936835Syc148097  * ----------------------------------------------------------------
38946835Syc148097  * ndd -set /dev/nxgeX param n		kstat nxge:X | grep param
38956835Syc148097  * ----------------------------------------------------------------
38966835Syc148097  * adv_autoneg_cap		kstat nxge:1 | grep adv_cap_autoneg
38976835Syc148097  * adv_10gfdx_cap
38986835Syc148097  * adv_1000fdx_cap		kstat nxge:1 | grep adv_cap_1000fdx
38996835Syc148097  * adv_100fdx_cap		kstat nxge:1 | grep adv_cap_100fdx
39006835Syc148097  * adv_10fdx_cap		kstat nxge:1 | grep adv_cap_10fdx
39016835Syc148097  * adv_pause_cap		kstat nxge:1 | grep adv_cap_pause
39026835Syc148097  * ----------------------------------------------------------------
39036835Syc148097  */
39046835Syc148097 static nxge_status_t
nxge_tn1010_xcvr_init(p_nxge_t nxgep)39056835Syc148097 nxge_tn1010_xcvr_init(p_nxge_t nxgep)
39066835Syc148097 {
39076835Syc148097 	p_nxge_param_t		param_arr;
39086835Syc148097 	p_nxge_stats_t		statsp;
39096835Syc148097 	tn1010_pcs_ctrl_t	tn1010_pcs_ctrl;
39106835Syc148097 	uint16_t		speed;
39116835Syc148097 	uint8_t			phy_port_addr;
39126835Syc148097 	uint8_t			portn = NXGE_GET_PORT_NUM(nxgep->function_num);
39136835Syc148097 	int			status = NXGE_OK;
39146835Syc148097 
39156835Syc148097 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_1G_tn1010_xcvr_init"));
39166835Syc148097 
39176835Syc148097 	param_arr	= nxgep->param_arr;
39186835Syc148097 	statsp		= nxgep->statsp;
39196835Syc148097 
39206835Syc148097 	/*
39216835Syc148097 	 * Initialize the xcvr statistics which are NOT controlled by ndd
39226835Syc148097 	 */
39236835Syc148097 	statsp->mac_stats.cap_autoneg  = 1; /* TN1010 autoneg is always on */
39246835Syc148097 	statsp->mac_stats.cap_100T4    = 0;
39256835Syc148097 
39266835Syc148097 	/*
39276835Syc148097 	 * Read the TN1010 link speed and initialize capabilities kstat. Note
39286835Syc148097 	 * that function nxge_check_tn1010_link repeatedly invoked by the
39296835Syc148097 	 * timer will update link_speed real time.
39306835Syc148097 	 */
39316835Syc148097 	if (nxge_get_tn1010_speed(nxgep,  &speed) != NXGE_OK) {
39326835Syc148097 		goto fail;
39336835Syc148097 	}
39346835Syc148097 	if (speed == TN1010_SPEED_1G) {
39356835Syc148097 		statsp->mac_stats.cap_10gfdx = 0;
39366835Syc148097 	} else {
39376835Syc148097 		statsp->mac_stats.cap_10gfdx = 1;
39386835Syc148097 	}
39396835Syc148097 
39406835Syc148097 	/* Whether we are in 1G or 10G mode, we always have the 1G capability */
39416835Syc148097 	statsp->mac_stats.cap_1000fdx  = 1;
39426835Syc148097 
39436835Syc148097 	/* TN1010 is not able to operate in the following states */
39446835Syc148097 	statsp->mac_stats.cap_1000hdx  = 0;
39456835Syc148097 	statsp->mac_stats.cap_100fdx   = 0;
39466835Syc148097 	statsp->mac_stats.cap_100hdx   = 0;
39476835Syc148097 	statsp->mac_stats.cap_10fdx    = 0;
39486835Syc148097 	statsp->mac_stats.cap_10hdx    = 0;
39496835Syc148097 
39506835Syc148097 	/* param_anar_pause can be modified by ndd -set */
39516835Syc148097 	statsp->mac_stats.cap_pause    = param_arr[param_anar_pause].value;
39526835Syc148097 
39536835Syc148097 	/*
39546835Syc148097 	 * The following 4 lines actually overwrites what ever the ndd command
39556835Syc148097 	 * has set. For example, by command
39566835Syc148097 	 * 	ndd -set /dev/nxge1 adv_autoneg_cap n (n = 0 or 1)
39576835Syc148097 	 * we could set param_arr[param_autoneg].value to n.  However, because
39586835Syc148097 	 * here we assign constants to these parameters, whatever we set with
39596835Syc148097 	 * the "ndd -set" command will be replaced. So command
39606835Syc148097 	 *	kstat nxge:X | grep param
39616835Syc148097 	 * will always show those constant values.  In other words, the
39626835Syc148097 	 * "ndd -set" command can NOT change the values of these 4 parameters
39636835Syc148097 	 * even though the command appears to be successful.
39646835Syc148097 	 *
39656835Syc148097 	 * Note: TN1010 auto negotiation is always enabled.
39666835Syc148097 	 */
39676835Syc148097 	statsp->mac_stats.adv_cap_autoneg
39686835Syc148097 	    = param_arr[param_autoneg].value = 1;
39696835Syc148097 	statsp->mac_stats.adv_cap_1000fdx
39706835Syc148097 	    = param_arr[param_anar_1000fdx].value = 1;
39716835Syc148097 	statsp->mac_stats.adv_cap_100fdx
39726835Syc148097 	    = param_arr[param_anar_100fdx].value = 0;
39736835Syc148097 	statsp->mac_stats.adv_cap_10fdx
39746835Syc148097 	    = param_arr[param_anar_10fdx].value = 0;
39756835Syc148097 
39766835Syc148097 	/*
39776835Syc148097 	 * The following 4 ndd params have type NXGE_PARAM_MAC_DONT_SHOW as
39786835Syc148097 	 * defined in nxge_param_arr[], therefore they are not seen by the
39796835Syc148097 	 * "ndd -get" command and can not be changed by ndd.  We just set
39806835Syc148097 	 * them (both ndd param and kstat values) to constant 0 because TN1010
39816835Syc148097 	 * does not support those speeds.
39826835Syc148097 	 */
39836835Syc148097 	statsp->mac_stats.adv_cap_100T4
39846835Syc148097 	    = param_arr[param_anar_100T4].value = 0;
39856835Syc148097 	statsp->mac_stats.adv_cap_1000hdx
39866835Syc148097 	    = param_arr[param_anar_1000hdx].value = 0;
39876835Syc148097 	statsp->mac_stats.adv_cap_100hdx
39886835Syc148097 	    = param_arr[param_anar_100hdx].value = 0;
39896835Syc148097 	statsp->mac_stats.adv_cap_10hdx
39906835Syc148097 	    = param_arr[param_anar_10hdx].value = 0;
39916835Syc148097 
39926835Syc148097 	/*
39936835Syc148097 	 * adv_cap_pause has type NXGE_PARAM_MAC_RW, so it can be modified
39946835Syc148097 	 * by ndd
39956835Syc148097 	 */
39966835Syc148097 	statsp->mac_stats.adv_cap_pause    = param_arr[param_anar_pause].value;
39976835Syc148097 
39986835Syc148097 	/*
39996835Syc148097 	 * nxge_param_arr[] defines the adv_cap_asmpause with type
40006835Syc148097 	 * NXGE_PARAM_DONT_SHOW, therefore they are NOT seen by the
40016835Syc148097 	 * "ndd -get" command and can not be changed by ndd. Here we do not
40026835Syc148097 	 * assign a constant to it so the default value defined in
40036835Syc148097 	 * nxge_param_arr[] will be used to set the parameter and
40046835Syc148097 	 * will be shown by the kstat.
40056835Syc148097 	 */
40066835Syc148097 	statsp->mac_stats.adv_cap_asmpause
40076835Syc148097 	    = param_arr[param_anar_asmpause].value;
40086835Syc148097 
40096835Syc148097 	/*
40106835Syc148097 	 * Initialize the link statistics.
40116835Syc148097 	 */
40126835Syc148097 	statsp->mac_stats.link_T4 = 0;
40136835Syc148097 	statsp->mac_stats.link_asmpause = 0;
40146835Syc148097 	statsp->mac_stats.link_pause = 0;
40156835Syc148097 	if (speed == TN1010_SPEED_1G) {
40166835Syc148097 		statsp->mac_stats.link_speed = 1000;
40176835Syc148097 		statsp->mac_stats.link_duplex = 2;	/* Full duplex */
40186835Syc148097 		statsp->mac_stats.link_up = 1;
40196835Syc148097 	} else {
40206835Syc148097 		statsp->mac_stats.link_speed = 10000;
40216835Syc148097 		statsp->mac_stats.link_duplex = 2;
40226835Syc148097 		statsp->mac_stats.link_up = 1;
40236835Syc148097 	}
40246835Syc148097 
40256835Syc148097 	/*
40266835Syc148097 	 * Because TN1010 does not have a link partner register, to
40276835Syc148097 	 * figure out the link partner's capabilities is tricky. Here we
40286835Syc148097 	 * just set the kstat based on our knowledge about the partner
40296835Syc148097 	 * (The partner must support auto-neg because auto-negotiation
40306835Syc148097 	 * has completed, it must support 1G or 10G because that is the
40316835Syc148097 	 * negotiated speed we are using.)
40326835Syc148097 	 *
40336835Syc148097 	 * Note: Current kstat does not show lp_cap_10gfdx and
40346835Syc148097 	 *	lp_cap_10ghdx.
40356835Syc148097 	 */
40366835Syc148097 	if (speed == TN1010_SPEED_1G) {
40376835Syc148097 		statsp->mac_stats.lp_cap_1000fdx  = 1;
40386835Syc148097 		statsp->mac_stats.lp_cap_10gfdx   = 0;
40396835Syc148097 	} else {
40406835Syc148097 		statsp->mac_stats.lp_cap_1000fdx  = 0;
40416835Syc148097 		statsp->mac_stats.lp_cap_10gfdx   = 1;
40426835Syc148097 	}
40436835Syc148097 	statsp->mac_stats.lp_cap_10ghdx   = 0;
40446835Syc148097 	statsp->mac_stats.lp_cap_1000hdx  = 0;
40456835Syc148097 	statsp->mac_stats.lp_cap_100fdx   = 0;
40466835Syc148097 	statsp->mac_stats.lp_cap_100hdx   = 0;
40476835Syc148097 	statsp->mac_stats.lp_cap_10fdx    = 0;
40486835Syc148097 	statsp->mac_stats.lp_cap_10hdx    = 0;
40496835Syc148097 	statsp->mac_stats.lp_cap_10gfdx   = 0;
40506835Syc148097 	statsp->mac_stats.lp_cap_10ghdx   = 0;
40516835Syc148097 	statsp->mac_stats.lp_cap_100T4    = 0;
40526835Syc148097 	statsp->mac_stats.lp_cap_autoneg  = 1;
40536835Syc148097 	statsp->mac_stats.lp_cap_asmpause = 0;
40546835Syc148097 	statsp->mac_stats.lp_cap_pause    = 0;
40556835Syc148097 
40566835Syc148097 	/* Handle PHY loopback for SunVTS loopback test */
40576835Syc148097 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
40586835Syc148097 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
40596835Syc148097 
40606835Syc148097 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
40616835Syc148097 	    TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
40626835Syc148097 	    &tn1010_pcs_ctrl.value)) != NXGE_OK) {
40636835Syc148097 		goto fail;
40646835Syc148097 	}
40656835Syc148097 	if ((statsp->port_stats.lb_mode == nxge_lb_phy1000) ||
40666835Syc148097 	    (statsp->port_stats.lb_mode == nxge_lb_phy10g)) {
40676835Syc148097 		tn1010_pcs_ctrl.bits.loopback = 1;
40686835Syc148097 	} else {
40696835Syc148097 		tn1010_pcs_ctrl.bits.loopback = 0;
40706835Syc148097 	}
40716835Syc148097 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
40726835Syc148097 	    TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
40736835Syc148097 	    tn1010_pcs_ctrl.value)) != NXGE_OK) {
40746835Syc148097 		goto fail;
40756835Syc148097 	}
40766835Syc148097 
40776835Syc148097 	statsp->mac_stats.xcvr_inits++;
40786835Syc148097 
40796835Syc148097 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
40806835Syc148097 	    "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
40816835Syc148097 	return (status);
40826835Syc148097 fail:
40836835Syc148097 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
40846835Syc148097 	    "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
40856835Syc148097 	return (status);
40866835Syc148097 }
40876835Syc148097 
40884732Sdavemq /* Initialize transceiver */
40894732Sdavemq 
40904732Sdavemq nxge_status_t
nxge_xcvr_init(p_nxge_t nxgep)40914732Sdavemq nxge_xcvr_init(p_nxge_t nxgep)
40924732Sdavemq {
40934732Sdavemq 	p_nxge_stats_t		statsp;
40944732Sdavemq #ifdef	NXGE_DEBUG
40954732Sdavemq 	uint8_t			portn;
40964732Sdavemq #endif
40974732Sdavemq 
40984732Sdavemq 	nxge_status_t		status = NXGE_OK;
40994732Sdavemq #ifdef	NXGE_DEBUG
41004732Sdavemq 	portn = nxgep->mac.portnum;
41014732Sdavemq #endif
41023859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
41033859Sml29623 	statsp = nxgep->statsp;
41043859Sml29623 
41053859Sml29623 	/*
41066835Syc148097 	 * Initialize the xcvr statistics. nxgep->xcvr.xcvr_init will
41076835Syc148097 	 * modify mac_stats.
41083859Sml29623 	 */
41093859Sml29623 	statsp->mac_stats.cap_autoneg = 0;
41103859Sml29623 	statsp->mac_stats.cap_100T4 = 0;
41113859Sml29623 	statsp->mac_stats.cap_100fdx = 0;
41123859Sml29623 	statsp->mac_stats.cap_100hdx = 0;
41133859Sml29623 	statsp->mac_stats.cap_10fdx = 0;
41143859Sml29623 	statsp->mac_stats.cap_10hdx = 0;
41153859Sml29623 	statsp->mac_stats.cap_asmpause = 0;
41163859Sml29623 	statsp->mac_stats.cap_pause = 0;
41173859Sml29623 	statsp->mac_stats.cap_1000fdx = 0;
41183859Sml29623 	statsp->mac_stats.cap_1000hdx = 0;
41193859Sml29623 	statsp->mac_stats.cap_10gfdx = 0;
41203859Sml29623 	statsp->mac_stats.cap_10ghdx = 0;
41213859Sml29623 
41223859Sml29623 	/*
41233859Sml29623 	 * Initialize the link statistics.
41243859Sml29623 	 */
41253859Sml29623 	statsp->mac_stats.link_T4 = 0;
41263859Sml29623 	statsp->mac_stats.link_asmpause = 0;
41273859Sml29623 	statsp->mac_stats.link_pause = 0;
41283859Sml29623 
41294732Sdavemq 	if (nxgep->xcvr.xcvr_init) {
41304732Sdavemq 		status = nxgep->xcvr.xcvr_init(nxgep);
41313859Sml29623 		if (status != NXGE_OK)
41323859Sml29623 			goto fail;
41334732Sdavemq 		statsp->mac_stats.xcvr_inits++;
41343859Sml29623 	}
41353859Sml29623 
41364732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>",
41374732Sdavemq 	    portn));
41383859Sml29623 	return (NXGE_OK);
41393859Sml29623 
41403859Sml29623 fail:
41413859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
41424732Sdavemq 	    "nxge_xcvr_init: failed to initialize transceiver for port<%d>",
41434732Sdavemq 	    portn));
41443859Sml29623 	return (status);
41453859Sml29623 }
41463859Sml29623 
41474977Sraghus /* Look for transceiver type */
41484977Sraghus 
41494977Sraghus nxge_status_t
nxge_xcvr_find(p_nxge_t nxgep)41504977Sraghus nxge_xcvr_find(p_nxge_t nxgep)
41514977Sraghus {
41525196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>",
41535196Ssbehera 	    nxgep->mac.portnum));
41544977Sraghus 
41554977Sraghus 	if (nxge_get_xcvr_type(nxgep) != NXGE_OK)
41564977Sraghus 		return (NXGE_ERROR);
41574977Sraghus 
41584977Sraghus 	if (nxge_setup_xcvr_table(nxgep) != NXGE_OK)
41594977Sraghus 		return (NXGE_ERROR);
41604977Sraghus 
41614977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d",
41624977Sraghus 	    nxgep->statsp->mac_stats.xcvr_inuse));
41634977Sraghus 	return (NXGE_OK);
41644977Sraghus }
41653859Sml29623 
41663859Sml29623 /* Initialize the TxMAC sub-block */
41673859Sml29623 
41683859Sml29623 nxge_status_t
nxge_tx_mac_init(p_nxge_t nxgep)41693859Sml29623 nxge_tx_mac_init(p_nxge_t nxgep)
41703859Sml29623 {
41713859Sml29623 	npi_attr_t		ap;
41723859Sml29623 	uint8_t			portn;
41733859Sml29623 	nxge_port_mode_t	portmode;
41743859Sml29623 	nxge_port_t		portt;
41753859Sml29623 	npi_handle_t		handle;
41763859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
41773859Sml29623 
41783859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
41793859Sml29623 	portt    = nxgep->mac.porttype;
41803859Sml29623 	handle   = nxgep->npi_handle;
41813859Sml29623 	portmode = nxgep->mac.portmode;
41823859Sml29623 
41833859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>",
41846929Smisaki 	    portn));
41853859Sml29623 	/* Set Max and Min Frame Size */
41866439Sml29623 	/*
41876439Sml29623 	 * Use maxframesize to configure the hardware maxframe size
41886835Syc148097 	 * and minframesize to configure the hardware minframe size.
41896439Sml29623 	 */
41906439Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
41916439Sml29623 	    "==> nxge_tx_mac_init: port<%d> "
41926439Sml29623 	    "min framesize %d max framesize %d ",
41936439Sml29623 	    nxgep->mac.minframesize,
41946439Sml29623 	    nxgep->mac.maxframesize,
41956439Sml29623 	    portn));
41966439Sml29623 
41976439Sml29623 	SET_MAC_ATTR2(handle, ap, portn,
41986439Sml29623 	    MAC_PORT_FRAME_SIZE,
41996439Sml29623 	    nxgep->mac.minframesize,
42006439Sml29623 	    nxgep->mac.maxframesize,
42016439Sml29623 	    rs);
42023859Sml29623 	if (rs != NPI_SUCCESS)
42033859Sml29623 		goto fail;
42043859Sml29623 
42053859Sml29623 	if (portt == PORT_TYPE_XMAC) {
42063859Sml29623 		if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn,
42076929Smisaki 		    0)) != NPI_SUCCESS)
42083859Sml29623 			goto fail;
42093859Sml29623 		nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS;
42103859Sml29623 		if ((portmode == PORT_10G_FIBER) ||
42114977Sraghus 		    (portmode == PORT_10G_COPPER) ||
42126835Syc148097 		    (portmode == PORT_10G_TN1010) ||
42139599Stc99174@train 		    (portmode == PORT_HSP_MODE) ||
42144977Sraghus 		    (portmode == PORT_10G_SERDES)) {
42153859Sml29623 			SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG,
42166929Smisaki 			    XGMII_IPG_12_15, rs);
42173859Sml29623 			if (rs != NPI_SUCCESS)
42183859Sml29623 				goto fail;
42193859Sml29623 			nxgep->mac.ipg[0] = XGMII_IPG_12_15;
42203859Sml29623 		} else {
42213859Sml29623 			SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG,
42226929Smisaki 			    MII_GMII_IPG_12, rs);
42233859Sml29623 			if (rs != NPI_SUCCESS)
42243859Sml29623 				goto fail;
42253859Sml29623 			nxgep->mac.ipg[0] = MII_GMII_IPG_12;
42263859Sml29623 		}
42273859Sml29623 		if ((rs = npi_xmac_tx_config(handle, INIT, portn,
42286929Smisaki 		    CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS)
42293859Sml29623 			goto fail;
42303859Sml29623 		nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX;
42313859Sml29623 		nxgep->mac.maxburstsize = 0;	/* not programmable */
42323859Sml29623 		nxgep->mac.ctrltype = 0;	/* not programmable */
42333859Sml29623 		nxgep->mac.pa_size = 0;		/* not programmable */
42343859Sml29623 
42353859Sml29623 		if ((rs = npi_xmac_zap_tx_counters(handle, portn))
42366929Smisaki 		    != NPI_SUCCESS)
42373859Sml29623 			goto fail;
42383859Sml29623 
42393859Sml29623 	} else {
42403859Sml29623 		if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn,
42416929Smisaki 		    0)) != NPI_SUCCESS)
42423859Sml29623 			goto fail;
42433859Sml29623 		nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS;
42443859Sml29623 
42453859Sml29623 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808,
42466929Smisaki 		    rs);
42473859Sml29623 		if (rs != NPI_SUCCESS)
42483859Sml29623 			goto fail;
42493859Sml29623 		nxgep->mac.ctrltype = 0x8808;
42503859Sml29623 
42513859Sml29623 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs);
42523859Sml29623 		if (rs != NPI_SUCCESS)
42533859Sml29623 			goto fail;
42543859Sml29623 		nxgep->mac.pa_size = 0x7;
42553859Sml29623 
42563859Sml29623 		if ((rs = npi_bmac_tx_config(handle, INIT, portn,
42576929Smisaki 		    CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS)
42583859Sml29623 			goto fail;
42593859Sml29623 		nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX;
42603859Sml29623 	}
42613859Sml29623 
42623859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>",
42636929Smisaki 	    portn));
42643859Sml29623 
42653859Sml29623 	return (NXGE_OK);
42663859Sml29623 fail:
42673859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
42686929Smisaki 	    "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", portn));
42693859Sml29623 
42703859Sml29623 	return (NXGE_ERROR | rs);
42713859Sml29623 }
42723859Sml29623 
427311878SVenu.Iyer@Sun.COM static npi_status_t
nxge_rx_mac_mcast_hash_table(p_nxge_t nxgep)427411878SVenu.Iyer@Sun.COM nxge_rx_mac_mcast_hash_table(p_nxge_t nxgep)
427511878SVenu.Iyer@Sun.COM {
427611878SVenu.Iyer@Sun.COM 	uint32_t		i;
427711878SVenu.Iyer@Sun.COM 	uint16_t		hashtab_e;
427811878SVenu.Iyer@Sun.COM 	p_hash_filter_t		hash_filter;
427911878SVenu.Iyer@Sun.COM 	uint8_t			portn;
428011878SVenu.Iyer@Sun.COM 	npi_handle_t		handle;
428111878SVenu.Iyer@Sun.COM 	npi_status_t		rs = NPI_SUCCESS;
428211878SVenu.Iyer@Sun.COM 
428311878SVenu.Iyer@Sun.COM 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
428411878SVenu.Iyer@Sun.COM 	handle = nxgep->npi_handle;
428511878SVenu.Iyer@Sun.COM 
428611878SVenu.Iyer@Sun.COM 	/*
428711878SVenu.Iyer@Sun.COM 	 * Load the multicast hash filter bits.
428811878SVenu.Iyer@Sun.COM 	 */
428911878SVenu.Iyer@Sun.COM 	hash_filter = nxgep->hash_filter;
429011878SVenu.Iyer@Sun.COM 	for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) {
429111878SVenu.Iyer@Sun.COM 		if (hash_filter != NULL) {
429211878SVenu.Iyer@Sun.COM 			hashtab_e = (uint16_t)hash_filter->hash_filter_regs[
429311878SVenu.Iyer@Sun.COM 			    (NMCFILTER_REGS - 1) - i];
429411878SVenu.Iyer@Sun.COM 		} else {
429511878SVenu.Iyer@Sun.COM 			hashtab_e = 0;
429611878SVenu.Iyer@Sun.COM 		}
429711878SVenu.Iyer@Sun.COM 
429811878SVenu.Iyer@Sun.COM 		if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i,
429911878SVenu.Iyer@Sun.COM 		    (uint16_t *)&hashtab_e)) != NPI_SUCCESS)
430011878SVenu.Iyer@Sun.COM 			return (rs);
430111878SVenu.Iyer@Sun.COM 	}
430211878SVenu.Iyer@Sun.COM 
430311878SVenu.Iyer@Sun.COM 	return (NPI_SUCCESS);
430411878SVenu.Iyer@Sun.COM }
430511878SVenu.Iyer@Sun.COM 
430611878SVenu.Iyer@Sun.COM /*
430711878SVenu.Iyer@Sun.COM  * Initialize the RxMAC sub-block
430811878SVenu.Iyer@Sun.COM  */
43093859Sml29623 nxge_status_t
nxge_rx_mac_init(p_nxge_t nxgep)43103859Sml29623 nxge_rx_mac_init(p_nxge_t nxgep)
43113859Sml29623 {
43123859Sml29623 	npi_attr_t		ap;
43133859Sml29623 	nxge_port_t		portt;
43143859Sml29623 	uint8_t			portn;
43153859Sml29623 	npi_handle_t		handle;
43163859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
43173859Sml29623 	uint16_t 		*addr16p;
43183859Sml29623 	uint16_t 		addr0, addr1, addr2;
43193859Sml29623 	xmac_rx_config_t	xconfig;
43203859Sml29623 	bmac_rx_config_t	bconfig;
43213859Sml29623 
43223859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
43233859Sml29623 
43243859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n",
43256929Smisaki 	    portn));
43263859Sml29623 	handle = nxgep->npi_handle;
43273859Sml29623 	portt = nxgep->mac.porttype;
43283859Sml29623 
43293859Sml29623 	addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet;
43303859Sml29623 	addr0 = ntohs(addr16p[2]);
43313859Sml29623 	addr1 = ntohs(addr16p[1]);
43323859Sml29623 	addr2 = ntohs(addr16p[0]);
433311878SVenu.Iyer@Sun.COM 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR,
433411878SVenu.Iyer@Sun.COM 	    addr0, addr1, addr2, rs);
43353859Sml29623 	if (rs != NPI_SUCCESS)
43363859Sml29623 		goto fail;
43373859Sml29623 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs);
43383859Sml29623 	if (rs != NPI_SUCCESS)
43393859Sml29623 		goto fail;
43403859Sml29623 	SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs);
43413859Sml29623 	if (rs != NPI_SUCCESS)
43423859Sml29623 		goto fail;
43433859Sml29623 
434411878SVenu.Iyer@Sun.COM 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
434511878SVenu.Iyer@Sun.COM 	if (rs != NPI_SUCCESS)
434611878SVenu.Iyer@Sun.COM 		goto fail;
43473859Sml29623 
43483859Sml29623 	if (portt == PORT_TYPE_XMAC) {
43493859Sml29623 		if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn,
43506929Smisaki 		    0)) != NPI_SUCCESS)
43513859Sml29623 			goto fail;
43523859Sml29623 		nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS;
43533859Sml29623 
43543859Sml29623 		(void) nxge_fflp_init_hostinfo(nxgep);
43553859Sml29623 
43563859Sml29623 		xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK |
43576929Smisaki 		    CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK &
43586929Smisaki 		    ~CFG_XMAC_RX_STRIP_CRC;
43593859Sml29623 
43603859Sml29623 		if (nxgep->filter.all_phys_cnt != 0)
43613859Sml29623 			xconfig |= CFG_XMAC_RX_PROMISCUOUS;
43623859Sml29623 		if (nxgep->filter.all_multicast_cnt != 0)
43633859Sml29623 			xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP;
43643859Sml29623 
43653859Sml29623 		xconfig |= CFG_XMAC_RX_HASH_FILTER;
43663859Sml29623 
436711878SVenu.Iyer@Sun.COM 		if ((rs = npi_xmac_rx_config(handle, INIT,
436811878SVenu.Iyer@Sun.COM 		    portn, xconfig)) != NPI_SUCCESS)
43693859Sml29623 			goto fail;
43703859Sml29623 		nxgep->mac.rx_config = xconfig;
43713859Sml29623 
437211878SVenu.Iyer@Sun.COM 		/*
437311878SVenu.Iyer@Sun.COM 		 * Comparison of mac unique address is always
437411878SVenu.Iyer@Sun.COM 		 * enabled on XMAC
437511878SVenu.Iyer@Sun.COM 		 */
43763859Sml29623 		if ((rs = npi_xmac_zap_rx_counters(handle, portn))
43776929Smisaki 		    != NPI_SUCCESS)
43783859Sml29623 			goto fail;
43793859Sml29623 	} else {
43803859Sml29623 		if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn,
43816929Smisaki 		    0) != NPI_SUCCESS)
43823859Sml29623 			goto fail;
438311878SVenu.Iyer@Sun.COM 
43843859Sml29623 		nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS;
43853859Sml29623 
438611878SVenu.Iyer@Sun.COM 		(void) nxge_fflp_init_hostinfo(nxgep);
438711878SVenu.Iyer@Sun.COM 
43883859Sml29623 		bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX &
43896929Smisaki 		    ~CFG_BMAC_RX_STRIP_CRC;
43903859Sml29623 
43913859Sml29623 		if (nxgep->filter.all_phys_cnt != 0)
43923859Sml29623 			bconfig |= CFG_BMAC_RX_PROMISCUOUS;
43933859Sml29623 		if (nxgep->filter.all_multicast_cnt != 0)
43943859Sml29623 			bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP;
43953859Sml29623 
43963859Sml29623 		bconfig |= CFG_BMAC_RX_HASH_FILTER;
439711878SVenu.Iyer@Sun.COM 		if ((rs = npi_bmac_rx_config(handle, INIT,
439811878SVenu.Iyer@Sun.COM 		    portn, bconfig)) != NPI_SUCCESS)
43993859Sml29623 			goto fail;
44003859Sml29623 		nxgep->mac.rx_config = bconfig;
44013859Sml29623 
440211878SVenu.Iyer@Sun.COM 		/*
440311878SVenu.Iyer@Sun.COM 		 * Always enable comparison of mac unique address
440411878SVenu.Iyer@Sun.COM 		 */
440511878SVenu.Iyer@Sun.COM 		if ((rs = npi_mac_altaddr_enable(handle,
440611878SVenu.Iyer@Sun.COM 		    portn, 0)) != NPI_SUCCESS)
44073859Sml29623 			goto fail;
44083859Sml29623 	}
44093859Sml29623 
44103859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n",
44116929Smisaki 	    portn));
44123859Sml29623 
44133859Sml29623 	return (NXGE_OK);
44143859Sml29623 
44153859Sml29623 fail:
44163859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44176929Smisaki 	    "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", portn));
44183859Sml29623 
44193859Sml29623 	return (NXGE_ERROR | rs);
44203859Sml29623 }
44213859Sml29623 
44223859Sml29623 /* Enable TXMAC */
44233859Sml29623 
44243859Sml29623 nxge_status_t
nxge_tx_mac_enable(p_nxge_t nxgep)44253859Sml29623 nxge_tx_mac_enable(p_nxge_t nxgep)
44263859Sml29623 {
44273859Sml29623 	npi_handle_t	handle;
44283859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
44293859Sml29623 	nxge_status_t	status = NXGE_OK;
44303859Sml29623 
44313859Sml29623 	handle = nxgep->npi_handle;
44323859Sml29623 
44333859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>",
44346929Smisaki 	    nxgep->mac.portnum));
44353859Sml29623 
44363859Sml29623 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
44373859Sml29623 		goto fail;
44383859Sml29623 
44393859Sml29623 	/* based on speed */
44403859Sml29623 	nxgep->msg_min = ETHERMIN;
44413859Sml29623 
44423859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
44433859Sml29623 		if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
44446929Smisaki 		    CFG_XMAC_TX)) != NPI_SUCCESS)
44453859Sml29623 			goto fail;
44463859Sml29623 	} else {
44473859Sml29623 		if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
44486929Smisaki 		    CFG_BMAC_TX)) != NPI_SUCCESS)
44493859Sml29623 			goto fail;
44503859Sml29623 	}
44513859Sml29623 
44523859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>",
44536929Smisaki 	    nxgep->mac.portnum));
44543859Sml29623 
44553859Sml29623 	return (NXGE_OK);
44563859Sml29623 fail:
44573859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44586929Smisaki 	    "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
44596929Smisaki 	    nxgep->mac.portnum));
44603859Sml29623 	if (rs != NPI_SUCCESS)
44613859Sml29623 		return (NXGE_ERROR | rs);
44623859Sml29623 	else
44633859Sml29623 		return (status);
44643859Sml29623 }
44653859Sml29623 
44663859Sml29623 /* Disable TXMAC */
44673859Sml29623 
44683859Sml29623 nxge_status_t
nxge_tx_mac_disable(p_nxge_t nxgep)44693859Sml29623 nxge_tx_mac_disable(p_nxge_t nxgep)
44703859Sml29623 {
44713859Sml29623 	npi_handle_t	handle;
44723859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
44733859Sml29623 
44746495Sspeer 	if (isLDOMguest(nxgep))
44756495Sspeer 		return (NXGE_OK);
44766495Sspeer 
44773859Sml29623 	handle = nxgep->npi_handle;
44783859Sml29623 
44793859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>",
44806929Smisaki 	    nxgep->mac.portnum));
44813859Sml29623 
44823859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
44833859Sml29623 		if ((rs = npi_xmac_tx_config(handle, DISABLE,
44846929Smisaki 		    nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS)
44853859Sml29623 			goto fail;
44863859Sml29623 	} else {
44873859Sml29623 		if ((rs = npi_bmac_tx_config(handle, DISABLE,
44886929Smisaki 		    nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS)
44893859Sml29623 			goto fail;
44903859Sml29623 	}
44913859Sml29623 
44923859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>",
44936929Smisaki 	    nxgep->mac.portnum));
44943859Sml29623 	return (NXGE_OK);
44953859Sml29623 fail:
44963859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44976929Smisaki 	    "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
44986929Smisaki 	    nxgep->mac.portnum));
44993859Sml29623 	return (NXGE_ERROR | rs);
45003859Sml29623 }
45013859Sml29623 
45023859Sml29623 /* Enable RXMAC */
45033859Sml29623 
45043859Sml29623 nxge_status_t
nxge_rx_mac_enable(p_nxge_t nxgep)45053859Sml29623 nxge_rx_mac_enable(p_nxge_t nxgep)
45063859Sml29623 {
45073859Sml29623 	npi_handle_t	handle;
45083859Sml29623 	uint8_t 	portn;
45093859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
45103859Sml29623 	nxge_status_t	status = NXGE_OK;
45113859Sml29623 
45126495Sspeer 	/* This is a service-domain-only activity. */
45136495Sspeer 	if (isLDOMguest(nxgep))
45146495Sspeer 		return (status);
45156495Sspeer 
45163859Sml29623 	handle = nxgep->npi_handle;
45173859Sml29623 	portn = nxgep->mac.portnum;
45183859Sml29623 
45193859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>",
45206929Smisaki 	    portn));
45213859Sml29623 
45223859Sml29623 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
45233859Sml29623 		goto fail;
45243859Sml29623 
45253859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
45263859Sml29623 		if ((rs = npi_xmac_rx_config(handle, ENABLE, portn,
45276495Sspeer 		    CFG_XMAC_RX)) != NPI_SUCCESS)
45283859Sml29623 			goto fail;
45293859Sml29623 	} else {
45303859Sml29623 		if ((rs = npi_bmac_rx_config(handle, ENABLE, portn,
45316495Sspeer 		    CFG_BMAC_RX)) != NPI_SUCCESS)
45323859Sml29623 			goto fail;
45333859Sml29623 	}
45343859Sml29623 
45356495Sspeer 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
45366495Sspeer 	    "<== nxge_rx_mac_enable: port<%d>", portn));
45373859Sml29623 
45383859Sml29623 	return (NXGE_OK);
45393859Sml29623 fail:
45403859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
45416495Sspeer 	    "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", portn));
45423859Sml29623 
45433859Sml29623 	if (rs != NPI_SUCCESS)
45443859Sml29623 		return (NXGE_ERROR | rs);
45453859Sml29623 	else
45463859Sml29623 		return (status);
45473859Sml29623 }
45483859Sml29623 
45493859Sml29623 /* Disable RXMAC */
45503859Sml29623 
45513859Sml29623 nxge_status_t
nxge_rx_mac_disable(p_nxge_t nxgep)45523859Sml29623 nxge_rx_mac_disable(p_nxge_t nxgep)
45533859Sml29623 {
45543859Sml29623 	npi_handle_t	handle;
45553859Sml29623 	uint8_t		portn;
45563859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
45573859Sml29623 
45586495Sspeer 	/* If we are a guest domain driver, don't bother. */
45596495Sspeer 	if (isLDOMguest(nxgep))
45606495Sspeer 		return (NXGE_OK);
45616495Sspeer 
45623859Sml29623 	handle = nxgep->npi_handle;
45633859Sml29623 	portn = nxgep->mac.portnum;
45643859Sml29623 
45653859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>",
45666929Smisaki 	    portn));
45673859Sml29623 
45683859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
45693859Sml29623 		if ((rs = npi_xmac_rx_config(handle, DISABLE, portn,
45706929Smisaki 		    CFG_XMAC_RX)) != NPI_SUCCESS)
45713859Sml29623 			goto fail;
45723859Sml29623 	} else {
45733859Sml29623 		if ((rs = npi_bmac_rx_config(handle, DISABLE, portn,
45746929Smisaki 		    CFG_BMAC_RX)) != NPI_SUCCESS)
45753859Sml29623 			goto fail;
45763859Sml29623 	}
45773859Sml29623 
45783859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>",
45796929Smisaki 	    portn));
45803859Sml29623 	return (NXGE_OK);
45813859Sml29623 fail:
45823859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
45836929Smisaki 	    "nxgep_rx_mac_disable: Failed to disable port<%d> RxMAC", portn));
45843859Sml29623 
45853859Sml29623 	return (NXGE_ERROR | rs);
45863859Sml29623 }
45873859Sml29623 
45883859Sml29623 /* Reset TXMAC */
45893859Sml29623 
45903859Sml29623 nxge_status_t
nxge_tx_mac_reset(p_nxge_t nxgep)45913859Sml29623 nxge_tx_mac_reset(p_nxge_t nxgep)
45923859Sml29623 {
45933859Sml29623 	npi_handle_t	handle;
45943859Sml29623 	uint8_t		portn;
45953859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
45963859Sml29623 
45973859Sml29623 	handle = nxgep->npi_handle;
45983859Sml29623 	portn = nxgep->mac.portnum;
45993859Sml29623 
46003859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>",
46016929Smisaki 	    portn));
46023859Sml29623 
46033859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
46043859Sml29623 		if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL))
46053859Sml29623 		    != NPI_SUCCESS)
46063859Sml29623 			goto fail;
46073859Sml29623 	} else {
46083859Sml29623 		if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET))
46096929Smisaki 		    != NPI_SUCCESS)
46103859Sml29623 			goto fail;
46113859Sml29623 	}
46123859Sml29623 
46133859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>",
46146929Smisaki 	    portn));
46153859Sml29623 
46163859Sml29623 	return (NXGE_OK);
46173859Sml29623 fail:
46183859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
46196929Smisaki 	    "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", portn));
46203859Sml29623 
46213859Sml29623 	return (NXGE_ERROR | rs);
46223859Sml29623 }
46233859Sml29623 
46243859Sml29623 /* Reset RXMAC */
46253859Sml29623 
46263859Sml29623 nxge_status_t
nxge_rx_mac_reset(p_nxge_t nxgep)46273859Sml29623 nxge_rx_mac_reset(p_nxge_t nxgep)
46283859Sml29623 {
46293859Sml29623 	npi_handle_t	handle;
46303859Sml29623 	uint8_t		portn;
46313859Sml29623 	npi_status_t	rs = NPI_SUCCESS;
46323859Sml29623 
46333859Sml29623 	handle = nxgep->npi_handle;
46343859Sml29623 	portn = nxgep->mac.portnum;
46353859Sml29623 
46363859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>",
46376929Smisaki 	    portn));
46383859Sml29623 
46393859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
46403859Sml29623 		if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL))
46413859Sml29623 		    != NPI_SUCCESS)
46423859Sml29623 		goto fail;
46433859Sml29623 	} else {
46443859Sml29623 		if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET))
46456929Smisaki 		    != NPI_SUCCESS)
46463859Sml29623 		goto fail;
46473859Sml29623 	}
46483859Sml29623 
46493859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>",
46506929Smisaki 	    portn));
46513859Sml29623 
46523859Sml29623 	return (NXGE_OK);
46533859Sml29623 fail:
46543859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
46556929Smisaki 	    "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", portn));
46563859Sml29623 	return (NXGE_ERROR | rs);
46573859Sml29623 }
46583859Sml29623 
46594732Sdavemq /* 10G fiber link interrupt start routine */
46604732Sdavemq 
46614732Sdavemq static nxge_status_t
nxge_10G_link_intr_start(p_nxge_t nxgep)46624732Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep)
46634732Sdavemq {
46644732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
46654732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
46664732Sdavemq 
46674732Sdavemq 	rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn);
46684732Sdavemq 
46694732Sdavemq 	if (rs != NPI_SUCCESS)
46704732Sdavemq 		return (NXGE_ERROR | rs);
46714732Sdavemq 	else
46724732Sdavemq 		return (NXGE_OK);
46734732Sdavemq }
46744732Sdavemq 
46754732Sdavemq /* 10G fiber link interrupt stop routine */
46764732Sdavemq 
46774732Sdavemq static nxge_status_t
nxge_10G_link_intr_stop(p_nxge_t nxgep)46784732Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep)
46794732Sdavemq {
46804732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
46814732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
46824732Sdavemq 
46834732Sdavemq 	rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn);
46844732Sdavemq 
46854732Sdavemq 	if (rs != NPI_SUCCESS)
46864732Sdavemq 		return (NXGE_ERROR | rs);
46874732Sdavemq 	else
46884732Sdavemq 		return (NXGE_OK);
46894732Sdavemq }
46904732Sdavemq 
46914732Sdavemq /* 1G fiber link interrupt start routine */
46924732Sdavemq 
46934732Sdavemq static nxge_status_t
nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)46944732Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)
46954732Sdavemq {
46964732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
46974732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
46984732Sdavemq 
46994732Sdavemq 	rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn);
47004732Sdavemq 	if (rs != NPI_SUCCESS)
47014732Sdavemq 		return (NXGE_ERROR | rs);
47024732Sdavemq 	else
47034732Sdavemq 		return (NXGE_OK);
47044732Sdavemq }
47054732Sdavemq 
47064732Sdavemq /* 1G fiber link interrupt stop routine */
47074732Sdavemq 
47084732Sdavemq static nxge_status_t
nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)47094732Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)
47104732Sdavemq {
47114732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
47124732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
47134732Sdavemq 
47144732Sdavemq 	rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn);
47154732Sdavemq 
47164732Sdavemq 	if (rs != NPI_SUCCESS)
47174732Sdavemq 		return (NXGE_ERROR | rs);
47184732Sdavemq 	else
47194732Sdavemq 		return (NXGE_OK);
47204732Sdavemq }
47214732Sdavemq 
47224732Sdavemq /* 1G copper link interrupt start routine */
47234732Sdavemq 
47244732Sdavemq static nxge_status_t
nxge_1G_copper_link_intr_start(p_nxge_t nxgep)47254732Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep)
47264732Sdavemq {
47274732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
47284732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
47294732Sdavemq 
47304732Sdavemq 	rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn,
47315203Ssbehera 	    MII_STATUS, MII_STATUS_LINKUP);
47324732Sdavemq 
47334732Sdavemq 	if (rs != NPI_SUCCESS)
47344732Sdavemq 		return (NXGE_ERROR | rs);
47354732Sdavemq 	else
47364732Sdavemq 		return (NXGE_OK);
47374732Sdavemq }
47384732Sdavemq 
47394732Sdavemq /* 1G copper link interrupt stop routine */
47404732Sdavemq 
47414732Sdavemq static nxge_status_t
nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)47424732Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)
47434732Sdavemq {
47444732Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
47454732Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
47464732Sdavemq 
47474732Sdavemq 	rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn);
47484732Sdavemq 
47494732Sdavemq 	if (rs != NPI_SUCCESS)
47504732Sdavemq 		return (NXGE_ERROR | rs);
47514732Sdavemq 	else
47524732Sdavemq 		return (NXGE_OK);
47534732Sdavemq }
47544732Sdavemq 
47554732Sdavemq /* Enable/Disable Link Status change interrupt */
47563859Sml29623 
47573859Sml29623 nxge_status_t
nxge_link_intr(p_nxge_t nxgep,link_intr_enable_t enable)47583859Sml29623 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
47593859Sml29623 {
47604732Sdavemq 	uint8_t		portn;
47614732Sdavemq 	nxge_status_t	status = NXGE_OK;
47623859Sml29623 
47633859Sml29623 	portn = nxgep->mac.portnum;
47643859Sml29623 
47653859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn));
47664732Sdavemq 	if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start)
47674732Sdavemq 		return (NXGE_OK);
47684732Sdavemq 
47694732Sdavemq 	if (enable == LINK_INTR_START)
47704732Sdavemq 		status = nxgep->xcvr.link_intr_start(nxgep);
47714732Sdavemq 	else if (enable == LINK_INTR_STOP)
47724732Sdavemq 		status = nxgep->xcvr.link_intr_stop(nxgep);
47734732Sdavemq 	if (status != NXGE_OK)
47744732Sdavemq 		goto fail;
47753859Sml29623 
47763859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
47773859Sml29623 
47783859Sml29623 	return (NXGE_OK);
47793859Sml29623 fail:
47803859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
47816929Smisaki 	    "nxge_link_intr: Failed to set port<%d> mif intr mode", portn));
47823859Sml29623 
47834732Sdavemq 	return (status);
47843859Sml29623 }
47853859Sml29623 
47863859Sml29623 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
47873859Sml29623 
47883859Sml29623 nxge_status_t
nxge_mii_xcvr_init(p_nxge_t nxgep)47893859Sml29623 nxge_mii_xcvr_init(p_nxge_t nxgep)
47903859Sml29623 {
47913859Sml29623 	p_nxge_param_t	param_arr;
47923859Sml29623 	p_nxge_stats_t	statsp;
47933859Sml29623 	uint8_t		xcvr_portn;
47943859Sml29623 	p_mii_regs_t	mii_regs;
47953859Sml29623 	mii_bmcr_t	bmcr;
47963859Sml29623 	mii_bmsr_t	bmsr;
47973859Sml29623 	mii_anar_t	anar;
47983859Sml29623 	mii_gcr_t	gcr;
47993859Sml29623 	mii_esr_t	esr;
48003859Sml29623 	mii_aux_ctl_t	bcm5464r_aux;
48013859Sml29623 	int		status = NXGE_OK;
48023859Sml29623 
48033859Sml29623 	uint_t delay;
48043859Sml29623 
48053859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init"));
48063859Sml29623 
48073859Sml29623 	param_arr = nxgep->param_arr;
48083859Sml29623 	statsp = nxgep->statsp;
48093859Sml29623 	xcvr_portn = statsp->mac_stats.xcvr_portn;
48103859Sml29623 
48113859Sml29623 	mii_regs = NULL;
48123859Sml29623 
48133859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
48146929Smisaki 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
48153859Sml29623 
48163859Sml29623 	/*
48175196Ssbehera 	 * The mif phy mode may be connected to either a copper link
48185196Ssbehera 	 * or fiber link. Read the mode control register to get the fiber
48195196Ssbehera 	 * configuration if it is hard-wired to fiber link.
48205196Ssbehera 	 */
48215196Ssbehera 	(void) nxge_mii_get_link_mode(nxgep);
48225196Ssbehera 	if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
48235196Ssbehera 		return (nxge_mii_xcvr_fiber_init(nxgep));
48245196Ssbehera 	}
48255196Ssbehera 
48265196Ssbehera 	/*
48273859Sml29623 	 * Reset the transceiver.
48283859Sml29623 	 */
48293859Sml29623 	delay = 0;
48303859Sml29623 	bmcr.value = 0;
48313859Sml29623 	bmcr.bits.reset = 1;
48323859Sml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
48335125Sjoycey #if defined(__i386)
48346929Smisaki 	    (uint8_t)(uint32_t)&mii_regs->bmcr,
48355125Sjoycey #else
48366929Smisaki 	    (uint8_t)(uint64_t)&mii_regs->bmcr,
48375125Sjoycey #endif
48386929Smisaki 	    bmcr.value)) != NXGE_OK)
48393859Sml29623 		goto fail;
48403859Sml29623 	do {
48413859Sml29623 		drv_usecwait(500);
48423859Sml29623 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
48435125Sjoycey #if defined(__i386)
48446929Smisaki 		    (uint8_t)(uint32_t)&mii_regs->bmcr,
48455125Sjoycey #else
48466929Smisaki 		    (uint8_t)(uint64_t)&mii_regs->bmcr,
48475125Sjoycey #endif
48486929Smisaki 		    &bmcr.value)) != NXGE_OK)
48493859Sml29623 			goto fail;
48503859Sml29623 		delay++;
48513859Sml29623 	} while ((bmcr.bits.reset) && (delay < 1000));
48523859Sml29623 	if (delay == 1000) {
48533859Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
48543859Sml29623 		goto fail;
48553859Sml29623 	}
48563859Sml29623 
48573859Sml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
48585125Sjoycey #if defined(__i386)
48596929Smisaki 	    (uint8_t)(uint32_t)(&mii_regs->bmsr),
48605125Sjoycey #else
48616929Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
48625125Sjoycey #endif
48636929Smisaki 	    &bmsr.value)) != NXGE_OK)
48643859Sml29623 		goto fail;
48653859Sml29623 
48663859Sml29623 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
48673859Sml29623 	param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4;
48683859Sml29623 	param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx;
48693859Sml29623 	param_arr[param_anar_100hdx].value = 0;
48703859Sml29623 	param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx;
48713859Sml29623 	param_arr[param_anar_10hdx].value = 0;
48723859Sml29623 
48733859Sml29623 	/*
48743859Sml29623 	 * Initialize the xcvr statistics.
48753859Sml29623 	 */
48763859Sml29623 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
48773859Sml29623 	statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4;
48783859Sml29623 	statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx;
48793859Sml29623 	statsp->mac_stats.cap_100hdx = 0;
48803859Sml29623 	statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx;
48813859Sml29623 	statsp->mac_stats.cap_10hdx = 0;
48823859Sml29623 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
48833859Sml29623 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
48843859Sml29623 
48853859Sml29623 	/*
48866835Syc148097 	 * Initialize the xcvr advertised capability statistics.
48873859Sml29623 	 */
48883859Sml29623 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
48893859Sml29623 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
48903859Sml29623 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
48913859Sml29623 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
48923859Sml29623 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
48933859Sml29623 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
48943859Sml29623 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
48953859Sml29623 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
48963859Sml29623 	statsp->mac_stats.adv_cap_asmpause =
48976929Smisaki 	    param_arr[param_anar_asmpause].value;
48983859Sml29623 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
48993859Sml29623 
49003859Sml29623 
49013859Sml29623 	/*
49023859Sml29623 	 * Check for extended status just in case we're
49033859Sml29623 	 * running a Gigibit phy.
49043859Sml29623 	 */
49053859Sml29623 	if (bmsr.bits.extend_status) {
49063859Sml29623 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
49075125Sjoycey #if defined(__i386)
49086929Smisaki 		    (uint8_t)(uint32_t)(&mii_regs->esr),
49095125Sjoycey #else
49106929Smisaki 		    (uint8_t)(uint64_t)(&mii_regs->esr),
49115125Sjoycey #endif
49126929Smisaki 		    &esr.value)) != NXGE_OK)
49133859Sml29623 			goto fail;
49146929Smisaki 		param_arr[param_anar_1000fdx].value &= esr.bits.link_1000fdx;
49153859Sml29623 		param_arr[param_anar_1000hdx].value = 0;
49163859Sml29623 
49173859Sml29623 		statsp->mac_stats.cap_1000fdx =
49186929Smisaki 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
49193859Sml29623 		statsp->mac_stats.cap_1000hdx = 0;
49203859Sml29623 	} else {
49213859Sml29623 		param_arr[param_anar_1000fdx].value = 0;
49223859Sml29623 		param_arr[param_anar_1000hdx].value = 0;
49233859Sml29623 	}
49243859Sml29623 
49253859Sml29623 	/*
49263859Sml29623 	 * Initialize 1G Statistics once the capability is established.
49273859Sml29623 	 */
49283859Sml29623 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
49293859Sml29623 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
49303859Sml29623 
49313859Sml29623 	/*
49326835Syc148097 	 * Initialize the link statistics.
49333859Sml29623 	 */
49343859Sml29623 	statsp->mac_stats.link_T4 = 0;
49353859Sml29623 	statsp->mac_stats.link_asmpause = 0;
49363859Sml29623 	statsp->mac_stats.link_pause = 0;
49373859Sml29623 	statsp->mac_stats.link_speed = 0;
49383859Sml29623 	statsp->mac_stats.link_duplex = 0;
49393859Sml29623 	statsp->mac_stats.link_up = 0;
49403859Sml29623 
49413859Sml29623 	/*
49423859Sml29623 	 * Switch off Auto-negotiation, 100M and full duplex.
49433859Sml29623 	 */
49443859Sml29623 	bmcr.value = 0;
49453859Sml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
49465125Sjoycey #if defined(__i386)
49476929Smisaki 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
49485125Sjoycey #else
49496929Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
49505125Sjoycey #endif
49516929Smisaki 	    bmcr.value)) != NXGE_OK)
49523859Sml29623 		goto fail;
49533859Sml29623 
49543859Sml29623 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
49556929Smisaki 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
49563859Sml29623 		bmcr.bits.loopback = 1;
49573859Sml29623 		bmcr.bits.enable_autoneg = 0;
49583859Sml29623 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
49593859Sml29623 			bmcr.bits.speed_1000_sel = 1;
49603859Sml29623 		bmcr.bits.duplex_mode = 1;
49613859Sml29623 		param_arr[param_autoneg].value = 0;
49623859Sml29623 	} else {
49633859Sml29623 		bmcr.bits.loopback = 0;
49643859Sml29623 	}
49653859Sml29623 
49663859Sml29623 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
49676929Smisaki 	    (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
49686929Smisaki 	    (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
49693859Sml29623 		param_arr[param_autoneg].value = 0;
49703859Sml29623 		bcm5464r_aux.value = 0;
49713859Sml29623 		bcm5464r_aux.bits.ext_lb = 1;
49723859Sml29623 		bcm5464r_aux.bits.write_1 = 1;
49733859Sml29623 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
49746929Smisaki 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
49753859Sml29623 			goto fail;
49763859Sml29623 	}
49773859Sml29623 
49786835Syc148097 	/* If auto-negotiation is desired */
49793859Sml29623 	if (param_arr[param_autoneg].value) {
49803859Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
49816929Smisaki 		    "Restarting Auto-negotiation."));
49823859Sml29623 		/*
49833859Sml29623 		 * Setup our Auto-negotiation advertisement register.
49843859Sml29623 		 */
49853859Sml29623 		anar.value = 0;
49863859Sml29623 		anar.bits.selector = 1;
49873859Sml29623 		anar.bits.cap_100T4 = param_arr[param_anar_100T4].value;
49883859Sml29623 		anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value;
49893859Sml29623 		anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value;
49903859Sml29623 		anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value;
49913859Sml29623 		anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value;
49923859Sml29623 		anar.bits.cap_asmpause = 0;
49933859Sml29623 		anar.bits.cap_pause = 0;
49943859Sml29623 		if (param_arr[param_anar_1000fdx].value ||
49956929Smisaki 		    param_arr[param_anar_100fdx].value ||
49966929Smisaki 		    param_arr[param_anar_10fdx].value) {
49973859Sml29623 			anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause;
49983859Sml29623 			anar.bits.cap_pause = statsp->mac_stats.cap_pause;
49993859Sml29623 		}
50003859Sml29623 
50016835Syc148097 		/* Write to the auto-negotiation advertisement register */
50023859Sml29623 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
50035125Sjoycey #if defined(__i386)
50046929Smisaki 		    (uint8_t)(uint32_t)(&mii_regs->anar),
50055125Sjoycey #else
50066929Smisaki 		    (uint8_t)(uint64_t)(&mii_regs->anar),
50075125Sjoycey #endif
50086929Smisaki 		    anar.value)) != NXGE_OK)
50093859Sml29623 			goto fail;
50103859Sml29623 		if (bmsr.bits.extend_status) {
50113859Sml29623 			gcr.value = 0;
50123859Sml29623 			gcr.bits.ms_mode_en =
50136929Smisaki 			    param_arr[param_master_cfg_enable].value;
50143859Sml29623 			gcr.bits.master =
50156929Smisaki 			    param_arr[param_master_cfg_value].value;
50163859Sml29623 			gcr.bits.link_1000fdx =
50176929Smisaki 			    param_arr[param_anar_1000fdx].value;
50183859Sml29623 			gcr.bits.link_1000hdx =
50196929Smisaki 			    param_arr[param_anar_1000hdx].value;
50203859Sml29623 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
50215125Sjoycey #if defined(__i386)
50226929Smisaki 			    (uint8_t)(uint32_t)(&mii_regs->gcr),
50235125Sjoycey #else
50246929Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->gcr),
50255125Sjoycey #endif
50266929Smisaki 			    gcr.value)) != NXGE_OK)
50273859Sml29623 				goto fail;
50283859Sml29623 		}
50293859Sml29623 
50303859Sml29623 		bmcr.bits.enable_autoneg = 1;
50313859Sml29623 		bmcr.bits.restart_autoneg = 1;
50323859Sml29623 
50333859Sml29623 	} else {
50343859Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
50353859Sml29623 		bmcr.bits.speed_1000_sel =
50366929Smisaki 		    param_arr[param_anar_1000fdx].value |
50376929Smisaki 		    param_arr[param_anar_1000hdx].value;
50383859Sml29623 		bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) &
50396929Smisaki 		    (param_arr[param_anar_100fdx].value |
50406929Smisaki 		    param_arr[param_anar_100hdx].value);
50416835Syc148097 
50426835Syc148097 		/* Force to 1G */
50433859Sml29623 		if (bmcr.bits.speed_1000_sel) {
50443859Sml29623 			statsp->mac_stats.link_speed = 1000;
50453859Sml29623 			gcr.value = 0;
50463859Sml29623 			gcr.bits.ms_mode_en =
50476929Smisaki 			    param_arr[param_master_cfg_enable].value;
50483859Sml29623 			gcr.bits.master =
50496929Smisaki 			    param_arr[param_master_cfg_value].value;
50503859Sml29623 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
50515125Sjoycey #if defined(__i386)
50526929Smisaki 			    (uint8_t)(uint32_t)(&mii_regs->gcr),
50535125Sjoycey #else
50546929Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->gcr),
50555125Sjoycey #endif
50566929Smisaki 			    gcr.value)) != NXGE_OK)
50573859Sml29623 				goto fail;
50583859Sml29623 			if (param_arr[param_anar_1000fdx].value) {
50593859Sml29623 				bmcr.bits.duplex_mode = 1;
50603859Sml29623 				statsp->mac_stats.link_duplex = 2;
50613859Sml29623 			} else
50623859Sml29623 				statsp->mac_stats.link_duplex = 1;
50636835Syc148097 
50646835Syc148097 		/* Force to 100M */
50653859Sml29623 		} else if (bmcr.bits.speed_sel) {
50663859Sml29623 			statsp->mac_stats.link_speed = 100;
50673859Sml29623 			if (param_arr[param_anar_100fdx].value) {
50683859Sml29623 				bmcr.bits.duplex_mode = 1;
50693859Sml29623 				statsp->mac_stats.link_duplex = 2;
50703859Sml29623 			} else
50713859Sml29623 				statsp->mac_stats.link_duplex = 1;
50726835Syc148097 
50736835Syc148097 		/* Force to 10M */
50743859Sml29623 		} else {
50753859Sml29623 			statsp->mac_stats.link_speed = 10;
50763859Sml29623 			if (param_arr[param_anar_10fdx].value) {
50773859Sml29623 				bmcr.bits.duplex_mode = 1;
50783859Sml29623 				statsp->mac_stats.link_duplex = 2;
50793859Sml29623 			} else
50803859Sml29623 				statsp->mac_stats.link_duplex = 1;
50813859Sml29623 		}
50823859Sml29623 		if (statsp->mac_stats.link_duplex != 1) {
50833859Sml29623 			statsp->mac_stats.link_asmpause =
50846929Smisaki 			    statsp->mac_stats.cap_asmpause;
50853859Sml29623 			statsp->mac_stats.link_pause =
50866929Smisaki 			    statsp->mac_stats.cap_pause;
50873859Sml29623 		}
50883859Sml29623 
50893859Sml29623 		if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
50906929Smisaki 		    (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
50916929Smisaki 		    (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
50923859Sml29623 			if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
50933859Sml29623 				/* BCM5464R 1000mbps external loopback mode */
50943859Sml29623 				gcr.value = 0;
50953859Sml29623 				gcr.bits.ms_mode_en = 1;
50963859Sml29623 				gcr.bits.master = 1;
50973859Sml29623 				if ((status = nxge_mii_write(nxgep, xcvr_portn,
50985125Sjoycey #if defined(__i386)
50996929Smisaki 				    (uint8_t)(uint32_t)(&mii_regs->gcr),
51005125Sjoycey #else
51016929Smisaki 				    (uint8_t)(uint64_t)(&mii_regs->gcr),
51025125Sjoycey #endif
51036929Smisaki 				    gcr.value)) != NXGE_OK)
51043859Sml29623 					goto fail;
51053859Sml29623 				bmcr.value = 0;
51063859Sml29623 				bmcr.bits.speed_1000_sel = 1;
51073859Sml29623 				statsp->mac_stats.link_speed = 1000;
51083859Sml29623 			} else if (statsp->port_stats.lb_mode
51093859Sml29623 			    == nxge_lb_ext100) {
51103859Sml29623 				/* BCM5464R 100mbps external loopback mode */
51113859Sml29623 				bmcr.value = 0;
51123859Sml29623 				bmcr.bits.speed_sel = 1;
51133859Sml29623 				bmcr.bits.duplex_mode = 1;
51143859Sml29623 				statsp->mac_stats.link_speed = 100;
51153859Sml29623 			} else if (statsp->port_stats.lb_mode
51163859Sml29623 			    == nxge_lb_ext10) {
51173859Sml29623 				/* BCM5464R 10mbps external loopback mode */
51183859Sml29623 				bmcr.value = 0;
51193859Sml29623 				bmcr.bits.duplex_mode = 1;
51203859Sml29623 				statsp->mac_stats.link_speed = 10;
51213859Sml29623 			}
51223859Sml29623 		}
51233859Sml29623 	}
51243859Sml29623 
51253859Sml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
51265125Sjoycey #if defined(__i386)
51276929Smisaki 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
51285125Sjoycey #else
51296929Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
51305125Sjoycey #endif
51316929Smisaki 	    bmcr.value)) != NXGE_OK)
51323859Sml29623 		goto fail;
51333859Sml29623 
51343859Sml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
51355125Sjoycey #if defined(__i386)
51366929Smisaki 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
51375125Sjoycey #else
51386929Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
51395125Sjoycey #endif
51406929Smisaki 	    &bmcr.value)) != NXGE_OK)
51413859Sml29623 		goto fail;
51423859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value));
51433859Sml29623 
51443859Sml29623 	/*
51453859Sml29623 	 * Initialize the xcvr status kept in the context structure.
51463859Sml29623 	 */
51473859Sml29623 	nxgep->soft_bmsr.value = 0;
51483859Sml29623 
51493859Sml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
51505125Sjoycey #if defined(__i386)
51516929Smisaki 	    (uint8_t)(uint32_t)(&mii_regs->bmsr),
51525125Sjoycey #else
51536929Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
51545125Sjoycey #endif
51556929Smisaki 	    &nxgep->bmsr.value)) != NXGE_OK)
51563859Sml29623 		goto fail;
51573859Sml29623 
51583859Sml29623 	statsp->mac_stats.xcvr_inits++;
51593859Sml29623 	nxgep->bmsr.value = 0;
51603859Sml29623 
51613859Sml29623 fail:
51623859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51636929Smisaki 	    "<== nxge_mii_xcvr_init status 0x%x", status));
51643859Sml29623 	return (status);
51653859Sml29623 }
51663859Sml29623 
51675196Ssbehera nxge_status_t
nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)51685196Ssbehera nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)
51695196Ssbehera {
51705196Ssbehera 	p_nxge_param_t	param_arr;
51715196Ssbehera 	p_nxge_stats_t	statsp;
51725196Ssbehera 	uint8_t		xcvr_portn;
51735196Ssbehera 	p_mii_regs_t	mii_regs;
51745196Ssbehera 	mii_bmcr_t	bmcr;
51755196Ssbehera 	mii_bmsr_t	bmsr;
51765196Ssbehera 	mii_gcr_t	gcr;
51775196Ssbehera 	mii_esr_t	esr;
51785196Ssbehera 	mii_aux_ctl_t	bcm5464r_aux;
51795196Ssbehera 	int		status = NXGE_OK;
51805196Ssbehera 
51815196Ssbehera 	uint_t delay;
51825196Ssbehera 
51835196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init"));
51845196Ssbehera 
51855196Ssbehera 	param_arr = nxgep->param_arr;
51865196Ssbehera 	statsp = nxgep->statsp;
51875196Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
51885196Ssbehera 
51895196Ssbehera 	mii_regs = NULL;
51905196Ssbehera 
51915196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51925196Ssbehera 	    "nxge_mii_xcvr_fiber_init: "
51935196Ssbehera 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
51945196Ssbehera 
51955196Ssbehera 	/*
51965196Ssbehera 	 * Reset the transceiver.
51975196Ssbehera 	 */
51985196Ssbehera 	delay = 0;
51995196Ssbehera 	bmcr.value = 0;
52005196Ssbehera 	bmcr.bits.reset = 1;
52015196Ssbehera 
52025196Ssbehera #if defined(__i386)
52035196Ssbehera 
52045196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
52055196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
52065196Ssbehera 		goto fail;
52075196Ssbehera #else
52085196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
52095196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
52105196Ssbehera 		goto fail;
52115196Ssbehera #endif
52125196Ssbehera 	do {
52135196Ssbehera 		drv_usecwait(500);
52145196Ssbehera #if defined(__i386)
52155196Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
52165196Ssbehera 		    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value))
52175196Ssbehera 		    != NXGE_OK)
52185196Ssbehera 			goto fail;
52195196Ssbehera #else
52205196Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
52215196Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value))
52225196Ssbehera 		    != NXGE_OK)
52235196Ssbehera 			goto fail;
52245196Ssbehera #endif
52255196Ssbehera 		delay++;
52265196Ssbehera 	} while ((bmcr.bits.reset) && (delay < 1000));
52275196Ssbehera 	if (delay == 1000) {
52285196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
52295196Ssbehera 		goto fail;
52305196Ssbehera 	}
52315196Ssbehera 
52325196Ssbehera #if defined(__i386)
52335196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
52345196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
52355196Ssbehera 		goto fail;
52365196Ssbehera #else
52375196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
52385196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
52395196Ssbehera 		goto fail;
52405196Ssbehera #endif
52415196Ssbehera 
52425196Ssbehera 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
52435196Ssbehera 	param_arr[param_anar_100T4].value = 0;
52445196Ssbehera 	param_arr[param_anar_100fdx].value = 0;
52455196Ssbehera 	param_arr[param_anar_100hdx].value = 0;
52465196Ssbehera 	param_arr[param_anar_10fdx].value = 0;
52475196Ssbehera 	param_arr[param_anar_10hdx].value = 0;
52485196Ssbehera 
52495196Ssbehera 	/*
52505196Ssbehera 	 * Initialize the xcvr statistics.
52515196Ssbehera 	 */
52525196Ssbehera 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
52535196Ssbehera 	statsp->mac_stats.cap_100T4 = 0;
52545196Ssbehera 	statsp->mac_stats.cap_100fdx = 0;
52555196Ssbehera 	statsp->mac_stats.cap_100hdx = 0;
52565196Ssbehera 	statsp->mac_stats.cap_10fdx = 0;
52575196Ssbehera 	statsp->mac_stats.cap_10hdx = 0;
52585196Ssbehera 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
52595196Ssbehera 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
52605196Ssbehera 
52615196Ssbehera 	/*
52625196Ssbehera 	 * Initialize the xcvr advertised capability statistics.
52635196Ssbehera 	 */
52645196Ssbehera 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
52655196Ssbehera 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
52665196Ssbehera 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
52675196Ssbehera 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
52685196Ssbehera 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
52695196Ssbehera 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
52705196Ssbehera 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
52715196Ssbehera 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
52725196Ssbehera 	statsp->mac_stats.adv_cap_asmpause =
52735196Ssbehera 	    param_arr[param_anar_asmpause].value;
52745196Ssbehera 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
52755196Ssbehera 
52765196Ssbehera 	/*
52775196Ssbehera 	 * Check for extended status just in case we're
52785196Ssbehera 	 * running a Gigibit phy.
52795196Ssbehera 	 */
52805196Ssbehera 	if (bmsr.bits.extend_status) {
52815196Ssbehera #if defined(__i386)
52825196Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
52835196Ssbehera 		    (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) !=
52845196Ssbehera 		    NXGE_OK)
52855196Ssbehera 			goto fail;
52865196Ssbehera #else
52875196Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
52885196Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) !=
52895196Ssbehera 		    NXGE_OK)
52905196Ssbehera 			goto fail;
52915196Ssbehera #endif
52925196Ssbehera 		param_arr[param_anar_1000fdx].value &=
52935196Ssbehera 		    esr.bits.link_1000fdx;
52945196Ssbehera 		param_arr[param_anar_1000hdx].value = 0;
52955196Ssbehera 
52965196Ssbehera 		statsp->mac_stats.cap_1000fdx =
52975196Ssbehera 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
52985196Ssbehera 		statsp->mac_stats.cap_1000hdx = 0;
52995196Ssbehera 	} else {
53005196Ssbehera 		param_arr[param_anar_1000fdx].value = 0;
53015196Ssbehera 		param_arr[param_anar_1000hdx].value = 0;
53025196Ssbehera 	}
53035196Ssbehera 
53045196Ssbehera 	/*
53055196Ssbehera 	 * Initialize 1G Statistics once the capability is established.
53065196Ssbehera 	 */
53075196Ssbehera 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
53085196Ssbehera 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
53095196Ssbehera 
53105196Ssbehera 	/*
53115196Ssbehera 	 * Initialize the link statistics.
53125196Ssbehera 	 */
53135196Ssbehera 	statsp->mac_stats.link_T4 = 0;
53145196Ssbehera 	statsp->mac_stats.link_asmpause = 0;
53155196Ssbehera 	statsp->mac_stats.link_pause = 0;
53165196Ssbehera 	statsp->mac_stats.link_speed = 0;
53175196Ssbehera 	statsp->mac_stats.link_duplex = 0;
53185196Ssbehera 	statsp->mac_stats.link_up = 0;
53195196Ssbehera 
53205196Ssbehera 	/*
53215196Ssbehera 	 * Switch off Auto-negotiation, 100M and full duplex.
53225196Ssbehera 	 */
53235196Ssbehera 	bmcr.value = 0;
53245196Ssbehera #if defined(__i386)
53255196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
53265196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
53275196Ssbehera 		goto fail;
53285196Ssbehera #else
53295196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
53305196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
53315196Ssbehera 		goto fail;
53325196Ssbehera #endif
53335196Ssbehera 
53345196Ssbehera 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
53355196Ssbehera 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
53365196Ssbehera 		bmcr.bits.loopback = 1;
53375196Ssbehera 		bmcr.bits.enable_autoneg = 0;
53385196Ssbehera 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
53395196Ssbehera 			bmcr.bits.speed_1000_sel = 1;
53405196Ssbehera 		bmcr.bits.duplex_mode = 1;
53415196Ssbehera 		param_arr[param_autoneg].value = 0;
53425196Ssbehera 	} else {
53435196Ssbehera 		bmcr.bits.loopback = 0;
53445196Ssbehera 	}
53455196Ssbehera 
53465196Ssbehera 	if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
53475196Ssbehera 		param_arr[param_autoneg].value = 0;
53485196Ssbehera 		bcm5464r_aux.value = 0;
53495196Ssbehera 		bcm5464r_aux.bits.ext_lb = 1;
53505196Ssbehera 		bcm5464r_aux.bits.write_1 = 1;
53515196Ssbehera 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
53525196Ssbehera 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
53535196Ssbehera 			goto fail;
53545196Ssbehera 	}
53555196Ssbehera 
53565196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
53575196Ssbehera 	bmcr.bits.speed_1000_sel = 1;
53585196Ssbehera 	bmcr.bits.speed_sel = 0;
53595196Ssbehera 	bmcr.bits.duplex_mode = 1;
53605196Ssbehera 	statsp->mac_stats.link_speed = 1000;
53615196Ssbehera 	statsp->mac_stats.link_duplex = 2;
53625196Ssbehera 
53635196Ssbehera 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) {
53645196Ssbehera 		/* BCM5464R 1000mbps external loopback mode */
53655196Ssbehera 		gcr.value = 0;
53665196Ssbehera 		gcr.bits.ms_mode_en = 1;
53675196Ssbehera 		gcr.bits.master = 1;
53685196Ssbehera #if defined(__i386)
53695196Ssbehera 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
53705196Ssbehera 		    (uint8_t)(uint32_t)(&mii_regs->gcr),
53715196Ssbehera 		    gcr.value)) != NXGE_OK)
53725196Ssbehera 			goto fail;
53735196Ssbehera #else
53745196Ssbehera 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
53755196Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->gcr),
53765196Ssbehera 		    gcr.value)) != NXGE_OK)
53775196Ssbehera 			goto fail;
53785196Ssbehera #endif
53795196Ssbehera 		bmcr.value = 0;
53805196Ssbehera 		bmcr.bits.speed_1000_sel = 1;
53815196Ssbehera 		statsp->mac_stats.link_speed = 1000;
53825196Ssbehera 	}
53835196Ssbehera 
53845196Ssbehera #if defined(__i386)
53855196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
53865196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
53875196Ssbehera 	    bmcr.value)) != NXGE_OK)
53885196Ssbehera 		goto fail;
53895196Ssbehera #else
53905196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
53915196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
53925196Ssbehera 	    bmcr.value)) != NXGE_OK)
53935196Ssbehera 		goto fail;
53945196Ssbehera #endif
53955196Ssbehera 
53965196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
53975196Ssbehera 	    "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x",
53985196Ssbehera 	    bmcr.value));
53995196Ssbehera 
54005196Ssbehera #if defined(__i386)
54015196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
54025196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
54035196Ssbehera 		goto fail;
54045196Ssbehera #else
54055196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
54065196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
54075196Ssbehera 		goto fail;
54085196Ssbehera #endif
54095196Ssbehera 
54105196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
54115196Ssbehera 	    "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value));
54125196Ssbehera 
54135196Ssbehera 	/*
54145196Ssbehera 	 * Initialize the xcvr status kept in the context structure.
54155196Ssbehera 	 */
54165196Ssbehera 	nxgep->soft_bmsr.value = 0;
54175196Ssbehera #if defined(__i386)
54185196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
54195196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmsr),
54205196Ssbehera 	    &nxgep->bmsr.value)) != NXGE_OK)
54215196Ssbehera 		goto fail;
54225196Ssbehera #else
54235196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
54245196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
54255196Ssbehera 	    &nxgep->bmsr.value)) != NXGE_OK)
54265196Ssbehera 		goto fail;
54275196Ssbehera #endif
54285196Ssbehera 
54295196Ssbehera 	statsp->mac_stats.xcvr_inits++;
54305196Ssbehera 	nxgep->bmsr.value = 0;
54315196Ssbehera 
54325196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
54335196Ssbehera 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
54345196Ssbehera 	return (status);
54355196Ssbehera 
54365196Ssbehera fail:
54375196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54385196Ssbehera 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
54395196Ssbehera 	return (status);
54405196Ssbehera }
54415196Ssbehera 
54423859Sml29623 /* Read from a MII compliant register */
54433859Sml29623 
54443859Sml29623 nxge_status_t
nxge_mii_read(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t xcvr_reg,uint16_t * value)54453859Sml29623 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
54463859Sml29623 		uint16_t *value)
54473859Sml29623 {
54483859Sml29623 	npi_status_t rs = NPI_SUCCESS;
54493859Sml29623 
54503859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>"
54516929Smisaki 	    "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
54523859Sml29623 
54536075Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
54543859Sml29623 
54555196Ssbehera 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
54565196Ssbehera 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
54573859Sml29623 		if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle,
54586929Smisaki 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
54593859Sml29623 			goto fail;
54604977Sraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
54614977Sraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
54623859Sml29623 		if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle,
54636929Smisaki 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
54643859Sml29623 			goto fail;
54653859Sml29623 	} else
54663859Sml29623 		goto fail;
54673859Sml29623 
54686075Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54693859Sml29623 
54703859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>"
54716929Smisaki 	    "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, *value));
54723859Sml29623 	return (NXGE_OK);
54733859Sml29623 fail:
54746075Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54753859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54766929Smisaki 	    "nxge_mii_read: Failed to read mii on xcvr %d", xcvr_portn));
54773859Sml29623 
54783859Sml29623 	return (NXGE_ERROR | rs);
54793859Sml29623 }
54803859Sml29623 
54813859Sml29623 /* Write to a MII compliant Register */
54823859Sml29623 
54833859Sml29623 nxge_status_t
nxge_mii_write(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t xcvr_reg,uint16_t value)54843859Sml29623 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
54853859Sml29623 		uint16_t value)
54863859Sml29623 {
54873859Sml29623 	npi_status_t rs = NPI_SUCCESS;
54883859Sml29623 
54893859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>"
54906929Smisaki 	    "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, value));
54913859Sml29623 
54926075Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
54933859Sml29623 
54945196Ssbehera 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
54955196Ssbehera 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
54963859Sml29623 		if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle,
54976929Smisaki 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
54983859Sml29623 			goto fail;
54994977Sraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
55004977Sraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
55013859Sml29623 		if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle,
55026929Smisaki 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
55033859Sml29623 			goto fail;
55043859Sml29623 	} else
55053859Sml29623 		goto fail;
55063859Sml29623 
55076075Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55083859Sml29623 
55093859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>"
55106929Smisaki 	    "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
55113859Sml29623 	return (NXGE_OK);
55123859Sml29623 fail:
55136075Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55143859Sml29623 
55153859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55166929Smisaki 	    "nxge_mii_write: Failed to write mii on xcvr %d", xcvr_portn));
55173859Sml29623 
55183859Sml29623 	return (NXGE_ERROR | rs);
55193859Sml29623 }
55203859Sml29623 
55216835Syc148097 /*
55226835Syc148097  * Perform write to Clause45 serdes / transceiver device
55236835Syc148097  * Arguments:
55246835Syc148097  *	xcvr_portn: 	The IEEE 802.3 Clause45 PHYAD, it is the same as port
55256835Syc148097  *			number if nxge_mdio_write is used for accessing the
55266835Syc148097  *			internal LSIL serdes. Otherwise PHYAD is different
55276835Syc148097  * 			for different platforms.
55286835Syc148097  *	device:		With each PHYAD, the driver can use MDIO to control
55296835Syc148097  *			multiple devices inside the PHY, here "device" is an
55306835Syc148097  *			MMD (MDIO managable device).
55316835Syc148097  *	xcvr_reg:	Each device has multiple registers. xcvr_reg specifies
55326835Syc148097  *			the register which the driver will write value to.
55336835Syc148097  *	value:		The register value will be filled in.
55346835Syc148097  */
55353859Sml29623 nxge_status_t
nxge_mdio_read(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t device,uint16_t xcvr_reg,uint16_t * value)55363859Sml29623 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
55373859Sml29623 		uint16_t xcvr_reg, uint16_t *value)
55383859Sml29623 {
55393859Sml29623 	npi_status_t rs = NPI_SUCCESS;
55403859Sml29623 
55413859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>",
55426929Smisaki 	    xcvr_portn));
55433859Sml29623 
55445780Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
55453859Sml29623 
55463859Sml29623 	if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle,
55476929Smisaki 	    xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
55483859Sml29623 		goto fail;
55493859Sml29623 
55505780Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55513859Sml29623 
55523859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>",
55536929Smisaki 	    xcvr_portn));
55543859Sml29623 	return (NXGE_OK);
55553859Sml29623 fail:
55565780Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55573859Sml29623 
55583859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55596929Smisaki 	    "nxge_mdio_read: Failed to read mdio on xcvr %d", xcvr_portn));
55603859Sml29623 
55613859Sml29623 	return (NXGE_ERROR | rs);
55623859Sml29623 }
55633859Sml29623 
55643859Sml29623 /* Perform write to Clause45 serdes / transceiver device */
55653859Sml29623 
55663859Sml29623 nxge_status_t
nxge_mdio_write(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t device,uint16_t xcvr_reg,uint16_t value)55673859Sml29623 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
55683859Sml29623 		uint16_t xcvr_reg, uint16_t value)
55693859Sml29623 {
55703859Sml29623 	npi_status_t rs = NPI_SUCCESS;
55713859Sml29623 
55723859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>",
55736929Smisaki 	    xcvr_portn));
55743859Sml29623 
55755780Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
55763859Sml29623 
55773859Sml29623 	if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle,
55786929Smisaki 	    xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
55793859Sml29623 		goto fail;
55803859Sml29623 
55815780Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55823859Sml29623 
55833859Sml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>",
55846929Smisaki 	    xcvr_portn));
55853859Sml29623 	return (NXGE_OK);
55863859Sml29623 fail:
55875780Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55883859Sml29623 
55893859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55906929Smisaki 	    "nxge_mdio_write: Failed to write mdio on xcvr %d", xcvr_portn));
55913859Sml29623 
55923859Sml29623 	return (NXGE_ERROR | rs);
55933859Sml29623 }
55943859Sml29623 
55953859Sml29623 
55963859Sml29623 /* Check MII to see if there is any link status change */
55973859Sml29623 
55983859Sml29623 nxge_status_t
nxge_mii_check(p_nxge_t nxgep,mii_bmsr_t bmsr,mii_bmsr_t bmsr_ints,nxge_link_state_t * link_up)55993859Sml29623 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints,
56003859Sml29623 		nxge_link_state_t *link_up)
56013859Sml29623 {
56023859Sml29623 	p_nxge_param_t	param_arr;
56033859Sml29623 	p_nxge_stats_t	statsp;
56043859Sml29623 	p_mii_regs_t	mii_regs;
56053859Sml29623 	p_mii_bmsr_t	soft_bmsr;
56063859Sml29623 	mii_anar_t	anar;
56073859Sml29623 	mii_anlpar_t	anlpar;
56083859Sml29623 	mii_anar_t	an_common;
56093859Sml29623 	mii_aner_t	aner;
56103859Sml29623 	mii_gsr_t	gsr;
56113859Sml29623 	nxge_status_t	status = NXGE_OK;
56123859Sml29623 
56133859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check"));
56143859Sml29623 
56153859Sml29623 	mii_regs = NULL;
56163859Sml29623 	param_arr = nxgep->param_arr;
56173859Sml29623 	statsp = nxgep->statsp;
56183859Sml29623 	soft_bmsr = &nxgep->soft_bmsr;
56193859Sml29623 	*link_up = LINK_NO_CHANGE;
56203859Sml29623 
56215196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56225196Ssbehera 	    "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x",
56235196Ssbehera 	    bmsr.value, bmsr_ints.value));
56245196Ssbehera 
56253859Sml29623 	if (bmsr_ints.bits.link_status) {
56265196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56275196Ssbehera 		    "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x",
56285196Ssbehera 		    bmsr.value, bmsr_ints.value));
56293859Sml29623 		if (bmsr.bits.link_status) {
56303859Sml29623 			soft_bmsr->bits.link_status = 1;
56315196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56325196Ssbehera 		    "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int "
56335196Ssbehera 		    "0x%x", bmsr.value, bmsr_ints.value));
56343859Sml29623 		} else {
563511409Stc99174@train 			/* Only status change will update *link_up */
563611409Stc99174@train 			if (statsp->mac_stats.link_up == 1) {
563711409Stc99174@train 				*link_up = LINK_IS_DOWN;
563811409Stc99174@train 				/* Will notify, turn off further msg */
563911409Stc99174@train 				nxgep->link_notify = B_FALSE;
564011409Stc99174@train 			}
56413859Sml29623 			statsp->mac_stats.link_up = 0;
56423859Sml29623 			soft_bmsr->bits.link_status = 0;
56433859Sml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56446929Smisaki 			    "Link down cable problem"));
56453859Sml29623 		}
56463859Sml29623 	}
56473859Sml29623 
56485196Ssbehera 	if (nxgep->mac.portmode == PORT_1G_COPPER &&
56495196Ssbehera 	    param_arr[param_autoneg].value) {
56503859Sml29623 		if (bmsr_ints.bits.auto_neg_complete) {
56513859Sml29623 			if (bmsr.bits.auto_neg_complete)
56523859Sml29623 				soft_bmsr->bits.auto_neg_complete = 1;
56533859Sml29623 			else
56543859Sml29623 				soft_bmsr->bits.auto_neg_complete = 0;
56553859Sml29623 		}
56563859Sml29623 		if (soft_bmsr->bits.link_status == 0) {
56573859Sml29623 			statsp->mac_stats.link_T4 = 0;
56583859Sml29623 			statsp->mac_stats.link_speed = 0;
56593859Sml29623 			statsp->mac_stats.link_duplex = 0;
56603859Sml29623 			statsp->mac_stats.link_asmpause = 0;
56613859Sml29623 			statsp->mac_stats.link_pause = 0;
56623859Sml29623 			statsp->mac_stats.lp_cap_autoneg = 0;
56633859Sml29623 			statsp->mac_stats.lp_cap_100T4 = 0;
56643859Sml29623 			statsp->mac_stats.lp_cap_1000fdx = 0;
56653859Sml29623 			statsp->mac_stats.lp_cap_1000hdx = 0;
56663859Sml29623 			statsp->mac_stats.lp_cap_100fdx = 0;
56673859Sml29623 			statsp->mac_stats.lp_cap_100hdx = 0;
56683859Sml29623 			statsp->mac_stats.lp_cap_10fdx = 0;
56693859Sml29623 			statsp->mac_stats.lp_cap_10hdx = 0;
56703859Sml29623 			statsp->mac_stats.lp_cap_10gfdx = 0;
56713859Sml29623 			statsp->mac_stats.lp_cap_10ghdx = 0;
56723859Sml29623 			statsp->mac_stats.lp_cap_asmpause = 0;
56733859Sml29623 			statsp->mac_stats.lp_cap_pause = 0;
56743859Sml29623 		}
56753859Sml29623 	} else
56763859Sml29623 		soft_bmsr->bits.auto_neg_complete = 1;
56773859Sml29623 
56783859Sml29623 	if ((bmsr_ints.bits.link_status ||
56796929Smisaki 	    bmsr_ints.bits.auto_neg_complete) &&
56806929Smisaki 	    soft_bmsr->bits.link_status &&
56816929Smisaki 	    soft_bmsr->bits.auto_neg_complete) {
568211409Stc99174@train 		if (statsp->mac_stats.link_up == 0) {
568311409Stc99174@train 			*link_up = LINK_IS_UP;
568411409Stc99174@train 			nxgep->link_notify = B_FALSE;
568511409Stc99174@train 		}
56863859Sml29623 		statsp->mac_stats.link_up = 1;
56875196Ssbehera 
56885196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56895196Ssbehera 		    "==> nxge_mii_check "
56905196Ssbehera 		    "(auto negotiation complete or link up) "
56915196Ssbehera 		    "soft bmsr 0x%x bmsr_int 0x%x",
56925196Ssbehera 		    bmsr.value, bmsr_ints.value));
56935196Ssbehera 
56945196Ssbehera 		if (nxgep->mac.portmode == PORT_1G_COPPER &&
56955196Ssbehera 		    param_arr[param_autoneg].value) {
56963859Sml29623 			if ((status = nxge_mii_read(nxgep,
56976929Smisaki 			    statsp->mac_stats.xcvr_portn,
56985125Sjoycey #if defined(__i386)
56996929Smisaki 			    (uint8_t)(uint32_t)(&mii_regs->anar),
57005125Sjoycey #else
57016929Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->anar),
57025125Sjoycey #endif
57036929Smisaki 			    &anar.value)) != NXGE_OK)
57043859Sml29623 				goto fail;
57053859Sml29623 			if ((status = nxge_mii_read(nxgep,
57066929Smisaki 			    statsp->mac_stats.xcvr_portn,
57075125Sjoycey #if defined(__i386)
57086929Smisaki 			    (uint8_t)(uint32_t)(&mii_regs->anlpar),
57095125Sjoycey #else
57106929Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->anlpar),
57115125Sjoycey #endif
57126929Smisaki 			    &anlpar.value)) != NXGE_OK)
57133859Sml29623 				goto fail;
57143859Sml29623 			if ((status = nxge_mii_read(nxgep,
57156929Smisaki 			    statsp->mac_stats.xcvr_portn,
57165125Sjoycey #if defined(__i386)
57176929Smisaki 			    (uint8_t)(uint32_t)(&mii_regs->aner),
57185125Sjoycey #else
57196929Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->aner),
57205125Sjoycey #endif
57216929Smisaki 			    &aner.value)) != NXGE_OK)
57223859Sml29623 				goto fail;
57233859Sml29623 			statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able;
57243859Sml29623 			statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4;
57253859Sml29623 			statsp->mac_stats.lp_cap_100fdx =
57266929Smisaki 			    anlpar.bits.cap_100fdx;
57273859Sml29623 			statsp->mac_stats.lp_cap_100hdx =
57286929Smisaki 			    anlpar.bits.cap_100hdx;
57293859Sml29623 			statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx;
57303859Sml29623 			statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx;
57313859Sml29623 			statsp->mac_stats.lp_cap_asmpause =
57326929Smisaki 			    anlpar.bits.cap_asmpause;
57333859Sml29623 			statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause;
57343859Sml29623 			an_common.value = anar.value & anlpar.value;
57353859Sml29623 			if (param_arr[param_anar_1000fdx].value ||
57366929Smisaki 			    param_arr[param_anar_1000hdx].value) {
57373859Sml29623 				if ((status = nxge_mii_read(nxgep,
57386929Smisaki 				    statsp->mac_stats.xcvr_portn,
57395125Sjoycey #if defined(__i386)
57406929Smisaki 				    (uint8_t)(uint32_t)(&mii_regs->gsr),
57415125Sjoycey #else
57426929Smisaki 				    (uint8_t)(uint64_t)(&mii_regs->gsr),
57435125Sjoycey #endif
57446929Smisaki 				    &gsr.value)) != NXGE_OK)
57453859Sml29623 					goto fail;
57463859Sml29623 				statsp->mac_stats.lp_cap_1000fdx =
57476929Smisaki 				    gsr.bits.link_1000fdx;
57483859Sml29623 				statsp->mac_stats.lp_cap_1000hdx =
57496929Smisaki 				    gsr.bits.link_1000hdx;
57503859Sml29623 				if (param_arr[param_anar_1000fdx].value &&
57516929Smisaki 				    gsr.bits.link_1000fdx) {
57523859Sml29623 					statsp->mac_stats.link_speed = 1000;
57533859Sml29623 					statsp->mac_stats.link_duplex = 2;
57543859Sml29623 				} else if (
57556929Smisaki 				    param_arr[param_anar_1000hdx].value &&
57566929Smisaki 				    gsr.bits.link_1000hdx) {
57573859Sml29623 					statsp->mac_stats.link_speed = 1000;
57583859Sml29623 					statsp->mac_stats.link_duplex = 1;
57593859Sml29623 				}
57603859Sml29623 			}
57613859Sml29623 			if ((an_common.value != 0) &&
57626929Smisaki 			    !(statsp->mac_stats.link_speed)) {
57633859Sml29623 				if (an_common.bits.cap_100T4) {
57643859Sml29623 					statsp->mac_stats.link_T4 = 1;
57653859Sml29623 					statsp->mac_stats.link_speed = 100;
57663859Sml29623 					statsp->mac_stats.link_duplex = 1;
57673859Sml29623 				} else if (an_common.bits.cap_100fdx) {
57683859Sml29623 					statsp->mac_stats.link_speed = 100;
57693859Sml29623 					statsp->mac_stats.link_duplex = 2;
57703859Sml29623 				} else if (an_common.bits.cap_100hdx) {
57713859Sml29623 					statsp->mac_stats.link_speed = 100;
57723859Sml29623 					statsp->mac_stats.link_duplex = 1;
57733859Sml29623 				} else if (an_common.bits.cap_10fdx) {
57743859Sml29623 					statsp->mac_stats.link_speed = 10;
57753859Sml29623 					statsp->mac_stats.link_duplex = 2;
57763859Sml29623 				} else if (an_common.bits.cap_10hdx) {
57773859Sml29623 					statsp->mac_stats.link_speed = 10;
57783859Sml29623 					statsp->mac_stats.link_duplex = 1;
57793859Sml29623 				} else {
57803859Sml29623 					goto fail;
57813859Sml29623 				}
57823859Sml29623 			}
57833859Sml29623 			if (statsp->mac_stats.link_duplex != 1) {
57846929Smisaki 				int	link_pause;
57856929Smisaki 				int	cp, lcp;
57866929Smisaki 
57873859Sml29623 				statsp->mac_stats.link_asmpause =
57886929Smisaki 				    an_common.bits.cap_asmpause;
57896929Smisaki 				cp = statsp->mac_stats.cap_pause;
57906929Smisaki 				lcp = statsp->mac_stats.lp_cap_pause;
57916929Smisaki 				if (statsp->mac_stats.link_asmpause) {
57926929Smisaki 					if ((cp == 0) && (lcp == 1)) {
57936929Smisaki 						link_pause = 0;
57946929Smisaki 					} else {
57956929Smisaki 						link_pause = 1;
57966929Smisaki 					}
57976929Smisaki 				} else {
57986929Smisaki 					link_pause = an_common.bits.cap_pause;
57996929Smisaki 				}
58006929Smisaki 				statsp->mac_stats.link_pause = link_pause;
58013859Sml29623 			}
58025196Ssbehera 		} else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
58035196Ssbehera 			statsp->mac_stats.link_speed = 1000;
58045196Ssbehera 			statsp->mac_stats.link_duplex = 2;
58053859Sml29623 		}
580611409Stc99174@train 	}
580711409Stc99174@train 	/* Initial link_notify, delay link down msg */
580811409Stc99174@train 	if (nxgep->link_notify && nxgep->nxge_mac_state == NXGE_MAC_STARTED &&
580911409Stc99174@train 	    (statsp->mac_stats.link_up == 1 || nxgep->link_check_count > 3)) {
58103859Sml29623 		*link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP :
58116929Smisaki 		    LINK_IS_DOWN);
58123859Sml29623 		nxgep->link_notify = B_FALSE;
58133859Sml29623 	}
58143859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check"));
58153859Sml29623 	return (NXGE_OK);
58163859Sml29623 fail:
58173859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
58186929Smisaki 	    "nxge_mii_check: Unable to check MII"));
58193859Sml29623 	return (status);
58203859Sml29623 }
58213859Sml29623 
58226835Syc148097 /*
58236835Syc148097  * Check PCS to see if there is any link status change.
58246835Syc148097  * This function is called by PORT_1G_SERDES only.
58256835Syc148097  */
58266835Syc148097 void
nxge_pcs_check(p_nxge_t nxgep,uint8_t portn,nxge_link_state_t * link_up)58274977Sraghus nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up)
58284977Sraghus {
58294977Sraghus 	p_nxge_stats_t	statsp;
58304977Sraghus 	boolean_t	linkup;
58314977Sraghus 
58324977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check"));
58334977Sraghus 
58344977Sraghus 	statsp = nxgep->statsp;
58354977Sraghus 	*link_up = LINK_NO_CHANGE;
58364977Sraghus 
58374977Sraghus 	(void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup);
58384977Sraghus 	if (linkup) {
583911409Stc99174@train 		if ((nxgep->link_notify &&
584011409Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
58414977Sraghus 		    nxgep->statsp->mac_stats.link_up == 0) {
58424977Sraghus 			statsp->mac_stats.link_up = 1;
58434977Sraghus 			statsp->mac_stats.link_speed = 1000;
58444977Sraghus 			statsp->mac_stats.link_duplex = 2;
58454977Sraghus 			*link_up = LINK_IS_UP;
58464977Sraghus 			nxgep->link_notify = B_FALSE;
58474977Sraghus 		}
58484977Sraghus 	} else {
584911409Stc99174@train 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
585011409Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
58514977Sraghus 		    nxgep->statsp->mac_stats.link_up == 1) {
58524977Sraghus 			statsp->mac_stats.link_up = 0;
58534977Sraghus 			statsp->mac_stats.link_speed = 0;
58544977Sraghus 			statsp->mac_stats.link_duplex = 0;
58554977Sraghus 			*link_up = LINK_IS_DOWN;
58564977Sraghus 			nxgep->link_notify = B_FALSE;
58574977Sraghus 		}
58584977Sraghus 	}
58594977Sraghus 
58604977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check"));
58614977Sraghus }
58624977Sraghus 
58633859Sml29623 /* Add a multicast address entry into the HW hash table */
58643859Sml29623 
58653859Sml29623 nxge_status_t
nxge_add_mcast_addr(p_nxge_t nxgep,struct ether_addr * addrp)58663859Sml29623 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
58673859Sml29623 {
58683859Sml29623 	uint32_t mchash;
58693859Sml29623 	p_hash_filter_t hash_filter;
58703859Sml29623 	uint16_t hash_bit;
58713859Sml29623 	uint_t j;
58723859Sml29623 	nxge_status_t status = NXGE_OK;
587311878SVenu.Iyer@Sun.COM 	npi_status_t rs;
58743859Sml29623 
58753859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr"));
58763859Sml29623 
58773859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
58783859Sml29623 	mchash = crc32_mchash(addrp);
58793859Sml29623 	if (nxgep->hash_filter == NULL) {
58803859Sml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
58816929Smisaki 		    "Allocating hash filter storage."));
58823859Sml29623 		nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t),
58836929Smisaki 		    KM_SLEEP);
58843859Sml29623 	}
588511878SVenu.Iyer@Sun.COM 
58863859Sml29623 	hash_filter = nxgep->hash_filter;
58873859Sml29623 	j = mchash / HASH_REG_WIDTH;
58883859Sml29623 	hash_bit = (1 << (mchash % HASH_REG_WIDTH));
58893859Sml29623 	hash_filter->hash_filter_regs[j] |= hash_bit;
58903859Sml29623 	hash_filter->hash_bit_ref_cnt[mchash]++;
58913859Sml29623 	if (hash_filter->hash_bit_ref_cnt[mchash] == 1) {
58923859Sml29623 		hash_filter->hash_ref_cnt++;
589311878SVenu.Iyer@Sun.COM 	}
589411878SVenu.Iyer@Sun.COM 
589511878SVenu.Iyer@Sun.COM 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
589611878SVenu.Iyer@Sun.COM 	if (rs != NPI_SUCCESS)
589711878SVenu.Iyer@Sun.COM 		goto fail;
58983859Sml29623 
58993859Sml29623 	RW_EXIT(&nxgep->filter_lock);
59003859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr"));
59013859Sml29623 	return (NXGE_OK);
59023859Sml29623 fail:
59033859Sml29623 	RW_EXIT(&nxgep->filter_lock);
59043859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: "
59056929Smisaki 	    "Unable to add multicast address"));
59063859Sml29623 	return (status);
59073859Sml29623 }
59083859Sml29623 
59093859Sml29623 /* Remove a multicast address entry from the HW hash table */
59103859Sml29623 
59113859Sml29623 nxge_status_t
nxge_del_mcast_addr(p_nxge_t nxgep,struct ether_addr * addrp)59123859Sml29623 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
59133859Sml29623 {
59143859Sml29623 	uint32_t mchash;
59153859Sml29623 	p_hash_filter_t hash_filter;
59163859Sml29623 	uint16_t hash_bit;
59173859Sml29623 	uint_t j;
59183859Sml29623 	nxge_status_t status = NXGE_OK;
591911878SVenu.Iyer@Sun.COM 	npi_status_t rs;
59203859Sml29623 
59213859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr"));
59223859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
59233859Sml29623 	mchash = crc32_mchash(addrp);
59243859Sml29623 	if (nxgep->hash_filter == NULL) {
59253859Sml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
59266929Smisaki 		    "Hash filter already de_allocated."));
59273859Sml29623 		RW_EXIT(&nxgep->filter_lock);
59283859Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
59293859Sml29623 		return (NXGE_OK);
59303859Sml29623 	}
59313859Sml29623 	hash_filter = nxgep->hash_filter;
59323859Sml29623 	hash_filter->hash_bit_ref_cnt[mchash]--;
59333859Sml29623 	if (hash_filter->hash_bit_ref_cnt[mchash] == 0) {
59343859Sml29623 		j = mchash / HASH_REG_WIDTH;
59353859Sml29623 		hash_bit = (1 << (mchash % HASH_REG_WIDTH));
59363859Sml29623 		hash_filter->hash_filter_regs[j] &= ~hash_bit;
59373859Sml29623 		hash_filter->hash_ref_cnt--;
593811878SVenu.Iyer@Sun.COM 	}
593911878SVenu.Iyer@Sun.COM 
59403859Sml29623 	if (hash_filter->hash_ref_cnt == 0) {
59413859Sml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
59426929Smisaki 		    "De-allocating hash filter storage."));
59433859Sml29623 		KMEM_FREE(hash_filter, sizeof (hash_filter_t));
59443859Sml29623 		nxgep->hash_filter = NULL;
59453859Sml29623 	}
59463859Sml29623 
594711878SVenu.Iyer@Sun.COM 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
594811878SVenu.Iyer@Sun.COM 	if (rs != NPI_SUCCESS)
594911878SVenu.Iyer@Sun.COM 		goto fail;
595011878SVenu.Iyer@Sun.COM 
59513859Sml29623 	RW_EXIT(&nxgep->filter_lock);
59523859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
59533859Sml29623 
59543859Sml29623 	return (NXGE_OK);
59553859Sml29623 fail:
59563859Sml29623 	RW_EXIT(&nxgep->filter_lock);
59573859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: "
59586929Smisaki 	    "Unable to remove multicast address"));
59593859Sml29623 
59603859Sml29623 	return (status);
59613859Sml29623 }
59623859Sml29623 
59633859Sml29623 /* Set MAC address into MAC address HW registers */
59643859Sml29623 
59653859Sml29623 nxge_status_t
nxge_set_mac_addr(p_nxge_t nxgep,struct ether_addr * addrp)59663859Sml29623 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp)
59673859Sml29623 {
59683859Sml29623 	nxge_status_t status = NXGE_OK;
59693859Sml29623 
59703859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr"));
59713859Sml29623 
59723859Sml29623 	MUTEX_ENTER(&nxgep->ouraddr_lock);
59733859Sml29623 	/*
59743859Sml29623 	 * Exit if the address is same as ouraddr or multicast or broadcast
59753859Sml29623 	 */
59763859Sml29623 	if (((addrp->ether_addr_octet[0] & 01) == 1) ||
59776929Smisaki 	    (ether_cmp(addrp, &etherbroadcastaddr) == 0) ||
59786929Smisaki 	    (ether_cmp(addrp, &nxgep->ouraddr) == 0)) {
59793859Sml29623 		goto nxge_set_mac_addr_exit;
59803859Sml29623 	}
59813859Sml29623 	nxgep->ouraddr = *addrp;
59823859Sml29623 	/*
59833859Sml29623 	 * Set new interface local address and re-init device.
59843859Sml29623 	 * This is destructive to any other streams attached
59853859Sml29623 	 * to this device.
59863859Sml29623 	 */
59873859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
59883859Sml29623 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
59893859Sml29623 		goto fail;
59903859Sml29623 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
59913859Sml29623 		goto fail;
59923859Sml29623 
59933859Sml29623 	RW_EXIT(&nxgep->filter_lock);
59943859Sml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
59953859Sml29623 	goto nxge_set_mac_addr_end;
59963859Sml29623 nxge_set_mac_addr_exit:
59973859Sml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
59983859Sml29623 nxge_set_mac_addr_end:
59993859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr"));
60003859Sml29623 
60013859Sml29623 	return (NXGE_OK);
60023859Sml29623 fail:
60033859Sml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
60043859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: "
60056929Smisaki 	    "Unable to set mac address"));
60063859Sml29623 	return (status);
60073859Sml29623 }
60083859Sml29623 
60094693Stm144005 static
60104693Stm144005 check_link_state_t
nxge_check_link_stop(nxge_t * nxge)60116835Syc148097 nxge_check_link_stop(nxge_t *nxge)
60124693Stm144005 {
60134693Stm144005 	/* If the poll has been cancelled, return STOP. */
60144693Stm144005 	MUTEX_ENTER(&nxge->poll_lock);
60154693Stm144005 	if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) {
60164693Stm144005 		nxge->poll_state = LINK_MONITOR_STOP;
60174693Stm144005 		nxge->nxge_link_poll_timerid = 0;
60184693Stm144005 		cv_broadcast(&nxge->poll_cv);
60194693Stm144005 		MUTEX_EXIT(&nxge->poll_lock);
60204693Stm144005 
60214693Stm144005 		NXGE_DEBUG_MSG((nxge, MAC_CTL,
60224693Stm144005 		    "nxge_check_%s_link(port<%d>) stopped.",
60234693Stm144005 		    nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii",
60244693Stm144005 		    nxge->mac.portnum));
60254693Stm144005 		return (CHECK_LINK_STOP);
60264693Stm144005 	}
60274693Stm144005 	MUTEX_EXIT(&nxge->poll_lock);
60284693Stm144005 
60294693Stm144005 	return (CHECK_LINK_RESCHEDULE);
60304693Stm144005 }
60314693Stm144005 
60326835Syc148097 /*
60336835Syc148097  * Check status of MII (MIF or PCS) link.
60346835Syc148097  * This function is called once per second, that is because this function
60356835Syc148097  * calls nxge_link_monitor with LINK_MONITOR_START, which starts a timer to
60366835Syc148097  * call this function recursively.
60376835Syc148097  */
60384732Sdavemq static nxge_status_t
nxge_check_mii_link(p_nxge_t nxgep)60393859Sml29623 nxge_check_mii_link(p_nxge_t nxgep)
60403859Sml29623 {
60413859Sml29623 	mii_bmsr_t bmsr_ints, bmsr_data;
60423859Sml29623 	mii_anlpar_t anlpar;
60433859Sml29623 	mii_gsr_t gsr;
60443859Sml29623 	p_mii_regs_t mii_regs;
60453859Sml29623 	nxge_status_t status = NXGE_OK;
60463859Sml29623 	uint8_t portn;
60473859Sml29623 	nxge_link_state_t link_up;
60483859Sml29623 
60494693Stm144005 	if (nxgep->nxge_magic != NXGE_MAGIC)
60504693Stm144005 		return (NXGE_ERROR);
60514693Stm144005 
60524693Stm144005 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
60534693Stm144005 		return (NXGE_OK);
60544693Stm144005 
60553859Sml29623 	portn = nxgep->mac.portnum;
60563859Sml29623 
60573859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>",
60584693Stm144005 	    portn));
60593859Sml29623 
60603859Sml29623 	mii_regs = NULL;
60613859Sml29623 
60623859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
60633859Sml29623 
60643859Sml29623 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
60653859Sml29623 		goto nxge_check_mii_link_exit;
60663859Sml29623 
60674977Sraghus 	switch (nxgep->mac.portmode) {
60684977Sraghus 	default:
60695196Ssbehera 		bmsr_data.value = 0;
60703859Sml29623 		if ((status = nxge_mii_read(nxgep,
60714977Sraghus 		    nxgep->statsp->mac_stats.xcvr_portn,
60725125Sjoycey #if defined(__i386)
60735125Sjoycey 		    (uint8_t)(uint32_t)(&mii_regs->bmsr),
60745125Sjoycey #else
60754977Sraghus 		    (uint8_t)(uint64_t)(&mii_regs->bmsr),
60765125Sjoycey #endif
60774977Sraghus 		    &bmsr_data.value)) != NXGE_OK) {
60783859Sml29623 			goto fail;
60793859Sml29623 		}
60804977Sraghus 
60815196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
60825196Ssbehera 		    "==> nxge_check_mii_link port<0x%x> "
60835196Ssbehera 		    "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ",
60845572Ssbehera 		    portn, bmsr_data.value, nxgep->bmsr.value));
60855196Ssbehera 
60864977Sraghus 		if (nxgep->param_arr[param_autoneg].value) {
60874977Sraghus 			if ((status = nxge_mii_read(nxgep,
60886929Smisaki 			    nxgep->statsp->mac_stats.xcvr_portn,
60895125Sjoycey #if defined(__i386)
60906929Smisaki 			    (uint8_t)(uint32_t)(&mii_regs->gsr),
60915125Sjoycey #else
60926929Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->gsr),
60935125Sjoycey #endif
60946929Smisaki 			    &gsr.value)) != NXGE_OK)
60954977Sraghus 				goto fail;
60964977Sraghus 			if ((status = nxge_mii_read(nxgep,
60976929Smisaki 			    nxgep->statsp->mac_stats.xcvr_portn,
60985125Sjoycey #if defined(__i386)
60996929Smisaki 			    (uint8_t)(uint32_t)(&mii_regs->anlpar),
61005125Sjoycey #else
61016929Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->anlpar),
61025125Sjoycey #endif
61036929Smisaki 			    &anlpar.value)) != NXGE_OK)
61044977Sraghus 				goto fail;
61055196Ssbehera 			if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) {
61065196Ssbehera 
61075196Ssbehera 				if (nxgep->statsp->mac_stats.link_up &&
61085196Ssbehera 				    ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^
61095196Ssbehera 				    gsr.bits.link_1000fdx) ||
61105196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_1000hdx ^
61115196Ssbehera 				    gsr.bits.link_1000hdx) ||
61125196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100T4 ^
61135196Ssbehera 				    anlpar.bits.cap_100T4) ||
61145196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100fdx ^
61155196Ssbehera 				    anlpar.bits.cap_100fdx) ||
61165196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100hdx ^
61175196Ssbehera 				    anlpar.bits.cap_100hdx) ||
61185196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_10fdx ^
61195196Ssbehera 				    anlpar.bits.cap_10fdx) ||
61205196Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_10hdx ^
61215196Ssbehera 				    anlpar.bits.cap_10hdx))) {
61225196Ssbehera 					bmsr_data.bits.link_status = 0;
61235196Ssbehera 				}
61244977Sraghus 			}
61254977Sraghus 		}
61264977Sraghus 
61274977Sraghus 		/* Workaround for link down issue */
61284977Sraghus 		if (bmsr_data.value == 0) {
61294977Sraghus 			cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
61304977Sraghus 			goto nxge_check_mii_link_exit;
61314977Sraghus 		}
61324977Sraghus 
61335196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61345196Ssbehera 		    "==> nxge_check_mii_link port<0x%x> :"
61355196Ssbehera 		    "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x",
61365572Ssbehera 		    portn, nxgep->bmsr.value, bmsr_data.value));
61375196Ssbehera 
61384977Sraghus 		bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value;
61394977Sraghus 		nxgep->bmsr.value = bmsr_data.value;
61405196Ssbehera 
61415196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61425196Ssbehera 		    "==> nxge_check_mii_link port<0x%x> CALLING "
61435196Ssbehera 		    "bmsr_data 0x%x bmsr_ints.value 0x%x",
61445572Ssbehera 		    portn, bmsr_data.value, bmsr_ints.value));
61455196Ssbehera 
61464977Sraghus 		if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints,
61474977Sraghus 		    &link_up)) != NXGE_OK) {
61484977Sraghus 			goto fail;
61494977Sraghus 		}
61504977Sraghus 		break;
61514977Sraghus 
61524977Sraghus 	case PORT_1G_SERDES:
61536835Syc148097 		/*
61546835Syc148097 		 * Above default is for all cases except PORT_1G_SERDES.
61556835Syc148097 		 * The default case gets information from the PHY, but a
61566835Syc148097 		 * nxge whose portmode equals PORT_1G_SERDES does not
61576835Syc148097 		 * have a PHY.
61586835Syc148097 		 */
61594977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61604977Sraghus 		    "==> nxge_check_mii_link port<%d> (SERDES)", portn));
61616835Syc148097 		nxge_pcs_check(nxgep, portn, &link_up);
61624977Sraghus 		break;
61633859Sml29623 	}
61643859Sml29623 
61653859Sml29623 nxge_check_mii_link_exit:
61663859Sml29623 	RW_EXIT(&nxgep->filter_lock);
61673859Sml29623 	if (link_up == LINK_IS_UP) {
61683859Sml29623 		nxge_link_is_up(nxgep);
61693859Sml29623 	} else if (link_up == LINK_IS_DOWN) {
61703859Sml29623 		nxge_link_is_down(nxgep);
61713859Sml29623 	}
61723859Sml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
61733859Sml29623 
61743859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>",
61756929Smisaki 	    portn));
61763859Sml29623 	return (NXGE_OK);
61773859Sml29623 
61783859Sml29623 fail:
61793859Sml29623 	RW_EXIT(&nxgep->filter_lock);
61803859Sml29623 
61813859Sml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
61823859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
61836929Smisaki 	    "nxge_check_mii_link: Failed to check link port<%d>", portn));
61843859Sml29623 	return (status);
61853859Sml29623 }
61863859Sml29623 
61873859Sml29623 /*ARGSUSED*/
61884732Sdavemq static nxge_status_t
nxge_check_10g_link(p_nxge_t nxgep)61893859Sml29623 nxge_check_10g_link(p_nxge_t nxgep)
61903859Sml29623 {
61913859Sml29623 	uint8_t		portn;
61923859Sml29623 	nxge_status_t	status = NXGE_OK;
61935422Ssbehera 	boolean_t	link_up;
61944977Sraghus 	uint32_t	val;
61954977Sraghus 	npi_status_t	rs;
61963859Sml29623 
61974693Stm144005 	if (nxgep->nxge_magic != NXGE_MAGIC)
61984693Stm144005 		return (NXGE_ERROR);
61994693Stm144005 
62004693Stm144005 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
62014693Stm144005 		return (NXGE_OK);
62024693Stm144005 
62033859Sml29623 	portn = nxgep->mac.portnum;
62045196Ssbehera 	val = 0;
62055196Ssbehera 	rs = NPI_SUCCESS;
62063859Sml29623 
62073859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
62084693Stm144005 	    portn));
62093859Sml29623 
62104977Sraghus 	switch (nxgep->mac.portmode) {
62114977Sraghus 	default:
62125572Ssbehera 		/*
62135572Ssbehera 		 * Check if the phy is present in case of hot swappable phy
62145572Ssbehera 		 */
62155572Ssbehera 		if (nxgep->hot_swappable_phy) {
62165572Ssbehera 			boolean_t phy_present_now = B_FALSE;
62175572Ssbehera 
621812103SSantwona.Behera@Sun.COM 			if (nxge_hswap_phy_present(nxgep, portn))
62195572Ssbehera 				phy_present_now = B_TRUE;
622012103SSantwona.Behera@Sun.COM 
62219599Stc99174@train 			/* Check back-to-back XAUI connect to detect Opus NEM */
62229599Stc99174@train 			rs = npi_xmac_xpcs_read(nxgep->npi_handle,
62239599Stc99174@train 			    nxgep->mac.portnum, XPCS_REG_STATUS, &val);
62249599Stc99174@train 			if (rs != 0)
62259599Stc99174@train 				goto fail;
62269599Stc99174@train 
62279599Stc99174@train 			link_up = B_FALSE;
62289599Stc99174@train 			if (val & XPCS_STATUS_LANE_ALIGN) {
62299599Stc99174@train 				link_up = B_TRUE;
62309599Stc99174@train 			}
62319599Stc99174@train 
62325572Ssbehera 			if (nxgep->phy_absent) {
62335572Ssbehera 				if (phy_present_now) {
62345572Ssbehera 				/*
62355572Ssbehera 				 * Detect, Initialize phy and do link up
62365572Ssbehera 				 * set xcvr vals, link_init, nxge_init
62375572Ssbehera 				 */
62385572Ssbehera 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
62395572Ssbehera 					    "Hot swappable phy DETECTED!!"));
62405572Ssbehera 					nxgep->phy_absent = B_FALSE;
62415572Ssbehera 					(void) nxge_xcvr_find(nxgep);
62425572Ssbehera 					(void) nxge_link_init(nxgep);
62435572Ssbehera 					if (!(nxgep->drv_state &
62445572Ssbehera 					    STATE_HW_INITIALIZED)) {
62455572Ssbehera 						status = nxge_init(nxgep);
62465572Ssbehera 						if (status != NXGE_OK) {
62475572Ssbehera 							NXGE_ERROR_MSG((nxgep,
62485572Ssbehera 							    NXGE_ERR_CTL,
62495572Ssbehera 							    "Hot swappable "
62505572Ssbehera 							    "phy present, but"
62515572Ssbehera 							    " driver init"
62525572Ssbehera 							    "  failed..."));
62535572Ssbehera 							goto fail;
62545572Ssbehera 						}
62555572Ssbehera 					}
62569599Stc99174@train 				} else if (link_up) { /* XAUI linkup, no PHY */
62579730SMichael.Speer@Sun.COM 					/*
62589599Stc99174@train 					 * This is the back-to-back XAUI
62599599Stc99174@train 					 * connect case for Opus NEM.
62609599Stc99174@train 					 */
62619599Stc99174@train 					nxgep->statsp->mac_stats.xcvr_inuse =
62629599Stc99174@train 					    XPCS_XCVR;
62639599Stc99174@train 					nxgep->mac.portmode = PORT_10G_SERDES;
62649599Stc99174@train 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
62659599Stc99174@train 					    "HSP 10G Serdes DETECTED!!"));
62669599Stc99174@train 					break;
62675572Ssbehera 				}
62685572Ssbehera 
626911409Stc99174@train 				if (nxgep->link_notify &&
627011409Stc99174@train 				    nxgep->link_check_count > 3 &&
627111409Stc99174@train 				    nxgep->nxge_mac_state == NXGE_MAC_STARTED ||
627211409Stc99174@train 				    nxgep->statsp->mac_stats.link_up == 1) {
627311409Stc99174@train 					nxgep->statsp->mac_stats.link_up = 0;
627411409Stc99174@train 					nxgep->statsp->mac_stats.link_speed = 0;
627511409Stc99174@train 					nxgep->statsp->mac_stats.link_duplex =
627611409Stc99174@train 					    0;
627711409Stc99174@train 
627811409Stc99174@train 					nxge_link_is_down(nxgep);
627911409Stc99174@train 					nxgep->link_notify = B_FALSE;
628011409Stc99174@train 				}
628111409Stc99174@train 
62825572Ssbehera 				goto start_link_check;
62835572Ssbehera 
62845572Ssbehera 			} else if (!phy_present_now) {
62855572Ssbehera 				/*
62865572Ssbehera 				 * Phy gone, bring link down reset xcvr vals
62875572Ssbehera 				 */
62885572Ssbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
62895572Ssbehera 				    "Hot swappable phy REMOVED!!"));
62905572Ssbehera 				nxgep->phy_absent = B_TRUE;
62915572Ssbehera 				nxgep->statsp->mac_stats.link_up = 0;
62925572Ssbehera 				nxgep->statsp->mac_stats.link_speed = 0;
62935572Ssbehera 				nxgep->statsp->mac_stats.link_duplex = 0;
62945572Ssbehera 				nxge_link_is_down(nxgep);
62955572Ssbehera 				nxgep->link_notify = B_FALSE;
62965572Ssbehera 
62975572Ssbehera 				(void) nxge_xcvr_find(nxgep);
62985572Ssbehera 
62995572Ssbehera 				goto start_link_check;
63005572Ssbehera 
63015572Ssbehera 			}
63025572Ssbehera 		}
630312103SSantwona.Behera@Sun.COM 
630412103SSantwona.Behera@Sun.COM 		switch (nxgep->chip_id) {
630512103SSantwona.Behera@Sun.COM 		case MRVL88X201X_CHIP_ID:
63066835Syc148097 			status = nxge_check_mrvl88x2011_link(nxgep, &link_up);
630712103SSantwona.Behera@Sun.COM 			break;
630812103SSantwona.Behera@Sun.COM 		case NLP2020_CHIP_ID:
630912103SSantwona.Behera@Sun.COM 			status = nxge_check_nlp2020_link(nxgep, &link_up);
631012103SSantwona.Behera@Sun.COM 			break;
631112103SSantwona.Behera@Sun.COM 		default:
63126604Ssbehera 			status = nxge_check_bcm8704_link(nxgep, &link_up);
631312103SSantwona.Behera@Sun.COM 			break;
63146604Ssbehera 		}
631512103SSantwona.Behera@Sun.COM 
63164977Sraghus 		if (status != NXGE_OK)
63174977Sraghus 			goto fail;
63184977Sraghus 		break;
63194977Sraghus 	case PORT_10G_SERDES:
63204977Sraghus 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
63215422Ssbehera 		    XPCS_REG_STATUS, &val);
63224977Sraghus 		if (rs != 0)
63234977Sraghus 			goto fail;
63244977Sraghus 
63254977Sraghus 		link_up = B_FALSE;
63265422Ssbehera 		if (val & XPCS_STATUS_LANE_ALIGN) {
63275422Ssbehera 			link_up = B_TRUE;
63284977Sraghus 		}
63294977Sraghus 
63304977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
63314977Sraghus 		    "==> nxge_check_10g_link port<%d> "
63325422Ssbehera 		    "XPCS_REG_STATUS2 0x%x link_up %d",
63335422Ssbehera 		    portn, val, link_up));
63345422Ssbehera 
63354977Sraghus 		break;
63364977Sraghus 	}
63373859Sml29623 
63383859Sml29623 	if (link_up) {
633911409Stc99174@train 		if ((nxgep->link_notify &&
634011409Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
63416929Smisaki 		    nxgep->statsp->mac_stats.link_up == 0) {
63423859Sml29623 			if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
63433859Sml29623 				goto fail;
63443859Sml29623 			nxgep->statsp->mac_stats.link_up = 1;
63453859Sml29623 			nxgep->statsp->mac_stats.link_speed = 10000;
63463859Sml29623 			nxgep->statsp->mac_stats.link_duplex = 2;
63473859Sml29623 
63483859Sml29623 			nxge_link_is_up(nxgep);
63493859Sml29623 			nxgep->link_notify = B_FALSE;
63503859Sml29623 		}
63513859Sml29623 	} else {
635211409Stc99174@train 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
635311409Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
63546929Smisaki 		    nxgep->statsp->mac_stats.link_up == 1) {
63553859Sml29623 			if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
63563859Sml29623 				goto fail;
63573859Sml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
63586929Smisaki 			    "Link down cable problem"));
63593859Sml29623 			nxgep->statsp->mac_stats.link_up = 0;
63603859Sml29623 			nxgep->statsp->mac_stats.link_speed = 0;
63613859Sml29623 			nxgep->statsp->mac_stats.link_duplex = 0;
63623859Sml29623 
63633859Sml29623 			nxge_link_is_down(nxgep);
63643859Sml29623 			nxgep->link_notify = B_FALSE;
63659599Stc99174@train 
63669599Stc99174@train 			if (nxgep->mac.portmode == PORT_10G_SERDES) {
63679599Stc99174@train 				/*
63689599Stc99174@train 				 * NEM was unplugged, set up xcvr table
63699599Stc99174@train 				 * to find another xcvr in the future.
63709599Stc99174@train 				 */
63719599Stc99174@train 				(void) nxge_xcvr_find(nxgep);
63729599Stc99174@train 			}
63733859Sml29623 		}
63743859Sml29623 	}
63753859Sml29623 
63765572Ssbehera start_link_check:
63773859Sml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
63783859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
63794693Stm144005 	    portn));
63803859Sml29623 	return (NXGE_OK);
63813859Sml29623 
63823859Sml29623 fail:
63834693Stm144005 	(void) nxge_check_link_stop(nxgep);
63844693Stm144005 
63853859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
63864693Stm144005 	    "nxge_check_10g_link: Failed to check link port<%d>",
63874693Stm144005 	    portn));
63883859Sml29623 	return (status);
63893859Sml29623 }
63903859Sml29623 
63913859Sml29623 
63923859Sml29623 /* Declare link down */
63933859Sml29623 
63943859Sml29623 void
nxge_link_is_down(p_nxge_t nxgep)63953859Sml29623 nxge_link_is_down(p_nxge_t nxgep)
63963859Sml29623 {
63974732Sdavemq 	p_nxge_stats_t statsp;
63984732Sdavemq 	char link_stat_msg[64];
63994732Sdavemq 
64003859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
64013859Sml29623 
64024732Sdavemq 	statsp = nxgep->statsp;
64034732Sdavemq 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down",
64044732Sdavemq 	    statsp->mac_stats.xcvr_portn);
64054732Sdavemq 
64064732Sdavemq 	if (nxge_no_msg == B_FALSE) {
64074732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
64084732Sdavemq 	}
64094732Sdavemq 
64103859Sml29623 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
64113859Sml29623 
64123859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
64133859Sml29623 }
64143859Sml29623 
64153859Sml29623 /* Declare link up */
64163859Sml29623 
64173859Sml29623 void
nxge_link_is_up(p_nxge_t nxgep)64183859Sml29623 nxge_link_is_up(p_nxge_t nxgep)
64193859Sml29623 {
64204732Sdavemq 	p_nxge_stats_t statsp;
64214732Sdavemq 	char link_stat_msg[64];
64223859Sml29623 	uint32_t val;
64233859Sml29623 
64243859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
64253859Sml29623 
64264732Sdavemq 	statsp = nxgep->statsp;
64274732Sdavemq 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ",
64284732Sdavemq 	    statsp->mac_stats.xcvr_portn,
64294732Sdavemq 	    statsp->mac_stats.link_speed);
64304732Sdavemq 
64314732Sdavemq 	if (statsp->mac_stats.link_T4)
64324732Sdavemq 		(void) strcat(link_stat_msg, "T4");
64334732Sdavemq 	else if (statsp->mac_stats.link_duplex == 2)
64344732Sdavemq 		(void) strcat(link_stat_msg, "full duplex");
64354732Sdavemq 	else
64364732Sdavemq 		(void) strcat(link_stat_msg, "half duplex");
64374732Sdavemq 
64383859Sml29623 
64393859Sml29623 	/* Clean up symbol errors incurred during link transition */
64404977Sraghus 	if ((nxgep->mac.portmode == PORT_10G_FIBER) ||
644112103SSantwona.Behera@Sun.COM 	    (nxgep->mac.portmode == PORT_10G_COPPER) ||
64424977Sraghus 	    (nxgep->mac.portmode == PORT_10G_SERDES)) {
64433859Sml29623 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
64446929Smisaki 		    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
64453859Sml29623 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
64466929Smisaki 		    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
64473859Sml29623 	}
64483859Sml29623 
64496835Syc148097 	/*
64506835Syc148097 	 * If the driver was plumbed without a link (therefore auto-negotiation
64516835Syc148097 	 * could not complete), the driver will detect a link up when a cable
64526835Syc148097 	 * conneting to a link partner is plugged into the port. By the time
64536835Syc148097 	 * link-up is detected, auto-negotiation should have completed (The
64546835Syc148097 	 * TN1010 tries to contact a link partner every 8~24ms). Here we re-
64556835Syc148097 	 * configure the Neptune/NIU according to the newly negotiated speed.
64566835Syc148097 	 * This is necessary only for the TN1010 basad device because only the
64576835Syc148097 	 * TN1010 supports dual speeds.
64586835Syc148097 	 */
64596835Syc148097 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
64606835Syc148097 	    nxgep->mac.portmode == PORT_10G_TN1010) {
64616835Syc148097 
64626835Syc148097 		(void) nxge_set_tn1010_param(nxgep);
64636835Syc148097 
64646835Syc148097 		/*
64656835Syc148097 		 * nxge_xcvr_find calls nxge_get_xcvr_type (which sets
64666835Syc148097 		 * nxgep->portmode) and nxge_setup_xcvr_table (which sets
64676835Syc148097 		 * the nxgep->xcvr to the proper nxge_xcvr_table_t struct).
64686835Syc148097 		 */
64696835Syc148097 		if (nxge_xcvr_find(nxgep) != NXGE_OK) {
64706835Syc148097 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
64716835Syc148097 			    "nxge_link_is_up: nxge_xcvr_find failed"));
64726835Syc148097 		}
64736835Syc148097 
64746835Syc148097 		/* nxge_link_init calls nxge_xcvr_init and nxge_serdes_init */
64756835Syc148097 		if (nxge_link_init(nxgep) != NXGE_OK) {
64766835Syc148097 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
64776835Syc148097 			    "nxge_link_is_up: nxge_link_init failed"));
64786835Syc148097 		}
64796835Syc148097 
64806835Syc148097 		/*
64816835Syc148097 		 * nxge_mac_init calls many subroutines including
64826835Syc148097 		 * nxge_xif_init which sets XGMII or GMII mode
64836835Syc148097 		 */
64846835Syc148097 		if (nxge_mac_init(nxgep) != NXGE_OK) {
64856835Syc148097 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
64866835Syc148097 			    "nxge_link_is_up: nxge_mac_init failed"));
64876835Syc148097 		}
64886835Syc148097 	} else {
64896835Syc148097 		(void) nxge_xif_init(nxgep);
64906835Syc148097 	}
64916835Syc148097 
64924732Sdavemq 	if (nxge_no_msg == B_FALSE) {
64934732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
64944732Sdavemq 	}
64954732Sdavemq 
64963859Sml29623 	mac_link_update(nxgep->mach, LINK_STATE_UP);
64973859Sml29623 
64983859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
64993859Sml29623 }
65003859Sml29623 
65016835Syc148097 #ifdef NXGE_DEBUG
65026835Syc148097 /* Dump all TN1010 Status registers */
65036835Syc148097 static void
nxge_dump_tn1010_status_regs(p_nxge_t nxgep)65046835Syc148097 nxge_dump_tn1010_status_regs(p_nxge_t nxgep)
65056835Syc148097 {
65066835Syc148097 	uint16_t val;
65076835Syc148097 
65086835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65096835Syc148097 	    TN1010_PMA_PMD_DEV_ADDR, 1, &val);
65106835Syc148097 	cmn_err(CE_NOTE, "PMA status1 = 0x%x", val);
65116835Syc148097 
65126835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65136835Syc148097 	    TN1010_PMA_PMD_DEV_ADDR, 8, &val);
65146835Syc148097 	cmn_err(CE_NOTE, "PMA status2 = 0x%x", val);
65156835Syc148097 
65166835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65176835Syc148097 	    TN1010_PMA_PMD_DEV_ADDR, 129, &val);
65186835Syc148097 	cmn_err(CE_NOTE, "10BASET-T status = 0x%x", val);
65196835Syc148097 
65206835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65216835Syc148097 	    TN1010_PCS_DEV_ADDR, 1, &val);
65226835Syc148097 	cmn_err(CE_NOTE, "PCS status1 = 0x%x", val);
65236835Syc148097 
65246835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65256835Syc148097 	    TN1010_PCS_DEV_ADDR, 8, &val);
65266835Syc148097 	cmn_err(CE_NOTE, "PCS status2 = 0x%x", val);
65276835Syc148097 
65286835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65296835Syc148097 	    TN1010_PCS_DEV_ADDR, 32, &val);
65306835Syc148097 	cmn_err(CE_NOTE, "10GBASE-R status1 = 0x%x", val);
65316835Syc148097 
65326835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65336835Syc148097 	    TN1010_PCS_DEV_ADDR, 33, &val);
65346835Syc148097 	cmn_err(CE_NOTE, "10GBASE-R Status2 = 0x%x", val);
65356835Syc148097 
65366835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65376835Syc148097 	    TN1010_PHYXS_DEV_ADDR, 1, &val);
65386835Syc148097 	cmn_err(CE_NOTE, "PHYXS status1 = 0x%x", val);
65396835Syc148097 
65406835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65416835Syc148097 	    TN1010_PHYXS_DEV_ADDR, 8, &val);
65426835Syc148097 	cmn_err(CE_NOTE, "PHYXS status2 = 0x%x", val);
65436835Syc148097 
65446835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65456835Syc148097 	    TN1010_PHYXS_DEV_ADDR, 24, &val);
65466835Syc148097 	cmn_err(CE_NOTE, "XGXS Lane status = 0x%x", val);
65476835Syc148097 
65486835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65496835Syc148097 	    TN1010_AUTONEG_DEV_ADDR, 1, &val);
65506835Syc148097 	cmn_err(CE_NOTE, "Autoneg status = 0x%x", val);
65516835Syc148097 
65526835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65536835Syc148097 	    TN1010_AUTONEG_DEV_ADDR, 33, &val);
65546835Syc148097 	cmn_err(CE_NOTE, "10Gbase-T An status = 0x%x", val);
65556835Syc148097 
65566835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65576835Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 1, &val);
65586835Syc148097 	cmn_err(CE_NOTE, "TN1010 status = 0x%x", val);
65596835Syc148097 
65606835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65616835Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 8, &val);
65626835Syc148097 	cmn_err(CE_NOTE, "Device status = 0x%x", val);
65636835Syc148097 
65646835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65656835Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 16, &val);
65666835Syc148097 	cmn_err(CE_NOTE, "DDR status = 0x%x", val);
65676835Syc148097 
65686835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65696835Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 17, &val);
65706835Syc148097 	cmn_err(CE_NOTE, "DDR fault status = 0x%x", val);
65716835Syc148097 
65726835Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65736835Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 11, &val);
65746835Syc148097 	cmn_err(CE_NOTE, "Firmware Revision = 0x%x  Major = 0x%x Minor = 0x%x",
65756835Syc148097 	    val,  (val & 0xFF00) >> 8, val & 0x00FF);
65766835Syc148097 }
65776835Syc148097 #endif
65786835Syc148097 
65793859Sml29623 /*
65803859Sml29623  * Calculate the bit in the multicast address filter
65813859Sml29623  * that selects the given * address.
65823859Sml29623  * Note: For GEM, the last 8-bits are used.
65833859Sml29623  */
65843859Sml29623 uint32_t
crc32_mchash(p_ether_addr_t addr)65853859Sml29623 crc32_mchash(p_ether_addr_t addr)
65863859Sml29623 {
65873859Sml29623 	uint8_t *cp;
65883859Sml29623 	uint32_t crc;
65893859Sml29623 	uint32_t c;
65903859Sml29623 	int byte;
65913859Sml29623 	int bit;
65923859Sml29623 
65933859Sml29623 	cp = (uint8_t *)addr;
65943859Sml29623 	crc = (uint32_t)0xffffffff;
65953859Sml29623 	for (byte = 0; byte < 6; byte++) {
65963859Sml29623 		c = (uint32_t)cp[byte];
65973859Sml29623 		for (bit = 0; bit < 8; bit++) {
65983859Sml29623 			if ((c & 0x1) ^ (crc & 0x1))
65993859Sml29623 				crc = (crc >> 1)^0xedb88320;
66003859Sml29623 			else
66013859Sml29623 				crc = (crc >> 1);
66023859Sml29623 			c >>= 1;
66033859Sml29623 		}
66043859Sml29623 	}
66053859Sml29623 	return ((~crc) >> (32 - HASH_BITS));
66063859Sml29623 }
66073859Sml29623 
66083859Sml29623 /* Reset serdes */
66093859Sml29623 
66103859Sml29623 nxge_status_t
nxge_serdes_reset(p_nxge_t nxgep)66113859Sml29623 nxge_serdes_reset(p_nxge_t nxgep)
66123859Sml29623 {
66133859Sml29623 	npi_handle_t		handle;
66143859Sml29623 
66153859Sml29623 	handle = nxgep->npi_handle;
66163859Sml29623 
66173859Sml29623 	ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1);
66183859Sml29623 	drv_usecwait(500);
66193859Sml29623 	ESR_REG_WR(handle, ESR_CONFIG_REG, 0);
66203859Sml29623 
66213859Sml29623 	return (NXGE_OK);
66223859Sml29623 }
66233859Sml29623 
66246835Syc148097 /*
66256835Syc148097  * This function monitors link status using interrupt or polling.
66266835Syc148097  * It calls nxgep->xcvr.check_link, a member function of
66276835Syc148097  * nxge_xcvr_table_t. But nxgep->xcvr.check_link calls this
66286835Syc148097  * function back, that is why the check_link routine is
66296835Syc148097  * executed periodically.
66306835Syc148097  */
66313859Sml29623 nxge_status_t
nxge_link_monitor(p_nxge_t nxgep,link_mon_enable_t enable)66323859Sml29623 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable)
66333859Sml29623 {
66343859Sml29623 	nxge_status_t status = NXGE_OK;
66353859Sml29623 
66366495Sspeer 	/* If we are a guest domain driver, don't bother. */
66376495Sspeer 	if (isLDOMguest(nxgep))
66386495Sspeer 		return (status);
66396495Sspeer 
66403859Sml29623 	/*
66414693Stm144005 	 * Return immediately if this is an imaginary XMAC port.
66424693Stm144005 	 * (At least, we don't have 4-port XMAC cards yet.)
66433859Sml29623 	 */
66444977Sraghus 	if ((nxgep->mac.portmode == PORT_10G_FIBER ||
664512103SSantwona.Behera@Sun.COM 	    nxgep->mac.portmode == PORT_10G_COPPER ||
66464977Sraghus 	    nxgep->mac.portmode == PORT_10G_SERDES) &&
66474977Sraghus 	    (nxgep->mac.portnum > 1))
66483859Sml29623 		return (NXGE_OK);
66493859Sml29623 
66503859Sml29623 	if (nxgep->statsp == NULL) {
66513859Sml29623 		/* stats has not been allocated. */
66523859Sml29623 		return (NXGE_OK);
66533859Sml29623 	}
66546075Ssbehera 	/* Don't check link if we're in internal loopback mode */
66556075Ssbehera 	if (nxgep->statsp->port_stats.lb_mode >= nxge_lb_serdes10g)
66563859Sml29623 		return (NXGE_OK);
66573859Sml29623 
66583859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
66594693Stm144005 	    "==> nxge_link_monitor port<%d> enable=%d",
66604693Stm144005 	    nxgep->mac.portnum, enable));
66613859Sml29623 	if (enable == LINK_MONITOR_START) {
66623859Sml29623 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
66633859Sml29623 			if ((status = nxge_link_intr(nxgep, LINK_INTR_START))
66644693Stm144005 			    != NXGE_OK)
66653859Sml29623 				goto fail;
66663859Sml29623 		} else {
66674693Stm144005 			timeout_id_t timerid;
66686835Syc148097 			/*
66696835Syc148097 			 * check_link_stop means "Stop the link check", so
66706835Syc148097 			 * we return without starting the timer.
66716835Syc148097 			 */
66724693Stm144005 			if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
66734693Stm144005 				return (NXGE_OK);
66744693Stm144005 
66756835Syc148097 			/*
66766835Syc148097 			 * Otherwise fire the timer for the nxge to check
66776835Syc148097 			 * the link using the check_link function
66786835Syc148097 			 * of the nxge_xcvr_table and pass "nxgep" as the
66796835Syc148097 			 * argument to the check_link function.
66806835Syc148097 			 */
66814732Sdavemq 			if (nxgep->xcvr.check_link) {
66824732Sdavemq 				timerid = timeout(
66834732Sdavemq 				    (fptrv_t)(nxgep->xcvr.check_link),
66844693Stm144005 				    nxgep,
66854693Stm144005 				    drv_usectohz(LINK_MONITOR_PERIOD));
66864732Sdavemq 				MUTEX_ENTER(&nxgep->poll_lock);
66874732Sdavemq 				nxgep->nxge_link_poll_timerid = timerid;
66884732Sdavemq 				MUTEX_EXIT(&nxgep->poll_lock);
668911409Stc99174@train 				nxgep->link_check_count ++;
66904732Sdavemq 			} else {
66914693Stm144005 				return (NXGE_ERROR);
66923859Sml29623 			}
66933859Sml29623 		}
66943859Sml29623 	} else {
66953859Sml29623 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
66963859Sml29623 			if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP))
66974693Stm144005 			    != NXGE_OK)
66983859Sml29623 				goto fail;
66993859Sml29623 		} else {
67004693Stm144005 			clock_t rv;
67014693Stm144005 
67024693Stm144005 			MUTEX_ENTER(&nxgep->poll_lock);
67034693Stm144005 
67044693Stm144005 			/* If <timerid> == 0, the link monitor has */
67054693Stm144005 			/* never been started, or just now stopped. */
67064693Stm144005 			if (nxgep->nxge_link_poll_timerid == 0) {
67074693Stm144005 				MUTEX_EXIT(&nxgep->poll_lock);
67084693Stm144005 				return (NXGE_OK);
67094693Stm144005 			}
67104693Stm144005 
67114693Stm144005 			nxgep->poll_state = LINK_MONITOR_STOPPING;
671211066Srafael.vanoni@sun.com 			rv = cv_reltimedwait(&nxgep->poll_cv, &nxgep->poll_lock,
67134693Stm144005 			    drv_usectohz(LM_WAIT_MULTIPLIER *
671411066Srafael.vanoni@sun.com 			    LINK_MONITOR_PERIOD), TR_CLOCK_TICK);
67154693Stm144005 			if (rv == -1) {
67164693Stm144005 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
67174693Stm144005 				    "==> stopping port %d: "
67184693Stm144005 				    "cv_timedwait(%d) timed out",
67194693Stm144005 				    nxgep->mac.portnum, nxgep->poll_state));
67204693Stm144005 				nxgep->poll_state = LINK_MONITOR_STOP;
67213859Sml29623 				nxgep->nxge_link_poll_timerid = 0;
67223859Sml29623 			}
67234693Stm144005 
67244693Stm144005 			MUTEX_EXIT(&nxgep->poll_lock);
67253859Sml29623 		}
67263859Sml29623 	}
67273859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
67284693Stm144005 	    "<== nxge_link_monitor port<%d> enable=%d",
67294693Stm144005 	    nxgep->mac.portnum, enable));
67306495Sspeer 
67313859Sml29623 	return (NXGE_OK);
67323859Sml29623 fail:
67333859Sml29623 	return (status);
67346835Syc148097 
67353859Sml29623 }
67363859Sml29623 
67376835Syc148097 nxge_status_t
nxge_check_tn1010_link(p_nxge_t nxgep)67386835Syc148097 nxge_check_tn1010_link(p_nxge_t nxgep)
67396835Syc148097 {
67406835Syc148097 	nxge_status_t	status = NXGE_OK;
67416835Syc148097 	nxge_link_state_t link_up;
67426835Syc148097 
67436835Syc148097 	if (nxgep->nxge_magic != NXGE_MAGIC) {
67446835Syc148097 		/* magic is 0 if driver is not attached */
67456835Syc148097 		return (NXGE_ERROR);
67466835Syc148097 	}
67476835Syc148097 
67486835Syc148097 	/* Link has been stopped, no need to continue */
67496835Syc148097 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) {
67506835Syc148097 		return (NXGE_OK);
67516835Syc148097 	}
67526835Syc148097 
67536835Syc148097 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
67546835Syc148097 		goto nxge_check_tn1010_link_exit;
67556835Syc148097 
67566835Syc148097 	if ((status = nxge_tn1010_check(nxgep, &link_up)) != NXGE_OK)
67576835Syc148097 		goto fail;
67586835Syc148097 
67596835Syc148097 nxge_check_tn1010_link_exit:
67606835Syc148097 	if (link_up == LINK_IS_UP)
67616835Syc148097 		nxge_link_is_up(nxgep);
67626835Syc148097 	else if (link_up == LINK_IS_DOWN)
67636835Syc148097 		nxge_link_is_down(nxgep);
67646835Syc148097 
67656835Syc148097 	/*
67666835Syc148097 	 * nxge_link_monitor will call (nxgep->xcvr.check_link)
67676835Syc148097 	 * which could be THIS function.
67686835Syc148097 	 */
67696835Syc148097 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
67706835Syc148097 
67716835Syc148097 	return (NXGE_OK);
67726835Syc148097 
67736835Syc148097 fail:
67746835Syc148097 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
67756835Syc148097 
67766835Syc148097 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
67776835Syc148097 	    "nxge_check_tn1010_link: Failed to check link"));
67786835Syc148097 	return (status);
67796835Syc148097 }
67806835Syc148097 
67816835Syc148097 
67826835Syc148097 /*
67836835Syc148097  * Fill variable "link_up" with either LINK_IS_UP or LINK_IS_DOWN.
67846835Syc148097  */
67856835Syc148097 static nxge_status_t
nxge_tn1010_check(p_nxge_t nxgep,nxge_link_state_t * link_up)67866835Syc148097 nxge_tn1010_check(p_nxge_t nxgep, nxge_link_state_t *link_up)
67876835Syc148097 {
67886835Syc148097 	nxge_status_t	status = NXGE_OK;
67896835Syc148097 	p_nxge_stats_t	statsp;
67906835Syc148097 	uint8_t		phy_port_addr, portn;
67916835Syc148097 	uint16_t	val;
67926835Syc148097 
67936835Syc148097 	*link_up = LINK_NO_CHANGE;
67946835Syc148097 
67956835Syc148097 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
67966835Syc148097 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
67976835Syc148097 	statsp = nxgep->statsp;
67986835Syc148097 
67996835Syc148097 	/* Check if link is up */
68006835Syc148097 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
68016835Syc148097 	    TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val))
68026835Syc148097 	    != NXGE_OK) {
68036835Syc148097 		goto fail;
68046835Syc148097 	}
68056835Syc148097 	/*
68066835Syc148097 	 * nxge_link_is_up has called nxge_set_tn1010_param and set
68076835Syc148097 	 * portmode and link_speed
68086835Syc148097 	 */
68096835Syc148097 	if (val & TN1010_AN_LINK_STAT_BIT) {
681011409Stc99174@train 		if ((nxgep->link_notify &&
681111409Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
68126835Syc148097 		    nxgep->statsp->mac_stats.link_up == 0) {
68136835Syc148097 			statsp->mac_stats.link_up = 1;
68146835Syc148097 			statsp->mac_stats.link_duplex = 2;
68156835Syc148097 			*link_up = LINK_IS_UP;
68166835Syc148097 			nxgep->link_notify = B_FALSE;
68176835Syc148097 		}
68186835Syc148097 	} else {
681911409Stc99174@train 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
682011409Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
68216835Syc148097 		    nxgep->statsp->mac_stats.link_up == 1) {
68226835Syc148097 			statsp->mac_stats.link_up = 0;
68236835Syc148097 			statsp->mac_stats.link_speed = 0;
68246835Syc148097 			statsp->mac_stats.link_duplex = 0;
68256835Syc148097 			*link_up = LINK_IS_DOWN;
68266835Syc148097 			nxgep->link_notify = B_FALSE;
68276835Syc148097 		}
68286835Syc148097 	}
68296835Syc148097 	return (NXGE_OK);
68306835Syc148097 
68316835Syc148097 fail:
68326835Syc148097 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
68336835Syc148097 	    "nxge_tn1010_check: Unable to check TN1010"));
68346835Syc148097 	return (status);
68356835Syc148097 }
68366835Syc148097 
68376835Syc148097 
68383859Sml29623 /* Set promiscous mode */
68393859Sml29623 
68403859Sml29623 nxge_status_t
nxge_set_promisc(p_nxge_t nxgep,boolean_t on)68413859Sml29623 nxge_set_promisc(p_nxge_t nxgep, boolean_t on)
68423859Sml29623 {
68433859Sml29623 	nxge_status_t status = NXGE_OK;
68443859Sml29623 
68454732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on));
68463859Sml29623 
68473859Sml29623 	nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
68483859Sml29623 
68493859Sml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
68503859Sml29623 
68513859Sml29623 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) {
68523859Sml29623 		goto fail;
68533859Sml29623 	}
68543859Sml29623 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) {
68553859Sml29623 		goto fail;
68563859Sml29623 	}
68573859Sml29623 
68583859Sml29623 	RW_EXIT(&nxgep->filter_lock);
68593859Sml29623 
68603859Sml29623 	if (on)
68613859Sml29623 		nxgep->statsp->mac_stats.promisc = B_TRUE;
68623859Sml29623 	else
68633859Sml29623 		nxgep->statsp->mac_stats.promisc = B_FALSE;
68643859Sml29623 
68653859Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc"));
68663859Sml29623 
68673859Sml29623 	return (NXGE_OK);
68683859Sml29623 fail:
68693859Sml29623 	RW_EXIT(&nxgep->filter_lock);
68703859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
68714732Sdavemq 	    "Unable to set promisc (%d)", on));
68723859Sml29623 
68733859Sml29623 	return (status);
68743859Sml29623 }
68753859Sml29623 
68763859Sml29623 /*ARGSUSED*/
68773859Sml29623 uint_t
nxge_mif_intr(void * arg1,void * arg2)68783859Sml29623 nxge_mif_intr(void *arg1, void *arg2)
68793859Sml29623 {
68803859Sml29623 #ifdef	NXGE_DEBUG
68813859Sml29623 	p_nxge_t		nxgep = (p_nxge_t)arg2;
68823859Sml29623 #endif
68833859Sml29623 #if NXGE_MIF
68843859Sml29623 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
68853859Sml29623 	uint32_t		status;
68863859Sml29623 	npi_handle_t		handle;
68873859Sml29623 	uint8_t			portn;
68883859Sml29623 	p_nxge_stats_t		statsp;
68893859Sml29623 #endif
68903859Sml29623 
68913859Sml29623 #ifdef	NXGE_MIF
68923859Sml29623 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
68933859Sml29623 		nxgep = ldvp->nxgep;
68943859Sml29623 	}
68953859Sml29623 	nxgep = ldvp->nxgep;
68963859Sml29623 #endif
68973859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr"));
68983859Sml29623 
68993859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
69003859Sml29623 	return (DDI_INTR_CLAIMED);
69013859Sml29623 
69023859Sml29623 mif_intr_fail:
69033859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
69043859Sml29623 	return (DDI_INTR_UNCLAIMED);
69053859Sml29623 }
69063859Sml29623 
69073859Sml29623 /*ARGSUSED*/
69083859Sml29623 uint_t
nxge_mac_intr(void * arg1,void * arg2)69093859Sml29623 nxge_mac_intr(void *arg1, void *arg2)
69103859Sml29623 {
69113859Sml29623 	p_nxge_t		nxgep = (p_nxge_t)arg2;
69123859Sml29623 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
69133859Sml29623 	p_nxge_ldg_t		ldgp;
69143859Sml29623 	uint32_t		status;
69153859Sml29623 	npi_handle_t		handle;
69163859Sml29623 	uint8_t			portn;
69173859Sml29623 	p_nxge_stats_t		statsp;
69183859Sml29623 	npi_status_t		rs = NPI_SUCCESS;
69193859Sml29623 
69203859Sml29623 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
69213859Sml29623 		nxgep = ldvp->nxgep;
69223859Sml29623 	}
69233859Sml29623 
69243859Sml29623 	ldgp = ldvp->ldgp;
69253859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
69264732Sdavemq 	    "group %d", ldgp->ldg));
69273859Sml29623 
69283859Sml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
69293859Sml29623 	/*
69303859Sml29623 	 * This interrupt handler is for a specific
69313859Sml29623 	 * mac port.
69323859Sml29623 	 */
69333859Sml29623 	statsp = (p_nxge_stats_t)nxgep->statsp;
69343859Sml29623 	portn = nxgep->mac.portnum;
69353859Sml29623 
69363859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
69374732Sdavemq 	    "==> nxge_mac_intr: reading mac stats: port<%d>", portn));
69383859Sml29623 
69393859Sml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
69403859Sml29623 		rs = npi_xmac_tx_get_istatus(handle, portn,
69416929Smisaki 		    (xmac_tx_iconfig_t *)&status);
69423859Sml29623 		if (rs != NPI_SUCCESS)
69433859Sml29623 			goto npi_fail;
69443859Sml29623 		if (status & ICFG_XMAC_TX_ALL) {
69453859Sml29623 			if (status & ICFG_XMAC_TX_UNDERRUN) {
69463859Sml29623 				statsp->xmac_stats.tx_underflow_err++;
69473859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
69486929Smisaki 				    NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
69493859Sml29623 			}
69503859Sml29623 			if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
69513859Sml29623 				statsp->xmac_stats.tx_maxpktsize_err++;
69525523Syc148097 				/*
69535523Syc148097 				 * Do not send FMA ereport because this
69545523Syc148097 				 * error does not indicate HW failure.
69555523Syc148097 				 */
69563859Sml29623 			}
69573859Sml29623 			if (status & ICFG_XMAC_TX_OVERFLOW) {
69583859Sml29623 				statsp->xmac_stats.tx_overflow_err++;
69593859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
69606929Smisaki 				    NXGE_FM_EREPORT_TXMAC_OVERFLOW);
69613859Sml29623 			}
69623859Sml29623 			if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
69633859Sml29623 				statsp->xmac_stats.tx_fifo_xfr_err++;
69643859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
69656929Smisaki 				    NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR);
69663859Sml29623 			}
69673859Sml29623 			if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
69683859Sml29623 				statsp->xmac_stats.tx_byte_cnt +=
69696929Smisaki 				    XTXMAC_BYTE_CNT_MASK;
69703859Sml29623 			}
69713859Sml29623 			if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
69723859Sml29623 				statsp->xmac_stats.tx_frame_cnt +=
69736929Smisaki 				    XTXMAC_FRM_CNT_MASK;
69743859Sml29623 			}
69753859Sml29623 		}
69763859Sml29623 
69773859Sml29623 		rs = npi_xmac_rx_get_istatus(handle, portn,
69786929Smisaki 		    (xmac_rx_iconfig_t *)&status);
69793859Sml29623 		if (rs != NPI_SUCCESS)
69803859Sml29623 			goto npi_fail;
69813859Sml29623 		if (status & ICFG_XMAC_RX_ALL) {
69823859Sml29623 			if (status & ICFG_XMAC_RX_OVERFLOW)
69833859Sml29623 				statsp->xmac_stats.rx_overflow_err++;
69843859Sml29623 			if (status & ICFG_XMAC_RX_UNDERFLOW) {
69853859Sml29623 				statsp->xmac_stats.rx_underflow_err++;
69863859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
69876929Smisaki 				    NXGE_FM_EREPORT_RXMAC_UNDERFLOW);
69883859Sml29623 			}
69895523Syc148097 			/*
69905523Syc148097 			 * Do not send FMA ereport for the following 3 errors
69915523Syc148097 			 * because they do not indicate HW failures.
69925523Syc148097 			 */
69933859Sml29623 			if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
69943859Sml29623 				statsp->xmac_stats.rx_crc_err_cnt +=
69956929Smisaki 				    XRXMAC_CRC_ER_CNT_MASK;
69963859Sml29623 			}
69973859Sml29623 			if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
69983859Sml29623 				statsp->xmac_stats.rx_len_err_cnt +=
69996929Smisaki 				    MAC_LEN_ER_CNT_MASK;
70003859Sml29623 			}
70013859Sml29623 			if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
70023859Sml29623 				statsp->xmac_stats.rx_viol_err_cnt +=
70036929Smisaki 				    XRXMAC_CD_VIO_CNT_MASK;
70043859Sml29623 			}
70053859Sml29623 			if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
70063859Sml29623 				statsp->xmac_stats.rx_byte_cnt +=
70076929Smisaki 				    XRXMAC_BT_CNT_MASK;
70083859Sml29623 			}
70093859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
70103859Sml29623 				statsp->xmac_stats.rx_hist1_cnt +=
70116929Smisaki 				    XRXMAC_HIST_CNT1_MASK;
70123859Sml29623 			}
70133859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
70143859Sml29623 				statsp->xmac_stats.rx_hist2_cnt +=
70156929Smisaki 				    XRXMAC_HIST_CNT2_MASK;
70163859Sml29623 			}
70173859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
70183859Sml29623 				statsp->xmac_stats.rx_hist3_cnt +=
70196929Smisaki 				    XRXMAC_HIST_CNT3_MASK;
70203859Sml29623 			}
70213859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
70223859Sml29623 				statsp->xmac_stats.rx_hist4_cnt +=
70236929Smisaki 				    XRXMAC_HIST_CNT4_MASK;
70243859Sml29623 			}
70253859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
70263859Sml29623 				statsp->xmac_stats.rx_hist5_cnt +=
70276929Smisaki 				    XRXMAC_HIST_CNT5_MASK;
70283859Sml29623 			}
70293859Sml29623 			if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
70303859Sml29623 				statsp->xmac_stats.rx_hist6_cnt +=
70316929Smisaki 				    XRXMAC_HIST_CNT6_MASK;
70323859Sml29623 			}
70333859Sml29623 			if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
70343859Sml29623 				statsp->xmac_stats.rx_broadcast_cnt +=
70356929Smisaki 				    XRXMAC_BC_FRM_CNT_MASK;
70363859Sml29623 			}
70373859Sml29623 			if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
70383859Sml29623 				statsp->xmac_stats.rx_mult_cnt +=
70396929Smisaki 				    XRXMAC_MC_FRM_CNT_MASK;
70403859Sml29623 			}
70415523Syc148097 			/*
70425523Syc148097 			 * Do not send FMA ereport for the following 3 errors
70435523Syc148097 			 * because they do not indicate HW failures.
70445523Syc148097 			 */
70453859Sml29623 			if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
70463859Sml29623 				statsp->xmac_stats.rx_frag_cnt +=
70476929Smisaki 				    XRXMAC_FRAG_CNT_MASK;
70483859Sml29623 			}
70493859Sml29623 			if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
70503859Sml29623 				statsp->xmac_stats.rx_frame_align_err_cnt +=
70516929Smisaki 				    XRXMAC_AL_ER_CNT_MASK;
70523859Sml29623 			}
70533859Sml29623 			if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
70543859Sml29623 				statsp->xmac_stats.rx_linkfault_err_cnt +=
70556929Smisaki 				    XMAC_LINK_FLT_CNT_MASK;
70563859Sml29623 			}
70573859Sml29623 			if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
70583859Sml29623 				statsp->xmac_stats.rx_remotefault_err++;
70593859Sml29623 			}
70603859Sml29623 			if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
70613859Sml29623 				statsp->xmac_stats.rx_localfault_err++;
70623859Sml29623 			}
70633859Sml29623 		}
70643859Sml29623 
70653859Sml29623 		rs = npi_xmac_ctl_get_istatus(handle, portn,
70666929Smisaki 		    (xmac_ctl_iconfig_t *)&status);
70673859Sml29623 		if (rs != NPI_SUCCESS)
70683859Sml29623 			goto npi_fail;
70693859Sml29623 		if (status & ICFG_XMAC_CTRL_ALL) {
70703859Sml29623 			if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
70713859Sml29623 				statsp->xmac_stats.rx_pause_cnt++;
70723859Sml29623 			if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
70733859Sml29623 				statsp->xmac_stats.tx_pause_state++;
70743859Sml29623 			if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE)
70753859Sml29623 				statsp->xmac_stats.tx_nopause_state++;
70763859Sml29623 		}
70773859Sml29623 	} else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
70783859Sml29623 		rs = npi_bmac_tx_get_istatus(handle, portn,
70796929Smisaki 		    (bmac_tx_iconfig_t *)&status);
70803859Sml29623 		if (rs != NPI_SUCCESS)
70813859Sml29623 			goto npi_fail;
70823859Sml29623 		if (status & ICFG_BMAC_TX_ALL) {
70833859Sml29623 			if (status & ICFG_BMAC_TX_UNDERFLOW) {
70843859Sml29623 				statsp->bmac_stats.tx_underrun_err++;
70853859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
70866929Smisaki 				    NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
70873859Sml29623 			}
70883859Sml29623 			if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
70893859Sml29623 				statsp->bmac_stats.tx_max_pkt_err++;
70903859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
70916929Smisaki 				    NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
70923859Sml29623 			}
70933859Sml29623 			if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
70943859Sml29623 				statsp->bmac_stats.tx_byte_cnt +=
70956929Smisaki 				    BTXMAC_BYTE_CNT_MASK;
70963859Sml29623 			}
70973859Sml29623 			if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
70983859Sml29623 				statsp->bmac_stats.tx_frame_cnt +=
70996929Smisaki 				    BTXMAC_FRM_CNT_MASK;
71003859Sml29623 			}
71013859Sml29623 		}
71023859Sml29623 
71033859Sml29623 		rs = npi_bmac_rx_get_istatus(handle, portn,
71046929Smisaki 		    (bmac_rx_iconfig_t *)&status);
71053859Sml29623 		if (rs != NPI_SUCCESS)
71063859Sml29623 			goto npi_fail;
71073859Sml29623 		if (status & ICFG_BMAC_RX_ALL) {
71083859Sml29623 			if (status & ICFG_BMAC_RX_OVERFLOW) {
71093859Sml29623 				statsp->bmac_stats.rx_overflow_err++;
71103859Sml29623 			}
71113859Sml29623 			if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
71123859Sml29623 				statsp->bmac_stats.rx_frame_cnt +=
71136929Smisaki 				    RXMAC_FRM_CNT_MASK;
71143859Sml29623 			}
71153859Sml29623 			if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
71163859Sml29623 				statsp->bmac_stats.rx_crc_err_cnt +=
71176929Smisaki 				    BMAC_CRC_ER_CNT_MASK;
71183859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
71196929Smisaki 				    NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
71203859Sml29623 			}
71213859Sml29623 			if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
71223859Sml29623 				statsp->bmac_stats.rx_len_err_cnt +=
71236929Smisaki 				    MAC_LEN_ER_CNT_MASK;
71243859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
71256929Smisaki 				    NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
71263859Sml29623 			}
71273859Sml29623 			if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP)
71283859Sml29623 				statsp->bmac_stats.rx_viol_err_cnt +=
71296929Smisaki 				    BMAC_CD_VIO_CNT_MASK;
71303859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
71316929Smisaki 				    NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
71323859Sml29623 			}
71333859Sml29623 			if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
71343859Sml29623 				statsp->bmac_stats.rx_byte_cnt +=
71356929Smisaki 				    BRXMAC_BYTE_CNT_MASK;
71363859Sml29623 			}
71373859Sml29623 			if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
71383859Sml29623 				statsp->bmac_stats.rx_align_err_cnt +=
71396929Smisaki 				    BMAC_AL_ER_CNT_MASK;
71403859Sml29623 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
71416929Smisaki 				    NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
71423859Sml29623 			}
71433859Sml29623 
71443859Sml29623 			rs = npi_bmac_ctl_get_istatus(handle, portn,
71456929Smisaki 			    (bmac_ctl_iconfig_t *)&status);
71463859Sml29623 			if (rs != NPI_SUCCESS)
71473859Sml29623 				goto npi_fail;
71483859Sml29623 
71493859Sml29623 			if (status & ICFG_BMAC_CTL_ALL) {
71503859Sml29623 				if (status & ICFG_BMAC_CTL_RCVPAUSE)
71513859Sml29623 					statsp->bmac_stats.rx_pause_cnt++;
71523859Sml29623 				if (status & ICFG_BMAC_CTL_INPAUSE_ST)
71533859Sml29623 					statsp->bmac_stats.tx_pause_state++;
71543859Sml29623 				if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST)
71553859Sml29623 					statsp->bmac_stats.tx_nopause_state++;
71563859Sml29623 			}
71573859Sml29623 		}
71583859Sml29623 
71593859Sml29623 	if (ldgp->nldvs == 1) {
71603859Sml29623 		(void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
71616929Smisaki 		    B_TRUE, ldgp->ldg_timer);
71623859Sml29623 	}
71633859Sml29623 
71643859Sml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
71653859Sml29623 	return (DDI_INTR_CLAIMED);
71663859Sml29623 
71673859Sml29623 npi_fail:
71683859Sml29623 	NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
71693859Sml29623 	return (DDI_INTR_UNCLAIMED);
71703859Sml29623 }
71713859Sml29623 
71723859Sml29623 nxge_status_t
nxge_check_bcm8704_link(p_nxge_t nxgep,boolean_t * link_up)71733859Sml29623 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up)
71743859Sml29623 {
71753859Sml29623 	uint8_t		phy_port_addr;
71763859Sml29623 	nxge_status_t	status = NXGE_OK;
71773859Sml29623 	boolean_t	rx_sig_ok;
71783859Sml29623 	boolean_t	pcs_blk_lock;
71793859Sml29623 	boolean_t	link_align;
71803859Sml29623 	uint16_t	val1, val2, val3;
71813859Sml29623 #ifdef	NXGE_DEBUG_SYMBOL_ERR
71823859Sml29623 	uint16_t	val_debug;
718311304SJanie.Lu@Sun.COM 	uint32_t	val;
71843859Sml29623 #endif
71853859Sml29623 
71863859Sml29623 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
71873859Sml29623 
71883859Sml29623 #ifdef	NXGE_DEBUG_SYMBOL_ERR
71893859Sml29623 	/* Check Device 3 Register Device 3 0xC809 */
71903859Sml29623 	(void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug);
71913859Sml29623 	if ((val_debug & ~0x200) != 0) {
71923859Sml29623 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n",
71936929Smisaki 		    nxgep->mac.portnum, val_debug);
71943859Sml29623 		(void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18,
71956929Smisaki 		    &val_debug);
71963859Sml29623 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n",
71976929Smisaki 		    nxgep->mac.portnum, val_debug);
71983859Sml29623 	}
71993859Sml29623 
72003859Sml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
72016929Smisaki 	    XPCS_REG_DESCWERR_COUNTER, &val);
72023859Sml29623 	if (val != 0)
72033859Sml29623 		cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val);
72043859Sml29623 
72053859Sml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
72066929Smisaki 	    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
72073859Sml29623 	if (val != 0)
72083859Sml29623 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val);
72093859Sml29623 
72103859Sml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
72116929Smisaki 	    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
72123859Sml29623 	if (val != 0)
72133859Sml29623 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val);
72143859Sml29623 #endif
72153859Sml29623 
72163859Sml29623 	/* Check from BCM8704 if 10G link is up or down */
72173859Sml29623 
72183859Sml29623 	/* Check Device 1 Register 0xA bit0 */
72196929Smisaki 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PMA_PMD_DEV_ADDR,
72206929Smisaki 	    BCM8704_PMD_RECEIVE_SIG_DETECT, &val1);
72213859Sml29623 	if (status != NXGE_OK)
72223859Sml29623 		goto fail;
72233859Sml29623 	rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE);
72243859Sml29623 
72253859Sml29623 	/* Check Device 3 Register 0x20 bit0 */
72266929Smisaki 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PCS_DEV_ADDR,
72276929Smisaki 	    BCM8704_10GBASE_R_PCS_STATUS_REG, &val2)) != NPI_SUCCESS)
72283859Sml29623 		goto fail;
72293859Sml29623 	pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE);
72303859Sml29623 
72313859Sml29623 	/* Check Device 4 Register 0x18 bit12 */
72326929Smisaki 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
72336929Smisaki 	    BCM8704_PHYXS_XGXS_LANE_STATUS_REG, &val3);
72343859Sml29623 	if (status != NXGE_OK)
72353859Sml29623 		goto fail;
72365572Ssbehera 
72375572Ssbehera 	switch (nxgep->chip_id) {
72385572Ssbehera 	case BCM8704_CHIP_ID:
72395572Ssbehera 		link_align = (val3 == (XGXS_LANE_ALIGN_STATUS |
72405572Ssbehera 		    XGXS_LANE3_SYNC | XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
72415572Ssbehera 		    XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE;
72425572Ssbehera 		break;
72435572Ssbehera 	case BCM8706_CHIP_ID:
72445572Ssbehera 		link_align = ((val3 & XGXS_LANE_ALIGN_STATUS) &&
72455572Ssbehera 		    (val3 & XGXS_LANE3_SYNC) && (val3 & XGXS_LANE2_SYNC) &&
72465572Ssbehera 		    (val3 & XGXS_LANE1_SYNC) && (val3 & XGXS_LANE0_SYNC)) ?
72475572Ssbehera 		    B_TRUE : B_FALSE;
72485572Ssbehera 		break;
72495572Ssbehera 	default:
72505572Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_check_bcm8704_link:"
72515572Ssbehera 		    "Unknown chip ID [0x%x]", nxgep->chip_id));
72525572Ssbehera 		goto fail;
72535572Ssbehera 	}
72545572Ssbehera 
72553859Sml29623 #ifdef	NXGE_DEBUG_ALIGN_ERR
72563859Sml29623 	/* Temp workaround for link down issue */
72573859Sml29623 	if (pcs_blk_lock == B_FALSE) {
72583859Sml29623 		if (val2 != 0x4) {
72593859Sml29623 			pcs_blk_lock = B_TRUE;
72606929Smisaki 			cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev3 "
72616929Smisaki 			    "Reg 0x20 = 0x%x\n", nxgep->mac.portnum, val2);
72623859Sml29623 		}
72633859Sml29623 	}
72643859Sml29623 
72653859Sml29623 	if (link_align == B_FALSE) {
72663859Sml29623 		if (val3 != 0x140f) {
72673859Sml29623 			link_align = B_TRUE;
72686929Smisaki 			cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev4 "
72696929Smisaki 			    "Reg 0x18 = 0x%x\n", nxgep->mac.portnum, val3);
72703859Sml29623 		}
72713859Sml29623 	}
72723859Sml29623 
72733859Sml29623 	if (rx_sig_ok == B_FALSE) {
72743859Sml29623 		if ((val2 == 0) || (val3 == 0)) {
72753859Sml29623 			rx_sig_ok = B_TRUE;
72763859Sml29623 			cmn_err(CE_NOTE,
72776929Smisaki 			    "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
72786929Smisaki 			    nxgep->mac.portnum);
72793859Sml29623 		}
72803859Sml29623 	}
72813859Sml29623 #endif
72823859Sml29623 
72833859Sml29623 	*link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) &&
72846929Smisaki 	    (link_align == B_TRUE)) ? B_TRUE : B_FALSE;
72853859Sml29623 
72863859Sml29623 	return (NXGE_OK);
72873859Sml29623 fail:
72883859Sml29623 	return (status);
72893859Sml29623 }
72903859Sml29623 
72916604Ssbehera static nxge_status_t
nxge_check_mrvl88x2011_link(p_nxge_t nxgep,boolean_t * link_up)72926835Syc148097 nxge_check_mrvl88x2011_link(p_nxge_t nxgep, boolean_t *link_up)
72936604Ssbehera {
72946604Ssbehera 	uint8_t		phy;
72956604Ssbehera 	nxge_status_t   status = NXGE_OK;
72966604Ssbehera 	boolean_t	pma_status;
72976604Ssbehera 	boolean_t	pcs_status;
72986604Ssbehera 	boolean_t	xgxs_status;
72996604Ssbehera 	uint16_t	val;
73006604Ssbehera 
73016604Ssbehera 	phy = nxgep->statsp->mac_stats.xcvr_portn;
73026604Ssbehera 
73036604Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
73046604Ssbehera 	    MRVL_88X2011_10G_PMD_STAT_2, &val);
73056604Ssbehera 
73066604Ssbehera 	*link_up = B_FALSE;
73076604Ssbehera 
73086604Ssbehera 	/* Check from Marvell 88X2011 if 10G link is up or down */
73096604Ssbehera 
73106604Ssbehera 	/* Check PMA/PMD Register: 1.0001.2 == 1 */
73116604Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
73126604Ssbehera 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
73136604Ssbehera 
73146604Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
73156604Ssbehera 	    "nxge_check_mrvl88x2011_link: pmd=0x%x", val));
73166604Ssbehera 
73176604Ssbehera 	pma_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE);
73186604Ssbehera 
73196604Ssbehera 	/* Check PMC Register : 3.0001.2 == 1: read twice */
73206604Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
73216604Ssbehera 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
73226604Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
73236604Ssbehera 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
73246604Ssbehera 
73256604Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
73266604Ssbehera 	    "nxge_check_mrvl88x2011_link: pcs=0x%x", val));
73276604Ssbehera 
73286604Ssbehera 	pcs_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE);
73296604Ssbehera 
73306604Ssbehera 	/* Check XGXS Register : 4.0018.[0-3,12] */
73316604Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV4_ADDR,
73326604Ssbehera 	    MRVL_88X2011_10G_XGXS_LANE_STAT, &val);
73336604Ssbehera 
73346604Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
73356604Ssbehera 	    "nxge_check_mrvl88x2011_link: xgxs=0x%x", val));
73366604Ssbehera 
73376604Ssbehera 	xgxs_status = (val == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC |
73386604Ssbehera 	    XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
73396604Ssbehera 	    XGXS_LANE0_SYNC | XGXS_PATTERN_TEST_ABILITY |
73406604Ssbehera 	    XGXS_LANE_STAT_MAGIC)) ? B_TRUE : B_FALSE;
73416604Ssbehera 
73426604Ssbehera 	*link_up = (pma_status && pcs_status && xgxs_status) ?
73436604Ssbehera 	    B_TRUE : B_FALSE;
73446604Ssbehera 
73456604Ssbehera fail:
73466604Ssbehera 
73476604Ssbehera 	if (*link_up == B_FALSE) {
73486604Ssbehera 		/* PCS OFF */
73496604Ssbehera 		nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_OFF);
73506604Ssbehera 	} else {
73516604Ssbehera 		/* PCS Activity */
73526604Ssbehera 		nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_PCS_ACT);
73536604Ssbehera 	}
73546604Ssbehera 
73556604Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
73566604Ssbehera 	    " <== nxge_check_mrvl88x2011_link: up=%d", *link_up));
73576604Ssbehera 
73586604Ssbehera 	return (status);
73596604Ssbehera }
73606604Ssbehera 
736112103SSantwona.Behera@Sun.COM static nxge_status_t
nxge_check_nlp2020_link(p_nxge_t nxgep,boolean_t * link_up)736212103SSantwona.Behera@Sun.COM nxge_check_nlp2020_link(p_nxge_t nxgep, boolean_t *link_up)
736312103SSantwona.Behera@Sun.COM {
736412103SSantwona.Behera@Sun.COM 	uint8_t		phy;
736512103SSantwona.Behera@Sun.COM 	nxge_status_t   status = NXGE_OK;
736612103SSantwona.Behera@Sun.COM 	uint16_t	pmd_rx_sig, pcs_10gbr_stat1, phy_xs_ln_stat;
736712103SSantwona.Behera@Sun.COM 	uint8_t		connector = 0;
736812103SSantwona.Behera@Sun.COM 
736912103SSantwona.Behera@Sun.COM 	phy = nxgep->statsp->mac_stats.xcvr_portn;
737012103SSantwona.Behera@Sun.COM 	*link_up = B_FALSE;
737112103SSantwona.Behera@Sun.COM 
737212103SSantwona.Behera@Sun.COM 	/* Check from Netlogic AEL2020 if 10G link is up or down */
737312103SSantwona.Behera@Sun.COM 
737412103SSantwona.Behera@Sun.COM 	status = nxge_mdio_read(nxgep, phy, NLP2020_PMA_PMD_ADDR,
737512103SSantwona.Behera@Sun.COM 	    NLP2020_PMA_PMD_RX_SIG_DET_REG, &pmd_rx_sig);
737612103SSantwona.Behera@Sun.COM 	if (status != NXGE_OK)
737712103SSantwona.Behera@Sun.COM 		goto fail;
737812103SSantwona.Behera@Sun.COM 
737912103SSantwona.Behera@Sun.COM 	status = nxge_mdio_read(nxgep, phy, NLP2020_PHY_PCS_ADDR,
738012103SSantwona.Behera@Sun.COM 	    NLP2020_PHY_PCS_10GBR_STAT1_REG, &pcs_10gbr_stat1);
738112103SSantwona.Behera@Sun.COM 	if (status != NXGE_OK)
738212103SSantwona.Behera@Sun.COM 		goto fail;
738312103SSantwona.Behera@Sun.COM 
738412103SSantwona.Behera@Sun.COM 	status = nxge_mdio_read(nxgep, phy, NLP2020_PHY_XS_ADDR,
738512103SSantwona.Behera@Sun.COM 	    NLP2020_PHY_XS_LN_ST_REG, &phy_xs_ln_stat);
738612103SSantwona.Behera@Sun.COM 	if (status != NXGE_OK)
738712103SSantwona.Behera@Sun.COM 		goto fail;
738812103SSantwona.Behera@Sun.COM 
738912103SSantwona.Behera@Sun.COM 	if ((pmd_rx_sig & NLP2020_PMA_PMD_RX_SIG_ON) &&
739012103SSantwona.Behera@Sun.COM 	    (pcs_10gbr_stat1 & NLP2020_PHY_PCS_10GBR_RX_LINK_UP) &&
739112103SSantwona.Behera@Sun.COM 	    (phy_xs_ln_stat & NLP2020_PHY_XS_LN_ALIGN_SYNC))
739212103SSantwona.Behera@Sun.COM 		*link_up = B_TRUE;
739312103SSantwona.Behera@Sun.COM 	/*
739412103SSantwona.Behera@Sun.COM 	 * If previously link was down, check the connector type as
739512103SSantwona.Behera@Sun.COM 	 * it might have been changed.
739612103SSantwona.Behera@Sun.COM 	 */
739712103SSantwona.Behera@Sun.COM 	if (nxgep->statsp->mac_stats.link_up == 0) {
739812103SSantwona.Behera@Sun.COM 		(void) nxge_nlp2020_i2c_read(nxgep, phy,
739912103SSantwona.Behera@Sun.COM 		    NLP2020_XCVR_I2C_ADDR, QSFP_MSA_CONN_REG, &connector);
740012103SSantwona.Behera@Sun.COM 
740112103SSantwona.Behera@Sun.COM 		switch (connector) {
740212103SSantwona.Behera@Sun.COM 		case SFPP_FIBER:
740312103SSantwona.Behera@Sun.COM 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
740412103SSantwona.Behera@Sun.COM 			    "nxge_check_nlp2020_link: SFPP_FIBER"));
740512103SSantwona.Behera@Sun.COM 			if (nxgep->mac.portmode != PORT_10G_FIBER) {
740612103SSantwona.Behera@Sun.COM 				nxgep->mac.portmode = PORT_10G_FIBER;
740712103SSantwona.Behera@Sun.COM 				(void) nxge_nlp2020_xcvr_init(nxgep);
740812103SSantwona.Behera@Sun.COM 			}
740912103SSantwona.Behera@Sun.COM 			break;
741012103SSantwona.Behera@Sun.COM 		case QSFP_FIBER:
741112103SSantwona.Behera@Sun.COM 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
741212103SSantwona.Behera@Sun.COM 			    "nxge_check_nlp2020_link: QSFP_FIBER"));
741312103SSantwona.Behera@Sun.COM 			if (nxgep->mac.portmode != PORT_10G_FIBER) {
741412103SSantwona.Behera@Sun.COM 				nxgep->mac.portmode = PORT_10G_FIBER;
741512103SSantwona.Behera@Sun.COM 				(void) nxge_nlp2020_xcvr_init(nxgep);
741612103SSantwona.Behera@Sun.COM 			}
741712103SSantwona.Behera@Sun.COM 			break;
741812103SSantwona.Behera@Sun.COM 		case QSFP_COPPER_TWINAX:
741912103SSantwona.Behera@Sun.COM 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
742012103SSantwona.Behera@Sun.COM 			    "nxge_check_nlp2020_link: "
742112103SSantwona.Behera@Sun.COM 			    "QSFP_COPPER_TWINAX/"
742212103SSantwona.Behera@Sun.COM 			    "SFPP_COPPER_TWINAX"));
742312103SSantwona.Behera@Sun.COM 			if (nxgep->mac.portmode != PORT_10G_COPPER) {
742412103SSantwona.Behera@Sun.COM 				nxgep->mac.portmode = PORT_10G_COPPER;
742512103SSantwona.Behera@Sun.COM 				(void) nxge_nlp2020_xcvr_init(nxgep);
742612103SSantwona.Behera@Sun.COM 			} else {
742712103SSantwona.Behera@Sun.COM 				uint8_t len = 0;
742812103SSantwona.Behera@Sun.COM 				(void) nxge_nlp2020_i2c_read(nxgep, phy,
742912103SSantwona.Behera@Sun.COM 				    NLP2020_XCVR_I2C_ADDR, QSFP_MSA_LEN_REG,
743012103SSantwona.Behera@Sun.COM 				    &len);
743112103SSantwona.Behera@Sun.COM 				if (((len < 7) &&
743212103SSantwona.Behera@Sun.COM 				    (nxgep->nlp_conn ==
743312103SSantwona.Behera@Sun.COM 				    NXGE_NLP_CONN_COPPER_7M_ABOVE)) ||
743412103SSantwona.Behera@Sun.COM 				    ((len >= 7) &&
743512103SSantwona.Behera@Sun.COM 				    (nxgep->nlp_conn ==
743612103SSantwona.Behera@Sun.COM 				    NXGE_NLP_CONN_COPPER_LT_7M))) {
743712103SSantwona.Behera@Sun.COM 					(void) nxge_nlp2020_xcvr_init(nxgep);
743812103SSantwona.Behera@Sun.COM 				}
743912103SSantwona.Behera@Sun.COM 			}
744012103SSantwona.Behera@Sun.COM 			break;
744112103SSantwona.Behera@Sun.COM 		default:
744212103SSantwona.Behera@Sun.COM 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
744312103SSantwona.Behera@Sun.COM 			    "nxge_check_nlp2020_link: Unknown type [0x%x] "
744412103SSantwona.Behera@Sun.COM 			    "detected...setting to QSFP_FIBER",
744512103SSantwona.Behera@Sun.COM 			    connector));
744612103SSantwona.Behera@Sun.COM 			if (nxgep->mac.portmode != PORT_10G_FIBER) {
744712103SSantwona.Behera@Sun.COM 				nxgep->mac.portmode = PORT_10G_FIBER;
744812103SSantwona.Behera@Sun.COM 				(void) nxge_nlp2020_xcvr_init(nxgep);
744912103SSantwona.Behera@Sun.COM 			}
745012103SSantwona.Behera@Sun.COM 			break;
745112103SSantwona.Behera@Sun.COM 		}
745212103SSantwona.Behera@Sun.COM 	}
745312103SSantwona.Behera@Sun.COM fail:
745412103SSantwona.Behera@Sun.COM 	if (*link_up == B_FALSE && nxgep->statsp->mac_stats.link_up == 1) {
745512103SSantwona.Behera@Sun.COM 		/* Turn link LED OFF */
745612103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_write(nxgep, phy,
745712103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 0xb000);
745812103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_write(nxgep, phy,
745912103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_PT3_CFG_REG, 0x0);
746012103SSantwona.Behera@Sun.COM 	} else if (*link_up == B_TRUE &&
746112103SSantwona.Behera@Sun.COM 	    nxgep->statsp->mac_stats.link_up == 0) {
746212103SSantwona.Behera@Sun.COM 		/* Turn link LED ON */
746312103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_write(nxgep, phy,
746412103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 0xd000);
746512103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_write(nxgep, phy,
746612103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_PT3_CFG_REG, 0xfbff);
746712103SSantwona.Behera@Sun.COM 		(void) nxge_mdio_write(nxgep, phy,
746812103SSantwona.Behera@Sun.COM 		    NLP2020_GPIO_ADDR, 0xff2a, 0x004a);
746912103SSantwona.Behera@Sun.COM 	}
747012103SSantwona.Behera@Sun.COM 
747112103SSantwona.Behera@Sun.COM 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
747212103SSantwona.Behera@Sun.COM 	    " <== nxge_check_nlp2020_link: up=%d", *link_up));
747312103SSantwona.Behera@Sun.COM 	return (status);
747412103SSantwona.Behera@Sun.COM }
747512103SSantwona.Behera@Sun.COM 
747612103SSantwona.Behera@Sun.COM 
74773859Sml29623 nxge_status_t
nxge_10g_link_led_on(p_nxge_t nxgep)74783859Sml29623 nxge_10g_link_led_on(p_nxge_t nxgep)
74793859Sml29623 {
74803859Sml29623 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
74814732Sdavemq 	    != NPI_SUCCESS)
74823859Sml29623 		return (NXGE_ERROR);
74833859Sml29623 	else
74843859Sml29623 		return (NXGE_OK);
74853859Sml29623 }
74863859Sml29623 
74873859Sml29623 nxge_status_t
nxge_10g_link_led_off(p_nxge_t nxgep)74883859Sml29623 nxge_10g_link_led_off(p_nxge_t nxgep)
74893859Sml29623 {
74903859Sml29623 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
74914732Sdavemq 	    != NPI_SUCCESS)
74923859Sml29623 		return (NXGE_ERROR);
74933859Sml29623 	else
74943859Sml29623 		return (NXGE_OK);
74953859Sml29623 }
74964185Sspeer 
74975572Ssbehera static boolean_t
nxge_hswap_phy_present(p_nxge_t nxgep,uint8_t portn)749812103SSantwona.Behera@Sun.COM nxge_hswap_phy_present(p_nxge_t nxgep, uint8_t portn)
749912103SSantwona.Behera@Sun.COM {
750012103SSantwona.Behera@Sun.COM 	/*
750112103SSantwona.Behera@Sun.COM 	 * check for BCM PHY (GOA NEM)
750212103SSantwona.Behera@Sun.COM 	 */
750312103SSantwona.Behera@Sun.COM 	/*
750412103SSantwona.Behera@Sun.COM 	 * If this is the 2nd NIU port, then check 2 addresses
750512103SSantwona.Behera@Sun.COM 	 * to take care of the Goa NEM card. Port 1 can have addr 17
750612103SSantwona.Behera@Sun.COM 	 * (in the eval board) or 20 (in the P0 board).
750712103SSantwona.Behera@Sun.COM 	 */
750812103SSantwona.Behera@Sun.COM 	if (portn == 1) {
750912103SSantwona.Behera@Sun.COM 		if (nxge_is_phy_present(nxgep, ALT_GOA_CLAUSE45_PORT1_ADDR,
751012103SSantwona.Behera@Sun.COM 		    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
751112103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = ALT_GOA_CLAUSE45_PORT1_ADDR;
751212103SSantwona.Behera@Sun.COM 			goto found_phy;
751312103SSantwona.Behera@Sun.COM 		}
751412103SSantwona.Behera@Sun.COM 	}
751512103SSantwona.Behera@Sun.COM 	if (nxge_is_phy_present(nxgep, GOA_CLAUSE45_PORT_ADDR_BASE + portn,
751612103SSantwona.Behera@Sun.COM 	    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
751712103SSantwona.Behera@Sun.COM 		nxgep->xcvr_addr = GOA_CLAUSE45_PORT_ADDR_BASE + portn;
751812103SSantwona.Behera@Sun.COM 			goto found_phy;
751912103SSantwona.Behera@Sun.COM 	}
752012103SSantwona.Behera@Sun.COM 
752112103SSantwona.Behera@Sun.COM 	/*
752212103SSantwona.Behera@Sun.COM 	 * check for NLP2020 PHY on C4 NEM
752312103SSantwona.Behera@Sun.COM 	 */
752412103SSantwona.Behera@Sun.COM 	switch (portn) {
752512103SSantwona.Behera@Sun.COM 	case 0:
752612103SSantwona.Behera@Sun.COM 		if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR0,
752712103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
752812103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR0;
752912103SSantwona.Behera@Sun.COM 			goto found_phy;
753012103SSantwona.Behera@Sun.COM 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR1,
753112103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
753212103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR1;
753312103SSantwona.Behera@Sun.COM 			goto found_phy;
753412103SSantwona.Behera@Sun.COM 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR2,
753512103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
753612103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR2;
753712103SSantwona.Behera@Sun.COM 			goto found_phy;
753812103SSantwona.Behera@Sun.COM 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR3,
753912103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
754012103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR3;
754112103SSantwona.Behera@Sun.COM 			goto found_phy;
754212103SSantwona.Behera@Sun.COM 		}
754312103SSantwona.Behera@Sun.COM 		break;
754412103SSantwona.Behera@Sun.COM 
754512103SSantwona.Behera@Sun.COM 	case 1:
754612103SSantwona.Behera@Sun.COM 		if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR0,
754712103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
754812103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR0;
754912103SSantwona.Behera@Sun.COM 			goto found_phy;
755012103SSantwona.Behera@Sun.COM 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR1,
755112103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
755212103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR1;
755312103SSantwona.Behera@Sun.COM 			goto found_phy;
755412103SSantwona.Behera@Sun.COM 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR2,
755512103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
755612103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR2;
755712103SSantwona.Behera@Sun.COM 			goto found_phy;
755812103SSantwona.Behera@Sun.COM 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR3,
755912103SSantwona.Behera@Sun.COM 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
756012103SSantwona.Behera@Sun.COM 			nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR3;
756112103SSantwona.Behera@Sun.COM 			goto found_phy;
756212103SSantwona.Behera@Sun.COM 		}
756312103SSantwona.Behera@Sun.COM 		break;
756412103SSantwona.Behera@Sun.COM 	default:
756512103SSantwona.Behera@Sun.COM 		break;
756612103SSantwona.Behera@Sun.COM 	}
756712103SSantwona.Behera@Sun.COM 
756812103SSantwona.Behera@Sun.COM 	return (B_FALSE);
756912103SSantwona.Behera@Sun.COM found_phy:
757012103SSantwona.Behera@Sun.COM 	return (B_TRUE);
757112103SSantwona.Behera@Sun.COM 
757212103SSantwona.Behera@Sun.COM }
757312103SSantwona.Behera@Sun.COM 
757412103SSantwona.Behera@Sun.COM static boolean_t
nxge_is_phy_present(p_nxge_t nxgep,int addr,uint32_t id,uint32_t mask)75755572Ssbehera nxge_is_phy_present(p_nxge_t nxgep, int addr, uint32_t id, uint32_t mask)
75765572Ssbehera {
75775572Ssbehera 	uint32_t pma_pmd_id = 0;
75785572Ssbehera 	uint32_t pcs_id = 0;
75795572Ssbehera 	uint32_t phy_id = 0;
75805572Ssbehera 
75815572Ssbehera 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, addr);
75825572Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75835572Ssbehera 	    "nxge_is_phy_present: pma_pmd_id[0x%x]", pma_pmd_id));
75845572Ssbehera 	if ((pma_pmd_id & mask) == (id & mask))
75855572Ssbehera 		goto found_phy;
75865572Ssbehera 	pcs_id = nxge_get_cl45_pcs_id(nxgep, addr);
75875572Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75885572Ssbehera 	    "nxge_is_phy_present: pcs_id[0x%x]", pcs_id));
75895572Ssbehera 	if ((pcs_id & mask) == (id & mask))
75905572Ssbehera 		goto found_phy;
75915572Ssbehera 	phy_id = nxge_get_cl22_phy_id(nxgep, addr);
75925572Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75935572Ssbehera 	    "nxge_is_phy_present: phy_id[0x%x]", phy_id));
75945572Ssbehera 	if ((phy_id & mask) == (id & mask))
75955572Ssbehera 		goto found_phy;
75965572Ssbehera 
75975572Ssbehera 	return (B_FALSE);
75985572Ssbehera 
75995572Ssbehera found_phy:
76005572Ssbehera 	return (B_TRUE);
76015572Ssbehera }
76025572Ssbehera 
76034732Sdavemq /* Check if the given id read using the given MDIO Clause is supported */
76044732Sdavemq 
76054732Sdavemq static boolean_t
nxge_is_supported_phy(uint32_t id,uint8_t type)76064732Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type)
76074732Sdavemq {
76084732Sdavemq 	int		i;
76094732Sdavemq 	boolean_t	found = B_FALSE;
76104732Sdavemq 
76114732Sdavemq 	switch (type) {
76124732Sdavemq 	case CLAUSE_45_TYPE:
76136835Syc148097 		for (i = 0; i < NUM_CLAUSE_45_IDS; i++) {
76146835Syc148097 			if (((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) ==
76156835Syc148097 			    (id & BCM_PHY_ID_MASK)) ||
761612103SSantwona.Behera@Sun.COM 			    (TN1010_DEV_ID == (id & TN1010_DEV_ID_MASK)) ||
761712103SSantwona.Behera@Sun.COM 			    (NLP2020_DEV_ID == (id & NLP2020_DEV_ID_MASK))) {
76184732Sdavemq 				found = B_TRUE;
76194732Sdavemq 				break;
76204732Sdavemq 			}
76214732Sdavemq 		}
76224732Sdavemq 		break;
76234732Sdavemq 	case CLAUSE_22_TYPE:
76246835Syc148097 		for (i = 0; i < NUM_CLAUSE_22_IDS; i++) {
76254782Ssbehera 			if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) ==
76264782Ssbehera 			    (id & BCM_PHY_ID_MASK)) {
76274732Sdavemq 				found = B_TRUE;
76284732Sdavemq 				break;
76294732Sdavemq 			}
76304732Sdavemq 		}
76314732Sdavemq 		break;
76324732Sdavemq 	default:
76334732Sdavemq 		break;
76344732Sdavemq 	}
76354732Sdavemq 
76364732Sdavemq 	return (found);
76374732Sdavemq }
76384732Sdavemq 
76394977Sraghus static uint32_t
nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep,int phy_port)76404977Sraghus nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port)
76414977Sraghus {
76424977Sraghus 	uint16_t	val1 = 0;
76434977Sraghus 	uint16_t	val2 = 0;
76444977Sraghus 	uint32_t	pma_pmd_dev_id = 0;
76454977Sraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
76464977Sraghus 
76475780Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
76484977Sraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
76494977Sraghus 	    NXGE_DEV_ID_REG_1, &val1);
76504977Sraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
76514977Sraghus 	    NXGE_DEV_ID_REG_2, &val2);
76525780Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
76534977Sraghus 
76546835Syc148097 	/* Concatenate the Device ID stored in two registers. */
76554977Sraghus 	pma_pmd_dev_id = val1;
76564977Sraghus 	pma_pmd_dev_id = (pma_pmd_dev_id << 16);
76574977Sraghus 	pma_pmd_dev_id |= val2;
76584977Sraghus 
76594977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD "
76604977Sraghus 	    "devid[0x%llx]", phy_port, pma_pmd_dev_id));
76614977Sraghus 
76624977Sraghus 	return (pma_pmd_dev_id);
76634977Sraghus }
76644977Sraghus 
76654977Sraghus static uint32_t
nxge_get_cl45_pcs_id(p_nxge_t nxgep,int phy_port)76664977Sraghus nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port)
76674977Sraghus {
76684977Sraghus 	uint16_t	val1 = 0;
76694977Sraghus 	uint16_t	val2 = 0;
76704977Sraghus 	uint32_t	pcs_dev_id = 0;
76714977Sraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
76724977Sraghus 
76735780Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
76744977Sraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
76754977Sraghus 	    NXGE_DEV_ID_REG_1, &val1);
76764977Sraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
76774977Sraghus 	    NXGE_DEV_ID_REG_2, &val2);
76785780Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
76794977Sraghus 
76804977Sraghus 	pcs_dev_id = val1;
76814977Sraghus 	pcs_dev_id = (pcs_dev_id << 16);
76824977Sraghus 	pcs_dev_id |= val2;
76834977Sraghus 
76844977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
76854977Sraghus 	    "devid[0x%llx]", phy_port, pcs_dev_id));
76864977Sraghus 
76874977Sraghus 	return (pcs_dev_id);
76884977Sraghus }
76894977Sraghus 
76904977Sraghus static uint32_t
nxge_get_cl22_phy_id(p_nxge_t nxgep,int phy_port)76914977Sraghus nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port)
76924977Sraghus {
76934977Sraghus 	uint16_t	val1 = 0;
76944977Sraghus 	uint16_t	val2 = 0;
76954977Sraghus 	uint32_t	phy_id = 0;
76964977Sraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
76974977Sraghus 	npi_status_t	npi_status = NPI_SUCCESS;
76984977Sraghus 
76996075Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
77004977Sraghus 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1,
77014977Sraghus 	    &val1);
77024977Sraghus 	if (npi_status != NPI_SUCCESS) {
77034977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
77044977Sraghus 		    "clause 22 read to reg 2 failed!!!"));
77054977Sraghus 		goto exit;
77064977Sraghus 	}
77074977Sraghus 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2,
77084977Sraghus 	    &val2);
77094977Sraghus 	if (npi_status != 0) {
77104977Sraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
77114977Sraghus 		    "clause 22 read to reg 3 failed!!!"));
77124977Sraghus 		goto exit;
77134977Sraghus 	}
77144977Sraghus 	phy_id = val1;
77154977Sraghus 	phy_id = (phy_id << 16);
77164977Sraghus 	phy_id |= val2;
77174977Sraghus 
77184977Sraghus exit:
77196075Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
77204977Sraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]",
77214977Sraghus 	    phy_port, phy_id));
77224977Sraghus 
77234977Sraghus 	return (phy_id);
77244977Sraghus }
77254977Sraghus 
77264732Sdavemq /*
77274732Sdavemq  * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO
77284732Sdavemq  * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO
77294732Sdavemq  * read. Then use the values obtained to determine the phy type of each port
77304732Sdavemq  * and the Neptune type.
77316835Syc148097  *
77326835Syc148097  * This function sets hw_p->xcvr_addr[i] for future MDIO access and set
77336835Syc148097  * hw_p->niu_type for each nxge instance to figure out nxgep->mac.portmode
77346835Syc148097  * in case the portmode information is not available via OBP, nxge.conf,
77356835Syc148097  * VPD or SEEPROM.
77364732Sdavemq  */
77374732Sdavemq nxge_status_t
nxge_scan_ports_phy(p_nxge_t nxgep,p_nxge_hw_list_t hw_p)77384732Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p)
77394732Sdavemq {
77406261Sjoycey 	int		i, j, l;
77414732Sdavemq 	uint32_t	pma_pmd_dev_id = 0;
77424732Sdavemq 	uint32_t	pcs_dev_id = 0;
77434732Sdavemq 	uint32_t	phy_id = 0;
77444782Ssbehera 	uint32_t	port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE];
77454782Ssbehera 	uint32_t	port_pcs_dev_id[NXGE_PORTS_NEPTUNE];
77464782Ssbehera 	uint32_t	port_phy_id[NXGE_PORTS_NEPTUNE];
77474732Sdavemq 	uint8_t		pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS];
77484732Sdavemq 	uint8_t		pcs_dev_fd[NXGE_MAX_PHY_PORTS];
77495572Ssbehera 	uint8_t		phy_fd_arr[NXGE_MAX_PHY_PORTS];
77505572Ssbehera 	uint8_t		port_fd_arr[NXGE_MAX_PHY_PORTS];
77514732Sdavemq 	uint8_t		total_port_fd, total_phy_fd;
77526835Syc148097 	uint8_t		num_xaui;
77534732Sdavemq 	nxge_status_t	status = NXGE_OK;
77544732Sdavemq 
77554732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: "));
77564732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
77574732Sdavemq 	    "==> nxge_scan_ports_phy: nxge niu_type[0x%x]",
77584732Sdavemq 	    nxgep->niu_type));
77594732Sdavemq 
77606495Sspeer 	if (isLDOMguest(nxgep)) {
77616495Sspeer 		hw_p->niu_type = NIU_TYPE_NONE;
77626495Sspeer 		hw_p->platform_type = P_NEPTUNE_NONE;
77636495Sspeer 		return (NXGE_OK);
77646495Sspeer 	}
77656495Sspeer 
77666261Sjoycey 	j = l = 0;
77674732Sdavemq 	total_port_fd = total_phy_fd = 0;
77684732Sdavemq 	/*
77697801SSantwona.Behera@Sun.COM 	 * Clause 45 and Clause 22 port/phy addresses 0 through 5 are reserved
77707801SSantwona.Behera@Sun.COM 	 * for on chip serdes usages. "i" in the following for loop starts at 6.
77714732Sdavemq 	 */
77724732Sdavemq 	for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) {
77734977Sraghus 
77744977Sraghus 		pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i);
77754732Sdavemq 
77764732Sdavemq 		if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) {
77774732Sdavemq 			pma_pmd_dev_fd[i] = 1;
77784732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
77796604Ssbehera 			    "PMA/PMD dev %x found", i, pma_pmd_dev_id));
77804782Ssbehera 			if (j < NXGE_PORTS_NEPTUNE) {
77816835Syc148097 				if ((pma_pmd_dev_id & TN1010_DEV_ID_MASK)
77826835Syc148097 				    == TN1010_DEV_ID) {
77836835Syc148097 					port_pma_pmd_dev_id[j] = TN1010_DEV_ID;
778412103SSantwona.Behera@Sun.COM 				} else if ((pma_pmd_dev_id &
778512103SSantwona.Behera@Sun.COM 				    NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID) {
778612103SSantwona.Behera@Sun.COM 					port_pma_pmd_dev_id[j] =
778712103SSantwona.Behera@Sun.COM 					    NLP2020_DEV_ID;
77886835Syc148097 				} else {
77896835Syc148097 					port_pma_pmd_dev_id[j] =
77906929Smisaki 					    pma_pmd_dev_id & BCM_PHY_ID_MASK;
77916835Syc148097 				}
77925572Ssbehera 				port_fd_arr[j] = (uint8_t)i;
77934732Sdavemq 				j++;
77944732Sdavemq 			}
77954732Sdavemq 		} else {
77964732Sdavemq 			pma_pmd_dev_fd[i] = 0;
77974732Sdavemq 		}
77984732Sdavemq 
77994977Sraghus 		pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i);
78004732Sdavemq 
78014732Sdavemq 		if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) {
78024732Sdavemq 			pcs_dev_fd[i] = 1;
78034732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
78046604Ssbehera 			    "dev %x found", i, pcs_dev_id));
78056261Sjoycey 			if (pma_pmd_dev_fd[i] == 1) {
78066835Syc148097 				if ((pcs_dev_id & TN1010_DEV_ID_MASK)
78076835Syc148097 				    == TN1010_DEV_ID) {
78086835Syc148097 					port_pcs_dev_id[j - 1] =
78096835Syc148097 					    TN1010_DEV_ID;
781012103SSantwona.Behera@Sun.COM 				} else if ((pcs_dev_id & NLP2020_DEV_ID_MASK)
781112103SSantwona.Behera@Sun.COM 				    == NLP2020_DEV_ID) {
781212103SSantwona.Behera@Sun.COM 					port_pcs_dev_id[j - 1] =
781312103SSantwona.Behera@Sun.COM 					    NLP2020_DEV_ID;
78146835Syc148097 				} else {
78156835Syc148097 					port_pcs_dev_id[j - 1] =
78166835Syc148097 					    pcs_dev_id &
78176835Syc148097 					    BCM_PHY_ID_MASK;
78186835Syc148097 				}
78196261Sjoycey 			} else {
78206261Sjoycey 				if (j < NXGE_PORTS_NEPTUNE) {
78216835Syc148097 					if ((pcs_dev_id & TN1010_DEV_ID_MASK)
78226929Smisaki 					    == TN1010_DEV_ID) {
78236835Syc148097 						port_pcs_dev_id[j] =
78246835Syc148097 						    TN1010_DEV_ID;
782512103SSantwona.Behera@Sun.COM 					} else if ((pcs_dev_id &
782612103SSantwona.Behera@Sun.COM 					    NLP2020_DEV_ID_MASK)
782712103SSantwona.Behera@Sun.COM 					    == NLP2020_DEV_ID) {
782812103SSantwona.Behera@Sun.COM 						port_pcs_dev_id[j] =
782912103SSantwona.Behera@Sun.COM 						    NLP2020_DEV_ID;
78306835Syc148097 					} else {
78316835Syc148097 						port_pcs_dev_id[j] =
78326835Syc148097 						    pcs_dev_id &
78336835Syc148097 						    BCM_PHY_ID_MASK;
78346835Syc148097 					}
78356261Sjoycey 					port_fd_arr[j] = (uint8_t)i;
78366261Sjoycey 					j++;
78376261Sjoycey 				}
78384732Sdavemq 			}
78394732Sdavemq 		} else {
78404732Sdavemq 			pcs_dev_fd[i] = 0;
78414732Sdavemq 		}
78424732Sdavemq 
78435572Ssbehera 		if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) {
78445572Ssbehera 			total_port_fd ++;
78455572Ssbehera 		}
78464732Sdavemq 
78474977Sraghus 		phy_id = nxge_get_cl22_phy_id(nxgep, i);
78484732Sdavemq 		if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
78495572Ssbehera 			total_phy_fd ++;
78504732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID"
78516604Ssbehera 			    "%x found", i, phy_id));
78524782Ssbehera 			if (l < NXGE_PORTS_NEPTUNE) {
78536835Syc148097 				if ((phy_id & TN1010_DEV_ID_MASK)
78546835Syc148097 				    == TN1010_DEV_ID) {
78556835Syc148097 					port_phy_id[l] = TN1010_DEV_ID;
78566835Syc148097 				} else {
78576835Syc148097 					port_phy_id[l]
78586835Syc148097 					    = phy_id & BCM_PHY_ID_MASK;
78596835Syc148097 				}
78605572Ssbehera 				phy_fd_arr[l] = (uint8_t)i;
78614732Sdavemq 				l++;
78624732Sdavemq 			}
78634732Sdavemq 		}
78644732Sdavemq 	}
78654732Sdavemq 
78664732Sdavemq 	switch (total_port_fd) {
78674732Sdavemq 	case 2:
78684732Sdavemq 		switch (total_phy_fd) {
78694732Sdavemq 		case 2:
78707801SSantwona.Behera@Sun.COM 			/* 2 10G, 2 1G RGMII Fiber / copper */
78716261Sjoycey 			if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
78726261Sjoycey 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
78736261Sjoycey 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
78746261Sjoycey 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) &&
78756261Sjoycey 			    ((port_phy_id[0] == PHY_BCM5482_FAMILY) &&
78766261Sjoycey 			    (port_phy_id[1] == PHY_BCM5482_FAMILY))) {
78776261Sjoycey 
78787801SSantwona.Behera@Sun.COM 				switch (hw_p->platform_type) {
78797801SSantwona.Behera@Sun.COM 				case P_NEPTUNE_ROCK:
78807801SSantwona.Behera@Sun.COM 					hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
78817801SSantwona.Behera@Sun.COM 					/*
78827801SSantwona.Behera@Sun.COM 					 * ROCK platform has assigned a lower
78837801SSantwona.Behera@Sun.COM 					 * addr to port 1. (port 0 = 0x9 and
78847801SSantwona.Behera@Sun.COM 					 * port 1 = 0x8).
78857801SSantwona.Behera@Sun.COM 					 */
78867801SSantwona.Behera@Sun.COM 					hw_p->xcvr_addr[1] = port_fd_arr[0];
78877801SSantwona.Behera@Sun.COM 					hw_p->xcvr_addr[0] = port_fd_arr[1];
78887801SSantwona.Behera@Sun.COM 
78897801SSantwona.Behera@Sun.COM 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
78907801SSantwona.Behera@Sun.COM 					    "Rock with 2 10G, 2 1GC"));
78917801SSantwona.Behera@Sun.COM 					break;
78927801SSantwona.Behera@Sun.COM 
78937801SSantwona.Behera@Sun.COM 				case P_NEPTUNE_NONE:
78947801SSantwona.Behera@Sun.COM 				default:
78957801SSantwona.Behera@Sun.COM 					hw_p->platform_type =
78967801SSantwona.Behera@Sun.COM 					    P_NEPTUNE_GENERIC;
78977801SSantwona.Behera@Sun.COM 					hw_p->niu_type = NEPTUNE_2_10GF_2_1GRF;
78987801SSantwona.Behera@Sun.COM 
78997801SSantwona.Behera@Sun.COM 					hw_p->xcvr_addr[0] = port_fd_arr[0];
79007801SSantwona.Behera@Sun.COM 					hw_p->xcvr_addr[1] = port_fd_arr[1];
79017801SSantwona.Behera@Sun.COM 
79027801SSantwona.Behera@Sun.COM 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
79037801SSantwona.Behera@Sun.COM 					    "ARTM card with 2 10G, 2 1GF"));
79047801SSantwona.Behera@Sun.COM 					break;
79057801SSantwona.Behera@Sun.COM 				}
79067801SSantwona.Behera@Sun.COM 
79076261Sjoycey 				hw_p->xcvr_addr[2] = phy_fd_arr[0];
79086261Sjoycey 				hw_p->xcvr_addr[3] = phy_fd_arr[1];
79096261Sjoycey 
79106261Sjoycey 			} else {
79116261Sjoycey 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
79126261Sjoycey 				    "Unsupported neptune type 1"));
79136261Sjoycey 				goto error_exit;
79146261Sjoycey 			}
79156261Sjoycey 			break;
79166261Sjoycey 
79174732Sdavemq 		case 1:
79184732Sdavemq 			/* TODO - 2 10G, 1 1G */
79194732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
79204732Sdavemq 			    "Unsupported neptune type 2 10G, 1 1G"));
79214732Sdavemq 			goto error_exit;
79224732Sdavemq 		case 0:
79236835Syc148097 			/*
79246835Syc148097 			 * 2 10G: 2XGF NIC, Marvell, Goa, Huron with 2 XAUI
79256835Syc148097 			 * cards, etc.
79266835Syc148097 			 */
79274782Ssbehera 			if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
79284782Ssbehera 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
79294782Ssbehera 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
79306604Ssbehera 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY)) ||
79316604Ssbehera 			    ((port_pcs_dev_id[0] == MARVELL_88X201X_PHY_ID) &&
79326604Ssbehera 			    (port_pcs_dev_id[1] == MARVELL_88X201X_PHY_ID)) ||
79336604Ssbehera 			    ((port_pma_pmd_dev_id[0] ==
79346604Ssbehera 			    MARVELL_88X201X_PHY_ID) &&
79356604Ssbehera 			    (port_pma_pmd_dev_id[1] ==
79366604Ssbehera 			    MARVELL_88X201X_PHY_ID))) {
79374977Sraghus 
79384977Sraghus 				/*
79394977Sraghus 				 * Check the first phy port address against
79404977Sraghus 				 * the known phy start addresses to determine
79414977Sraghus 				 * the platform type.
79424977Sraghus 				 */
79435572Ssbehera 
79445572Ssbehera 				switch (port_fd_arr[0]) {
79456835Syc148097 				case NEPTUNE_CLAUSE45_PORT_ADDR_BASE:
79466604Ssbehera 					/*
79476604Ssbehera 					 * The Marvell case also falls into
79486604Ssbehera 					 * this case as
79496604Ssbehera 					 * MRVL88X2011_NEPTUNE_PORT_ADDR_BASE
79506835Syc148097 					 * == NEPTUNE_CLAUSE45_PORT_ADDR_BASE.
79516604Ssbehera 					 * This is OK for the 2 10G case.
79526604Ssbehera 					 */
79534977Sraghus 					hw_p->niu_type = NEPTUNE_2_10GF;
79544977Sraghus 					hw_p->platform_type =
79554977Sraghus 					    P_NEPTUNE_ATLAS_2PORT;
79565572Ssbehera 					break;
79576835Syc148097 				case GOA_CLAUSE45_PORT_ADDR_BASE:
79585572Ssbehera 					if (hw_p->platform_type !=
79595572Ssbehera 					    P_NEPTUNE_NIU) {
79605572Ssbehera 						hw_p->platform_type =
79615572Ssbehera 						    P_NEPTUNE_GENERIC;
79625572Ssbehera 						hw_p->niu_type =
79635572Ssbehera 						    NEPTUNE_2_10GF;
79645572Ssbehera 					}
79655572Ssbehera 					break;
79665572Ssbehera 				default:
79675572Ssbehera 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
79684977Sraghus 					    "Unsupported neptune type 2 - 1"));
79694977Sraghus 					goto error_exit;
79704977Sraghus 				}
79715572Ssbehera 
79725572Ssbehera 				for (i = 0; i < 2; i++) {
79735572Ssbehera 					hw_p->xcvr_addr[i] = port_fd_arr[i];
79745572Ssbehera 				}
79756835Syc148097 
797612103SSantwona.Behera@Sun.COM 			/* 2 10G optical Netlogic AEL2020 ports */
797712103SSantwona.Behera@Sun.COM 			} else if (((port_pcs_dev_id[0] == NLP2020_DEV_ID) &&
797812103SSantwona.Behera@Sun.COM 			    (port_pcs_dev_id[1]  == NLP2020_DEV_ID)) ||
797912103SSantwona.Behera@Sun.COM 			    ((port_pma_pmd_dev_id[0]  == NLP2020_DEV_ID) &&
798012103SSantwona.Behera@Sun.COM 			    (port_pma_pmd_dev_id[1] == NLP2020_DEV_ID))) {
798112103SSantwona.Behera@Sun.COM 				if (hw_p->platform_type != P_NEPTUNE_NIU) {
798212103SSantwona.Behera@Sun.COM 					hw_p->platform_type =
798312103SSantwona.Behera@Sun.COM 					    P_NEPTUNE_GENERIC;
798412103SSantwona.Behera@Sun.COM 					hw_p->niu_type =
798512103SSantwona.Behera@Sun.COM 					    NEPTUNE_2_10GF;
798612103SSantwona.Behera@Sun.COM 				}
798712103SSantwona.Behera@Sun.COM 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
798812103SSantwona.Behera@Sun.COM 				    "Found 2 NL PHYs at addrs 0x%x and 0x%x",
798912103SSantwona.Behera@Sun.COM 				    port_fd_arr[0], port_fd_arr[1]));
799012103SSantwona.Behera@Sun.COM 				hw_p->xcvr_addr[0] = port_fd_arr[0];
799112103SSantwona.Behera@Sun.COM 				hw_p->xcvr_addr[1] = port_fd_arr[1];
799212103SSantwona.Behera@Sun.COM 
79936835Syc148097 			/* Both XAUI slots have copper XAUI cards */
79946835Syc148097 			} else if ((((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
79956835Syc148097 			    == TN1010_DEV_ID) &&
79966835Syc148097 			    ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
79976835Syc148097 			    == TN1010_DEV_ID)) ||
79986835Syc148097 			    (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
79996835Syc148097 			    == TN1010_DEV_ID) &&
80006835Syc148097 			    ((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
80016835Syc148097 			    == TN1010_DEV_ID))) {
80026835Syc148097 				hw_p->niu_type = NEPTUNE_2_TN1010;
80036835Syc148097 				hw_p->xcvr_addr[0] = port_fd_arr[0];
80046835Syc148097 				hw_p->xcvr_addr[1] = port_fd_arr[1];
80056835Syc148097 
80066835Syc148097 			/* Slot0 has fiber XAUI, slot1 has copper XAUI */
80076835Syc148097 			} else if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
80086835Syc148097 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
80096835Syc148097 			    == TN1010_DEV_ID) ||
80106835Syc148097 			    (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY &&
80116835Syc148097 			    (port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) ==
80126835Syc148097 			    TN1010_DEV_ID)) {
80136835Syc148097 				hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010;
80146835Syc148097 				hw_p->xcvr_addr[0] = port_fd_arr[0];
80156835Syc148097 				hw_p->xcvr_addr[1] = port_fd_arr[1];
80166835Syc148097 
80176835Syc148097 			/* Slot0 has copper XAUI, slot1 has fiber XAUI */
80186835Syc148097 			} else if ((port_pcs_dev_id[1] == PHY_BCM8704_FAMILY &&
80196835Syc148097 			    (port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
80206835Syc148097 			    == TN1010_DEV_ID) ||
80216835Syc148097 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY &&
80226835Syc148097 			    (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
80236835Syc148097 			    == TN1010_DEV_ID)) {
80246835Syc148097 				hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF;
80256835Syc148097 				hw_p->xcvr_addr[0] = port_fd_arr[0];
80266835Syc148097 				hw_p->xcvr_addr[1] = port_fd_arr[1];
80276835Syc148097 
80284732Sdavemq 			} else {
80294732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
80304732Sdavemq 				    "Unsupported neptune type 2"));
80314732Sdavemq 				goto error_exit;
80324732Sdavemq 			}
80334732Sdavemq 			break;
80346835Syc148097 
80354732Sdavemq 		case 4:
80366835Syc148097 			if (nxge_get_num_of_xaui(
80376835Syc148097 			    port_pma_pmd_dev_id, port_pcs_dev_id,
80386835Syc148097 			    port_phy_id, &num_xaui) == NXGE_ERROR) {
80396835Syc148097 				goto error_exit;
80406835Syc148097 			}
80416835Syc148097 			if (num_xaui != 2)
80426835Syc148097 				goto error_exit;
80436835Syc148097 
80446835Syc148097 			/*
80456835Syc148097 			 *  Maramba with 2 XAUIs (either fiber or copper)
80466835Syc148097 			 *
80476835Syc148097 			 * Check the first phy port address against
80486835Syc148097 			 * the known phy start addresses to determine
80496835Syc148097 			 * the platform type.
80506835Syc148097 			 */
80516835Syc148097 			switch (phy_fd_arr[0]) {
80526835Syc148097 			case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
80536835Syc148097 				hw_p->platform_type =
80546835Syc148097 				    P_NEPTUNE_MARAMBA_P0;
80556835Syc148097 				break;
80566835Syc148097 			case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
80576835Syc148097 				hw_p->platform_type =
80586835Syc148097 				    P_NEPTUNE_MARAMBA_P1;
80596835Syc148097 				break;
80606835Syc148097 			default:
80616835Syc148097 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
80626835Syc148097 				    "Unknown port %d...Cannot "
80636835Syc148097 				    "determine platform type", i));
80646835Syc148097 				goto error_exit;
80656835Syc148097 			}
80666835Syc148097 
80676835Syc148097 			hw_p->xcvr_addr[0] = port_fd_arr[0];
80686835Syc148097 			hw_p->xcvr_addr[1] = port_fd_arr[1];
80696835Syc148097 			hw_p->xcvr_addr[2] = phy_fd_arr[2];
80706835Syc148097 			hw_p->xcvr_addr[3] = phy_fd_arr[3];
80716835Syc148097 
80726835Syc148097 			/* slot0 has fiber XAUI, slot1 has Cu XAUI */
80736835Syc148097 			if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
80746835Syc148097 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
80756835Syc148097 			    == TN1010_DEV_ID) {
80766835Syc148097 				hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010_2_1GC;
80776835Syc148097 
80786835Syc148097 			/* slot0 has Cu XAUI, slot1 has fiber XAUI */
80796835Syc148097 			} else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
80806835Syc148097 			    == TN1010_DEV_ID) &&
80816835Syc148097 			    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
80826835Syc148097 				hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF_2_1GC;
80836835Syc148097 
80846835Syc148097 			/* Both slots have fiber XAUI */
80856835Syc148097 			} else if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
80866835Syc148097 			    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
80874977Sraghus 				hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
80884977Sraghus 
80896835Syc148097 			/* Both slots have copper XAUI */
80906835Syc148097 			} else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
80916835Syc148097 			    == TN1010_DEV_ID) &&
80926835Syc148097 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
80936835Syc148097 			    == TN1010_DEV_ID) {
80946835Syc148097 				hw_p->niu_type = NEPTUNE_2_TN1010_2_1GC;
80956835Syc148097 
80964732Sdavemq 			} else {
80974732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
80984732Sdavemq 				    "Unsupported neptune type 3"));
80994732Sdavemq 				goto error_exit;
81004732Sdavemq 			}
81014732Sdavemq 			break;
81024732Sdavemq 		default:
81034732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
81044732Sdavemq 			    "Unsupported neptune type 5"));
81054732Sdavemq 			goto error_exit;
81064732Sdavemq 		}
81074782Ssbehera 		break;
81086835Syc148097 	case 1: 	/* Only one clause45 port */
81096835Syc148097 		switch (total_phy_fd) {	/* Number of clause22 ports */
81104732Sdavemq 		case 3:
81114977Sraghus 			/*
81124977Sraghus 			 * TODO 3 1G, 1 10G mode.
81134977Sraghus 			 * Differentiate between 1_1G_1_10G_2_1G and
81144977Sraghus 			 * 1_10G_3_1G
81154977Sraghus 			 */
81164977Sraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
81174977Sraghus 			    "Unsupported neptune type 7"));
81184977Sraghus 			goto error_exit;
81194732Sdavemq 		case 2:
81204732Sdavemq 			/*
81214732Sdavemq 			 * TODO 2 1G, 1 10G mode.
81224732Sdavemq 			 * Differentiate between 1_1G_1_10G_1_1G and
81234732Sdavemq 			 * 1_10G_2_1G
81244732Sdavemq 			 */
81254732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
81264732Sdavemq 			    "Unsupported neptune type 8"));
81274732Sdavemq 			goto error_exit;
81284732Sdavemq 		case 1:
81294732Sdavemq 			/*
81304732Sdavemq 			 * TODO 1 1G, 1 10G mode.
81314732Sdavemq 			 * Differentiate between 1_1G_1_10G and
81324732Sdavemq 			 * 1_10G_1_1G
81334732Sdavemq 			 */
81344732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
81354732Sdavemq 			    "Unsupported neptune type 9"));
81364732Sdavemq 			goto error_exit;
81376835Syc148097 		case 0:	/* N2 with 1 XAUI (fiber or copper) */
81386835Syc148097 			/* Fiber XAUI */
81395572Ssbehera 			if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY ||
81405572Ssbehera 			    port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) {
81415572Ssbehera 
81425572Ssbehera 				/*
81435572Ssbehera 				 * Check the first phy port address against
81445572Ssbehera 				 * the known phy start addresses to determine
81455572Ssbehera 				 * the platform type.
81465572Ssbehera 				 */
81475572Ssbehera 
81485572Ssbehera 				switch (port_fd_arr[0]) {
81496835Syc148097 				case N2_CLAUSE45_PORT_ADDR_BASE:
81506835Syc148097 				case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
81516835Syc148097 				case ALT_GOA_CLAUSE45_PORT1_ADDR:
81526835Syc148097 					/*
81536835Syc148097 					 * If hw_p->platform_type ==
81546835Syc148097 					 * P_NEPTUNE_NIU, then portmode
81556835Syc148097 					 * is already known, so there is
81566835Syc148097 					 * no need to figure out hw_p->
81576835Syc148097 					 * platform_type because
81586835Syc148097 					 * platform_type is only for
81596835Syc148097 					 * figuring out portmode.
81606835Syc148097 					 */
81615572Ssbehera 					if (hw_p->platform_type !=
81625572Ssbehera 					    P_NEPTUNE_NIU) {
81635572Ssbehera 						hw_p->platform_type =
81645572Ssbehera 						    P_NEPTUNE_GENERIC;
81655572Ssbehera 						hw_p->niu_type =
81665572Ssbehera 						    NEPTUNE_2_10GF;
81675572Ssbehera 					}
81685572Ssbehera 					break;
81695572Ssbehera 				default:
81705572Ssbehera 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
81715572Ssbehera 					    "Unsupported neptune type 10"));
81725572Ssbehera 					goto error_exit;
81735572Ssbehera 				}
81746075Ssbehera 				/*
81756075Ssbehera 				 * For GOA, which is a hot swappable PHY, the
81766075Ssbehera 				 * phy address to function number mapping
81776075Ssbehera 				 * should be preserved, i.e., addr 16 is
81786075Ssbehera 				 * assigned to function 0 and 20 to function 1
81796075Ssbehera 				 * But for Huron XAUI, the assignment should
81806075Ssbehera 				 * be by function number, i.e., whichever
81816075Ssbehera 				 * function number attaches should be
81826075Ssbehera 				 * assigned the available PHY (this is required
81836075Ssbehera 				 * primarily to support pre-production Huron
81846075Ssbehera 				 * boards where function 0 is mapped to addr 17
81856075Ssbehera 				 */
81866075Ssbehera 				if (port_fd_arr[0] ==
81876835Syc148097 				    ALT_GOA_CLAUSE45_PORT1_ADDR) {
81886075Ssbehera 					hw_p->xcvr_addr[1] = port_fd_arr[0];
81896075Ssbehera 				} else {
81906075Ssbehera 					hw_p->xcvr_addr[nxgep->function_num] =
81916075Ssbehera 					    port_fd_arr[0];
81926075Ssbehera 				}
819312103SSantwona.Behera@Sun.COM 			} else if (port_pcs_dev_id[0] == NLP2020_DEV_ID ||
819412103SSantwona.Behera@Sun.COM 			    port_pma_pmd_dev_id[0] == NLP2020_DEV_ID) {
819512103SSantwona.Behera@Sun.COM 				/* A 10G NLP2020 PHY in slot0 or slot1 */
819612103SSantwona.Behera@Sun.COM 				switch (port_fd_arr[0]) {
819712103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT0_ADDR0:
819812103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT0_ADDR1:
819912103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT0_ADDR2:
820012103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT0_ADDR3:
820112103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT1_ADDR0:
820212103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT1_ADDR1:
820312103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT1_ADDR2:
820412103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT1_ADDR3:
820512103SSantwona.Behera@Sun.COM 					/*
820612103SSantwona.Behera@Sun.COM 					 * If hw_p->platform_type ==
820712103SSantwona.Behera@Sun.COM 					 * P_NEPTUNE_NIU, then portmode
820812103SSantwona.Behera@Sun.COM 					 * is already known, so there is
820912103SSantwona.Behera@Sun.COM 					 * no need to figure out hw_p->
821012103SSantwona.Behera@Sun.COM 					 * platform_type because
821112103SSantwona.Behera@Sun.COM 					 * platform_type is only for
821212103SSantwona.Behera@Sun.COM 					 * figuring out portmode.
821312103SSantwona.Behera@Sun.COM 					 */
821412103SSantwona.Behera@Sun.COM 					if (hw_p->platform_type !=
821512103SSantwona.Behera@Sun.COM 					    P_NEPTUNE_NIU) {
821612103SSantwona.Behera@Sun.COM 						hw_p->platform_type =
821712103SSantwona.Behera@Sun.COM 						    P_NEPTUNE_GENERIC;
821812103SSantwona.Behera@Sun.COM 						hw_p->niu_type =
821912103SSantwona.Behera@Sun.COM 						    NEPTUNE_2_10GF;
822012103SSantwona.Behera@Sun.COM 					}
822112103SSantwona.Behera@Sun.COM 					break;
822212103SSantwona.Behera@Sun.COM 				default:
822312103SSantwona.Behera@Sun.COM 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
822412103SSantwona.Behera@Sun.COM 					    "Unsupported neptune type 10-1"));
822512103SSantwona.Behera@Sun.COM 					goto error_exit;
822612103SSantwona.Behera@Sun.COM 				}
822712103SSantwona.Behera@Sun.COM 				switch (port_fd_arr[0]) {
822812103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT0_ADDR0:
822912103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT0_ADDR1:
823012103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT0_ADDR2:
823112103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT0_ADDR3:
823212103SSantwona.Behera@Sun.COM 					hw_p->xcvr_addr[0] = port_fd_arr[0];
823312103SSantwona.Behera@Sun.COM 					break;
823412103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT1_ADDR0:
823512103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT1_ADDR1:
823612103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT1_ADDR2:
823712103SSantwona.Behera@Sun.COM 				case NLP2020_CL45_PORT1_ADDR3:
823812103SSantwona.Behera@Sun.COM 					hw_p->xcvr_addr[1] = port_fd_arr[0];
823912103SSantwona.Behera@Sun.COM 					break;
824012103SSantwona.Behera@Sun.COM 				default:
824112103SSantwona.Behera@Sun.COM 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
824212103SSantwona.Behera@Sun.COM 					    "Unsupported neptune type 10-11"));
824312103SSantwona.Behera@Sun.COM 					goto error_exit;
824412103SSantwona.Behera@Sun.COM 				}
824512103SSantwona.Behera@Sun.COM 
824612103SSantwona.Behera@Sun.COM 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
824712103SSantwona.Behera@Sun.COM 				    "Found 1 NL PHYs at addr 0x%x",
824812103SSantwona.Behera@Sun.COM 				    port_fd_arr[0]));
82496835Syc148097 
82506835Syc148097 			/* A 10G copper XAUI in either slot0 or slot1 */
82516835Syc148097 			} else if ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
82526835Syc148097 			    == TN1010_DEV_ID ||
82536835Syc148097 			    (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
82546835Syc148097 			    == TN1010_DEV_ID) {
82556835Syc148097 				switch (port_fd_arr[0]) {
82566835Syc148097 				/* The XAUI is in slot0 */
82576835Syc148097 				case N2_CLAUSE45_PORT_ADDR_BASE:
82586835Syc148097 					hw_p->niu_type = NEPTUNE_1_TN1010;
82596835Syc148097 					break;
82606835Syc148097 
82616835Syc148097 				/* The XAUI is in slot1 */
82626835Syc148097 				case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
82636835Syc148097 					hw_p->niu_type
82646835Syc148097 					    = NEPTUNE_1_NONE_1_TN1010;
82656835Syc148097 					break;
82666835Syc148097 				default:
82676835Syc148097 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
82686835Syc148097 					    "Unsupported XAUI port address"));
82696835Syc148097 					goto error_exit;
82706835Syc148097 				}
82716835Syc148097 				hw_p->xcvr_addr[nxgep->function_num]
82726835Syc148097 				    = port_fd_arr[0];
82736835Syc148097 
82745572Ssbehera 			} else {
82755572Ssbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
82766835Syc148097 				    "Unsupported PHY type"));
82775572Ssbehera 				goto error_exit;
82785572Ssbehera 			}
82795572Ssbehera 			break;
82806835Syc148097 		case 4: /* Maramba always have 4 clause 45 ports */
82816835Syc148097 
82824732Sdavemq 			/* Maramba with 1 XAUI */
82836929Smisaki 			if ((port_pcs_dev_id[0] != PHY_BCM8704_FAMILY) &&
82846929Smisaki 			    (port_pma_pmd_dev_id[0] != PHY_BCM8704_FAMILY) &&
82856835Syc148097 			    ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
82866929Smisaki 			    != TN1010_DEV_ID) &&
82876835Syc148097 			    ((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
82886929Smisaki 			    != TN1010_DEV_ID)) {
82894732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
82904732Sdavemq 				    "Unsupported neptune type 12"));
82914732Sdavemq 				goto error_exit;
82924732Sdavemq 			}
82936929Smisaki 
82946929Smisaki 			/*
82956929Smisaki 			 * Check the first phy port address against
82966929Smisaki 			 * the known phy start addresses to determine
82976929Smisaki 			 * the platform type.
82986929Smisaki 			 */
82996929Smisaki 			switch (phy_fd_arr[0]) {
83006929Smisaki 			case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
83016929Smisaki 				hw_p->platform_type =
83026929Smisaki 				    P_NEPTUNE_MARAMBA_P0;
83036929Smisaki 				break;
83046929Smisaki 			case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
83056929Smisaki 				hw_p->platform_type =
83066929Smisaki 				    P_NEPTUNE_MARAMBA_P1;
83076929Smisaki 				break;
83086929Smisaki 			default:
83096929Smisaki 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
83106929Smisaki 				    "Unknown port %d...Cannot "
83116929Smisaki 				    "determine platform type 10 - 2",
83126929Smisaki 				    i));
83136929Smisaki 				goto error_exit;
83146929Smisaki 			}
83156929Smisaki 
83166929Smisaki 			/*
83176929Smisaki 			 * Check the clause45 address to determine
83186929Smisaki 			 * if XAUI is in port 0 or port 1.
83196929Smisaki 			 */
83206929Smisaki 			switch (port_fd_arr[0]) {
83216929Smisaki 			case MARAMBA_CLAUSE45_PORT_ADDR_BASE:
83226929Smisaki 				if (port_pcs_dev_id[0]
83236929Smisaki 				    == PHY_BCM8704_FAMILY ||
83246929Smisaki 				    port_pma_pmd_dev_id[0]
83256929Smisaki 				    == PHY_BCM8704_FAMILY) {
83266929Smisaki 					hw_p->niu_type
83276929Smisaki 					    = NEPTUNE_1_10GF_3_1GC;
83286929Smisaki 				} else {
83296929Smisaki 					hw_p->niu_type
83306929Smisaki 					    = NEPTUNE_1_TN1010_3_1GC;
83316929Smisaki 				}
83326929Smisaki 				hw_p->xcvr_addr[0] = port_fd_arr[0];
83336929Smisaki 				for (i = 1; i < NXGE_MAX_PORTS; i++) {
83346929Smisaki 					hw_p->xcvr_addr[i] =
83356929Smisaki 					    phy_fd_arr[i];
83366929Smisaki 				}
83376929Smisaki 				break;
83386929Smisaki 			case (MARAMBA_CLAUSE45_PORT_ADDR_BASE + 1):
83396929Smisaki 				if (port_pcs_dev_id[0]
83406929Smisaki 				    == PHY_BCM8704_FAMILY ||
83416929Smisaki 				    port_pma_pmd_dev_id[0]
83426929Smisaki 				    == PHY_BCM8704_FAMILY) {
83436929Smisaki 					hw_p->niu_type =
83446929Smisaki 					    NEPTUNE_1_1GC_1_10GF_2_1GC;
83456929Smisaki 				} else {
83466929Smisaki 					hw_p->niu_type =
83476929Smisaki 					    NEPTUNE_1_1GC_1_TN1010_2_1GC;
83486929Smisaki 				}
83496929Smisaki 				hw_p->xcvr_addr[0] = phy_fd_arr[0];
83506929Smisaki 				hw_p->xcvr_addr[1] = port_fd_arr[0];
83516929Smisaki 				hw_p->xcvr_addr[2] = phy_fd_arr[2];
83526929Smisaki 				hw_p->xcvr_addr[3] = phy_fd_arr[3];
83536929Smisaki 				break;
83546929Smisaki 			default:
83556929Smisaki 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83566929Smisaki 				    "Unsupported neptune type 11"));
83576929Smisaki 				goto error_exit;
83586929Smisaki 			}
83596929Smisaki 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83606929Smisaki 			    "Maramba with 1 XAUI (fiber or copper)"));
83614732Sdavemq 			break;
83624732Sdavemq 		default:
83634732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83644732Sdavemq 			    "Unsupported neptune type 13"));
83654732Sdavemq 			goto error_exit;
83664732Sdavemq 		}
83674732Sdavemq 		break;
83686835Syc148097 	case 0: /* 4 ports Neptune based NIC */
83694732Sdavemq 		switch (total_phy_fd) {
83704732Sdavemq 		case 4:
83714782Ssbehera 			if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
83724782Ssbehera 			    (port_phy_id[1] == PHY_BCM5464R_FAMILY) &&
83734782Ssbehera 			    (port_phy_id[2] == PHY_BCM5464R_FAMILY) &&
83744782Ssbehera 			    (port_phy_id[3] == PHY_BCM5464R_FAMILY)) {
83754732Sdavemq 
83764732Sdavemq 				/*
83774732Sdavemq 				 * Check the first phy port address against
83784732Sdavemq 				 * the known phy start addresses to determine
83794732Sdavemq 				 * the platform type.
83804732Sdavemq 				 */
83815572Ssbehera 				switch (phy_fd_arr[0]) {
83826835Syc148097 				case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
83834732Sdavemq 					hw_p->platform_type =
83844732Sdavemq 					    P_NEPTUNE_MARAMBA_P1;
83855572Ssbehera 					break;
83866835Syc148097 				case NEPTUNE_CLAUSE22_PORT_ADDR_BASE:
83874977Sraghus 					hw_p->platform_type =
83884977Sraghus 					    P_NEPTUNE_ATLAS_4PORT;
83895572Ssbehera 					break;
83905572Ssbehera 				default:
83914977Sraghus 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
83924977Sraghus 					    "Unknown port %d...Cannot "
83934977Sraghus 					    "determine platform type", i));
83944977Sraghus 					goto error_exit;
83954732Sdavemq 				}
83964977Sraghus 				hw_p->niu_type = NEPTUNE_4_1GC;
83975572Ssbehera 				for (i = 0; i < NXGE_MAX_PORTS; i++) {
83985572Ssbehera 					hw_p->xcvr_addr[i] = phy_fd_arr[i];
83995572Ssbehera 				}
84004732Sdavemq 			} else {
84014732Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84024732Sdavemq 				    "Unsupported neptune type 14"));
84034732Sdavemq 				goto error_exit;
84044732Sdavemq 			}
84054732Sdavemq 			break;
84064732Sdavemq 		case 3:
84074732Sdavemq 			/* TODO 3 1G mode */
84084732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84094732Sdavemq 			    "Unsupported neptune type 15"));
84104732Sdavemq 			goto error_exit;
84114732Sdavemq 		case 2:
84124732Sdavemq 			/* TODO 2 1G mode */
84136261Sjoycey 			if ((port_phy_id[0] == PHY_BCM5482_FAMILY) &&
84146261Sjoycey 			    (port_phy_id[1] == PHY_BCM5482_FAMILY)) {
84156261Sjoycey 				hw_p->platform_type = P_NEPTUNE_GENERIC;
84166261Sjoycey 				hw_p->niu_type = NEPTUNE_2_1GRF;
84176261Sjoycey 				hw_p->xcvr_addr[2] = phy_fd_arr[0];
84186261Sjoycey 				hw_p->xcvr_addr[3] = phy_fd_arr[1];
84196261Sjoycey 			} else {
84206261Sjoycey 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
84216261Sjoycey 				    "Unsupported neptune type 16"));
84226261Sjoycey 				goto error_exit;
84236261Sjoycey 			}
84244732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84256261Sjoycey 			    "2 RGMII Fiber ports - RTM"));
84266261Sjoycey 			break;
84276261Sjoycey 
84284732Sdavemq 		case 1:
84294732Sdavemq 			/* TODO 1 1G mode */
84304732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84314732Sdavemq 			    "Unsupported neptune type 17"));
84324732Sdavemq 			goto error_exit;
84334732Sdavemq 		default:
84344732Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84354732Sdavemq 			    "Unsupported neptune type 18, total phy fd %d",
84364732Sdavemq 			    total_phy_fd));
84374732Sdavemq 			goto error_exit;
84384732Sdavemq 		}
84394732Sdavemq 		break;
84404732Sdavemq 	default:
84414732Sdavemq 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84424732Sdavemq 		    "Unsupported neptune type 19"));
84434732Sdavemq 		goto error_exit;
84444732Sdavemq 	}
84454732Sdavemq 
84464732Sdavemq scan_exit:
84474732Sdavemq 
84484732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, "
84494732Sdavemq 	    "niu type [0x%x]\n", hw_p->niu_type));
84504732Sdavemq 	return (status);
84514732Sdavemq 
84524732Sdavemq error_exit:
84534732Sdavemq 	return (NXGE_ERROR);
84544732Sdavemq }
84554732Sdavemq 
84564185Sspeer boolean_t
nxge_is_valid_local_mac(ether_addr_st mac_addr)84574185Sspeer nxge_is_valid_local_mac(ether_addr_st mac_addr)
84584185Sspeer {
84594185Sspeer 	if ((mac_addr.ether_addr_octet[0] & 0x01) ||
84604185Sspeer 	    (ether_cmp(&mac_addr, &etherbroadcastaddr) == 0) ||
84614185Sspeer 	    (ether_cmp(&mac_addr, &etherzeroaddr) == 0))
84624185Sspeer 		return (B_FALSE);
84634185Sspeer 	else
84644185Sspeer 		return (B_TRUE);
84654185Sspeer }
84664732Sdavemq 
84674732Sdavemq static void
nxge_bcm5464_link_led_off(p_nxge_t nxgep)84684732Sdavemq nxge_bcm5464_link_led_off(p_nxge_t nxgep) {
84694732Sdavemq 
84704732Sdavemq 	npi_status_t rs = NPI_SUCCESS;
84714732Sdavemq 	uint8_t xcvr_portn;
84724732Sdavemq 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
84734732Sdavemq 
84744732Sdavemq 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off"));
84754732Sdavemq 
84764732Sdavemq 	if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) {
84776835Syc148097 		xcvr_portn = MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE;
84784732Sdavemq 	} else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) {
84796835Syc148097 		xcvr_portn = MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE;
84804732Sdavemq 	}
84814732Sdavemq 	/*
84824732Sdavemq 	 * For Altas 4-1G copper, Xcvr port numbers are
84834732Sdavemq 	 * swapped with ethernet port number. This is
84844732Sdavemq 	 * designed for better signal integrity in routing.
84854732Sdavemq 	 */
84864732Sdavemq 	switch (portn) {
84874732Sdavemq 	case 0:
84884732Sdavemq 		xcvr_portn += 3;
84894732Sdavemq 		break;
84904732Sdavemq 	case 1:
84914732Sdavemq 		xcvr_portn += 2;
84924732Sdavemq 		break;
84934732Sdavemq 	case 2:
84944732Sdavemq 		xcvr_portn += 1;
84954732Sdavemq 		break;
84964732Sdavemq 	case 3:
84974732Sdavemq 	default:
84984732Sdavemq 		break;
84994732Sdavemq 	}
85004732Sdavemq 
85016075Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
85024732Sdavemq 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
85034732Sdavemq 	    xcvr_portn, BCM5464R_MISC, 0xb4ee);
85044732Sdavemq 	if (rs != NPI_SUCCESS) {
85054732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
85064732Sdavemq 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
85074732Sdavemq 		    "returned error 0x[%x]", rs));
85086075Ssbehera 		MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
85094732Sdavemq 		return;
85104732Sdavemq 	}
85114732Sdavemq 
85124732Sdavemq 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
85134732Sdavemq 	    xcvr_portn, BCM5464R_MISC, 0xb8ee);
85144732Sdavemq 	if (rs != NPI_SUCCESS) {
85154732Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
85164732Sdavemq 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
85174732Sdavemq 		    "returned error 0x[%x]", rs));
85184732Sdavemq 	}
85194732Sdavemq 
85206075Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
85214732Sdavemq }
85225196Ssbehera 
85235196Ssbehera static nxge_status_t
nxge_mii_get_link_mode(p_nxge_t nxgep)85245196Ssbehera nxge_mii_get_link_mode(p_nxge_t nxgep)
85255196Ssbehera {
85265196Ssbehera 	p_nxge_stats_t	statsp;
85275196Ssbehera 	uint8_t		xcvr_portn;
85285196Ssbehera 	p_mii_regs_t	mii_regs;
85295196Ssbehera 	mii_mode_control_stat_t	mode;
85305196Ssbehera 	int		status = NXGE_OK;
85315196Ssbehera 
85325196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode"));
85335196Ssbehera 
85345196Ssbehera 	statsp = nxgep->statsp;
85355196Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
85365196Ssbehera 	mii_regs = NULL;
85375196Ssbehera 	mode.value = 0;
85385203Ssbehera 	mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
85395196Ssbehera #if defined(__i386)
85405196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
85415196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->shadow),
85425196Ssbehera 	    mode.value)) != NXGE_OK) {
85435196Ssbehera 		goto fail;
85445196Ssbehera #else
85455196Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
85465196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow),
85475196Ssbehera 	    mode.value)) != NXGE_OK) {
85485196Ssbehera 		goto fail;
85495196Ssbehera #endif
85505196Ssbehera 	}
85515196Ssbehera #if defined(__i386)
85525196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
85535196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->shadow),
85545196Ssbehera 	    &mode.value)) != NXGE_OK) {
85555196Ssbehera 		goto fail;
85565196Ssbehera 	}
85575196Ssbehera #else
85585196Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
85595196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow),
85605196Ssbehera 	    &mode.value)) != NXGE_OK) {
85615196Ssbehera 		goto fail;
85625196Ssbehera 	}
85635196Ssbehera #endif
85645196Ssbehera 
85655196Ssbehera 	if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) {
85665196Ssbehera 		nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
85675196Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
85685196Ssbehera 		    "nxge_mii_get_link_mode: fiber mode"));
85695196Ssbehera 	}
85705196Ssbehera 
85715196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
85725196Ssbehera 	    "nxge_mii_get_link_mode: "
85735196Ssbehera 	    "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x",
85745203Ssbehera 	    NXGE_MII_MODE_CONTROL_REG, xcvr_portn,
85755196Ssbehera 	    mode.value, nxgep->mac.portmode));
85765196Ssbehera 
85775196Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
85785196Ssbehera 	    "<== nxge_mii_get_link_mode"));
85795196Ssbehera 	return (status);
85805196Ssbehera fail:
85815196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
85825196Ssbehera 	    "<== nxge_mii_get_link_mode (failed)"));
85835196Ssbehera 	return (NXGE_ERROR);
85845196Ssbehera }
85855196Ssbehera 
85866439Sml29623 nxge_status_t
85876439Sml29623 nxge_mac_set_framesize(p_nxge_t nxgep)
85886439Sml29623 {
85896439Sml29623 	npi_attr_t		ap;
85906439Sml29623 	uint8_t			portn;
85916439Sml29623 	npi_handle_t		handle;
85926439Sml29623 	npi_status_t		rs = NPI_SUCCESS;
85936439Sml29623 
85946439Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_set_framesize"));
85956439Sml29623 
85966439Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
85976439Sml29623 	handle = nxgep->npi_handle;
85986439Sml29623 
85996439Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
86006439Sml29623 	    "==> nxge_mac_sec_framesize: port<%d> "
86016439Sml29623 	    "min framesize %d max framesize %d ",
86026439Sml29623 	    portn,
86036439Sml29623 	    nxgep->mac.minframesize,
86046439Sml29623 	    nxgep->mac.maxframesize));
86056439Sml29623 
86066439Sml29623 	SET_MAC_ATTR2(handle, ap, portn,
86076439Sml29623 	    MAC_PORT_FRAME_SIZE,
86086439Sml29623 	    nxgep->mac.minframesize,
86096439Sml29623 	    nxgep->mac.maxframesize,
86106439Sml29623 	    rs);
86116439Sml29623 	if (rs != NPI_SUCCESS) {
86126439Sml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
86136439Sml29623 		    "<== nxge_mac_set_framesize: failed to configure "
86146439Sml29623 		    "max/min frame size port %d", portn));
86156439Sml29623 
86166439Sml29623 		return (NXGE_ERROR | rs);
86176439Sml29623 	}
86186439Sml29623 
86196439Sml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
86206439Sml29623 	    "<== nxge_mac_set_framesize: port<%d>", portn));
86216439Sml29623 
86226439Sml29623 	return (NXGE_OK);
86236439Sml29623 }
86246439Sml29623 
86256835Syc148097 static nxge_status_t
86266835Syc148097 nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
86276835Syc148097     uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui)
86286835Syc148097 {
86296835Syc148097 	uint8_t i;
86306835Syc148097 
86316835Syc148097 	for (i = 0; i < 4; i++) {
86326835Syc148097 		if (port_phy_id[i] != PHY_BCM5464R_FAMILY)
86336835Syc148097 			return (NXGE_ERROR);
86346835Syc148097 	}
86356835Syc148097 
86366835Syc148097 	*num_xaui = 0;
86376835Syc148097 	if ((port_pma_pmd_dev_id[0]  == PHY_BCM8704_FAMILY &&
86386835Syc148097 	    port_pcs_dev_id[0] 	== PHY_BCM8704_FAMILY) ||
86396835Syc148097 	    (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
86406835Syc148097 	    == TN1010_DEV_ID) &&
86416835Syc148097 	    ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
86426835Syc148097 	    == TN1010_DEV_ID))) {
86436835Syc148097 		(*num_xaui) ++;
86446835Syc148097 	}
86456835Syc148097 	if ((port_pma_pmd_dev_id[1]  == PHY_BCM8704_FAMILY &&
86466835Syc148097 	    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) ||
86476835Syc148097 	    (((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
86486835Syc148097 	    == TN1010_DEV_ID) &&
86496835Syc148097 	    ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
86506835Syc148097 	    == TN1010_DEV_ID))) {
86516835Syc148097 		(*num_xaui) ++;
86526835Syc148097 	}
86536835Syc148097 	return (NXGE_OK);
86546835Syc148097 }
86556835Syc148097 
86566835Syc148097 /*
86576835Syc148097  * Instruction from Teranetics:  Once you detect link is up, go
86586835Syc148097  * read Reg 30.1.4 for link speed: '1' for 1G and '0' for 10G. You
86596835Syc148097  * may want to qualify it by first checking Register 30.1.7:6 and
86606835Syc148097  * making sure it reads "01" (Auto-Neg Complete).
86616835Syc148097  *
86626835Syc148097  * If this function is called when the link is down or before auto-
86636835Syc148097  * negotiation has completed, then the speed of the PHY is not certain.
86646835Syc148097  * In such cases, this function returns 1G as the default speed with
86656835Syc148097  * NXGE_OK status instead of NXGE_ERROR.  It is OK to initialize the
86666835Syc148097  * driver based on a default speed because this function will be called
86676835Syc148097  * again when the link comes up.  Returning NXGE_ERROR, which may
86686835Syc148097  * cause brutal chain reaction in caller functions, is not necessary.
86696835Syc148097  */
86706835Syc148097 static nxge_status_t
86716835Syc148097 nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed)
86726835Syc148097 {
86736835Syc148097 	uint8_t		phy_port_addr, autoneg_stat, link_up;
86746835Syc148097 	nxge_status_t	status = NXGE_OK;
86756835Syc148097 	uint16_t	val;
86766835Syc148097 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
86776835Syc148097 
86786835Syc148097 	/* Set default speed to 10G */
86796835Syc148097 	*speed = TN1010_SPEED_10G;
86806835Syc148097 
86816835Syc148097 	/* Set Clause 45 */
86826835Syc148097 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
86836835Syc148097 
86846835Syc148097 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
86856835Syc148097 
86866835Syc148097 	/* Check Device 1 Register 0xA bit0 for link up status */
86876835Syc148097 	status = nxge_mdio_read(nxgep, phy_port_addr,
86886835Syc148097 	    TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val);
86896835Syc148097 	if (status != NXGE_OK)
86906835Syc148097 		goto fail;
86916835Syc148097 
86926835Syc148097 	link_up = ((val & TN1010_AN_LINK_STAT_BIT)
86936835Syc148097 	    ? B_TRUE : B_FALSE);
86946835Syc148097 	if (link_up == B_FALSE) {
86956835Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
86966835Syc148097 		    "nxge_get_tn1010_speed: link is down"));
86976835Syc148097 		goto nxge_get_tn1010_speed_exit;
86986835Syc148097 	}
86996835Syc148097 
87006835Syc148097 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
87016835Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, TN1010_VENDOR_MMD1_STATUS_REG,
87026835Syc148097 	    &val)) != NXGE_OK) {
87036835Syc148097 		goto fail;
87046835Syc148097 	}
87056835Syc148097 	autoneg_stat = (val & TN1010_VENDOR_MMD1_AN_STAT_BITS) >>
87066835Syc148097 	    TN1010_VENDOR_MMD1_AN_STAT_SHIFT;
87076835Syc148097 
87086835Syc148097 	/*
87096835Syc148097 	 * Return NXGE_OK even when we can not get a settled speed. In
87106835Syc148097 	 * such case, the speed reported should not be trusted but that
87116835Syc148097 	 * is OK, we will call this function periodically and will get
87126835Syc148097 	 * the correct speed after the link is up.
87136835Syc148097 	 */
87146835Syc148097 	switch (autoneg_stat) {
87156835Syc148097 	case TN1010_AN_IN_PROG:
87166835Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
87176835Syc148097 		    "nxge_get_tn1010_speed: Auto-negotiation in progress"));
87186835Syc148097 		break;
87196835Syc148097 	case TN1010_AN_COMPLETE:
87206835Syc148097 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
87216835Syc148097 		    TN1010_VENDOR_MMD1_DEV_ADDR,
87226835Syc148097 		    TN1010_VENDOR_MMD1_STATUS_REG,
87236835Syc148097 		    &val)) != NXGE_OK) {
87246835Syc148097 			goto fail;
87256835Syc148097 		}
87266835Syc148097 		*speed = (val & TN1010_VENDOR_MMD1_AN_SPEED_BIT) >>
87276835Syc148097 		    TN1010_VENDOR_MMD1_AN_SPEED_SHIFT;
87286835Syc148097 		break;
87296835Syc148097 	case TN1010_AN_RSVD:
87306835Syc148097 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
87316835Syc148097 		    "nxge_get_tn1010_speed: Autoneg status undefined"));
87326835Syc148097 		break;
87336835Syc148097 	case TN1010_AN_FAILED:
87346835Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
87356835Syc148097 		    "nxge_get_tn1010_speed: Auto-negotiation failed"));
87366835Syc148097 		break;
87376835Syc148097 	default:
87386835Syc148097 		break;
87396835Syc148097 	}
87406835Syc148097 nxge_get_tn1010_speed_exit:
87416835Syc148097 	return (NXGE_OK);
87426835Syc148097 fail:
87436835Syc148097 	return (status);
87446835Syc148097 }
87456835Syc148097 
87466835Syc148097 
87476835Syc148097 /*
87486835Syc148097  * Teranetics TN1010 PHY chip supports both 1G and 10G modes, this function
87496835Syc148097  * figures out the speed of the PHY determined by the autonegotiation
87506835Syc148097  * process and sets the following 3 parameters,
87516835Syc148097  * 	nxgep->mac.portmode
87526835Syc148097  *     	nxgep->statsp->mac_stats.link_speed
87536835Syc148097  *	nxgep->statsp->mac_stats.xcvr_inuse
87546835Syc148097  */
87556835Syc148097 static nxge_status_t
87566835Syc148097 nxge_set_tn1010_param(p_nxge_t nxgep)
87576835Syc148097 {
87586835Syc148097 	uint16_t speed;
87596835Syc148097 
87606835Syc148097 	if (nxge_get_tn1010_speed(nxgep,  &speed) != NXGE_OK) {
87616835Syc148097 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
87626835Syc148097 		    "nxge_set_tn1010_param: "
87636835Syc148097 		    "Failed to get TN1010 speed"));
87646835Syc148097 		return (NXGE_ERROR);
87656835Syc148097 	}
87666835Syc148097 	if (speed == TN1010_SPEED_1G) {
87676835Syc148097 		nxgep->mac.portmode = PORT_1G_TN1010;
87686835Syc148097 		nxgep->statsp->mac_stats.link_speed = 1000;
87696835Syc148097 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
87706835Syc148097 	} else {
87716835Syc148097 		nxgep->mac.portmode = PORT_10G_TN1010;
87726835Syc148097 		nxgep->statsp->mac_stats.link_speed = 10000;
87736835Syc148097 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
87746835Syc148097 	}
87756835Syc148097 	return (NXGE_OK);
87766835Syc148097 }
87776835Syc148097 
87785196Ssbehera #ifdef NXGE_DEBUG
87795196Ssbehera static void
87805196Ssbehera nxge_mii_dump(p_nxge_t nxgep)
87815196Ssbehera {
87825196Ssbehera 	p_nxge_stats_t	statsp;
87835196Ssbehera 	uint8_t		xcvr_portn;
87845196Ssbehera 	p_mii_regs_t	mii_regs;
87855196Ssbehera 	mii_bmcr_t	bmcr;
87865196Ssbehera 	mii_bmsr_t	bmsr;
87875196Ssbehera 	mii_idr1_t	idr1;
87885196Ssbehera 	mii_idr2_t	idr2;
87895196Ssbehera 	mii_mode_control_stat_t	mode;
87906495Sspeer 	p_nxge_param_t	param_arr;
87915196Ssbehera 
87925196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump"));
87935196Ssbehera 
87945196Ssbehera 	statsp = nxgep->statsp;
87955196Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
87965196Ssbehera 
87975196Ssbehera 	mii_regs = NULL;
87985196Ssbehera 
87995196Ssbehera #if defined(__i386)
88005196Ssbehera 	(void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
88015196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value);
88025196Ssbehera #else
88035196Ssbehera 	(void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
88045196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value);
88055196Ssbehera #endif
88065196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88075196Ssbehera 	    "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x",
88085196Ssbehera 	    xcvr_portn, bmcr.value));
88095196Ssbehera 
88105196Ssbehera #if defined(__i386)
88115196Ssbehera 	(void) nxge_mii_read(nxgep,
88125196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
88135196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value);
88145196Ssbehera #else
88155196Ssbehera 	(void) nxge_mii_read(nxgep,
88165196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
88175196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value);
88185196Ssbehera #endif
88195196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88205196Ssbehera 	    "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x",
88215196Ssbehera 	    xcvr_portn, bmsr.value));
88225196Ssbehera 
88235196Ssbehera #if defined(__i386)
88245196Ssbehera 	(void) nxge_mii_read(nxgep,
88255196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
88265196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value);
88275196Ssbehera #else
88285196Ssbehera 	(void) nxge_mii_read(nxgep,
88295196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
88305196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value);
88315196Ssbehera #endif
88325196Ssbehera 
88335196Ssbehera 
88345196Ssbehera #if defined(__i386)
88355196Ssbehera 	(void) nxge_mii_read(nxgep,
88365196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
88375196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value);
88385196Ssbehera #else
88395196Ssbehera 	(void) nxge_mii_read(nxgep,
88405196Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
88415196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value);
88425196Ssbehera #endif
88435196Ssbehera 
88445196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88455196Ssbehera 	    "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x",
88465196Ssbehera 	    xcvr_portn, idr1.value));
88475196Ssbehera 
88485196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88495196Ssbehera 	    "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x",
88505196Ssbehera 	    xcvr_portn, idr2.value));
88515196Ssbehera 
88525196Ssbehera 	mode.value = 0;
88535203Ssbehera 	mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
88545196Ssbehera 
88555196Ssbehera #if defined(__i386)
88565196Ssbehera 	(void) nxge_mii_write(nxgep, xcvr_portn,
88575196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value);
88585196Ssbehera 
88595196Ssbehera 	(void) nxge_mii_read(nxgep, xcvr_portn,
88605196Ssbehera 	    (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value);
88615196Ssbehera #else
88625196Ssbehera 	(void) nxge_mii_write(nxgep, xcvr_portn,
88635196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value);
88645196Ssbehera 
88655196Ssbehera 	(void) nxge_mii_read(nxgep, xcvr_portn,
88665196Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value);
88675196Ssbehera #endif
88685196Ssbehera 
88695196Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88705196Ssbehera 	    "nxge_mii_dump: mode control xcvr 0x%x value 0x%x",
88715196Ssbehera 	    xcvr_portn, mode.value));
88725196Ssbehera }
88735196Ssbehera #endif
8874